Suporte a IR, talvez...
[Projeto-PCG.git] / shooter.cpp
blobe6002386479deaa6d7e7143545a210f2952d61e7
1 #include <math.h>
2 #include "shooter.h"
3 #include "gravity.h"
4 #include "shot.h"
5 #include "shotmanager.h"
6 #include "usereventtype.h"
9 Shooter::Shooter(Game* agame, Ponto pos, Ponto speed) {
10 weapon = NULL;
11 setPosition(pos.x, pos.y);
12 setSpeed(speed.x, speed.y);
13 game = agame;
14 game->gravityManager->subscribe(this);
15 maxspeed.x = 5;
16 maxspeed.y = 20;
17 canfire = true;
20 void Shooter::equip(Weapon* aweapon) {
21 //desequipar a anterior aqui mais tarde
22 weapon = aweapon;
25 static void allowFireFunc(void* param) {
26 ((Shooter*)param)->allowFire();
29 static Uint32 allowFireCallback(Uint32 interval, void *param) {
30 SDL_Event event;
31 SDL_UserEvent userevent;
32 userevent.type = SDL_USEREVENT;
33 userevent.code = FUNCTIONCALL;
34 userevent.data1 = (void*)allowFireFunc;
35 userevent.data2 = (void*)param;
37 event.type = SDL_USEREVENT;
38 event.user = userevent;
40 SDL_PushEvent(&event);
42 return 0;
45 void Shooter::allowFire() {
46 canfire = true;
51 void Shooter::fire() {
52 if (!canfire || weapon == NULL)
53 return;
54 SDL_AddTimer(weapon->fireRate*game->rate,allowFireCallback,this);
55 canfire = false;
56 Ponto tiplinha = weapon->getTip();
57 double angle = getAngle();
58 double cosAngle = cos(angle);
59 double sinAngle = sin(angle);
60 Ponto tip;
61 tip.x = (cosAngle*tiplinha.x+sinAngle*tiplinha.y);
62 tip.y = -(sinAngle*tiplinha.x-cosAngle*tiplinha.y);
63 tip = tip + pescoco();
64 tip.x += getX();
65 tip.y += getY();
67 weapon->fire(tip,angle);
71 Ponto Shooter::leftFeet() {
72 Ponto pe(-10,0);
73 return pe;
76 Ponto Shooter::rightFeet() {
77 Ponto pe(10,0);
78 return pe;
81 Ponto Shooter::leftArm() {
82 if (weapon == NULL) {
83 Ponto braco(-10,-30);
84 return braco;
86 else
87 return weapon->getLeftHand();
90 Ponto Shooter::rightArm() {
91 if (weapon == NULL) {
92 Ponto braco(10,-30);
93 return braco;
95 else
96 return weapon->getRightHand();
99 Ponto Shooter::cintura() {
100 Ponto c(0,-30);
101 return c;
104 Ponto Shooter::pescoco() {
105 Ponto neck(0,-60);
106 return neck;
109 double areaTriangle(double a, double b, double c) {
110 if (a < b) std::swap(a,b);
111 if (a < c) std::swap(a,c);
112 if (b < c) std::swap(b,c);
113 //a >= b >= c
115 return sqrt((a+(b+c))*(c-(a-b))*(c+(a-b))*(a+(b-c)))/4.0;
118 //retorna cotovelo em relacao ao ombro, usa matematica levemente pesada, cuidado ao mexer
119 Ponto Shooter::getCotovelo(Ponto ombro, Ponto hand) {
120 double a = tamanhoBraco();
121 double b = tamanhoAntebraco();
122 double d = distance(ombro,hand);
123 double area = areaTriangle(a,b,d);
124 double ylinha = 2.0*area/d;
125 double xlinha = sqrt(a*a-ylinha*ylinha);
126 double sinTheta = (hand.y-ombro.y)/d;
127 double cosTheta = (hand.x-ombro.x)/d;
128 Ponto ret;
129 ret.x = (cosTheta*xlinha-sinTheta*ylinha);
130 ret.y = (sinTheta*xlinha+cosTheta*ylinha);
131 return ret;
134 //cuidado, distancia da arma nao pode exceder tamanhoBraco+tamanhoAntebraco
135 double Shooter::tamanhoBraco() {
136 return 20.0;
139 double Shooter::tamanhoAntebraco() {
140 return 13.0;
143 double Shooter::getAngle() {
144 Ponto gameaim(aim.x+game->camera.x,aim.y+game->camera.y);
145 Ponto gameneck(pescoco().x+getX(),pescoco().y+getY());
146 double hyp = sqrt((gameaim.x-gameneck.x)*(gameaim.x-gameneck.x) +
147 (gameaim.y-gameneck.y)*(gameaim.y-gameneck.y));
148 if (gameaim.y <= gameneck.y)
149 return -acos((-gameaim.x+gameneck.x)/hyp);
150 else
151 return acos((-gameaim.x+gameneck.x)/hyp);
154 void Shooter::desenha() {
155 glPushMatrix();
156 glTranslatef(getX(),getY(),0);
157 Ponto leftfeet = leftFeet();
158 Ponto rightfeet = rightFeet();
159 Ponto hips = cintura();
160 Ponto leftarm = leftArm();
161 Ponto rightarm = rightArm();
162 Ponto neck = pescoco();
163 glBegin(GL_LINES);
164 glVertex3f(hips.x,hips.y,0);
165 glVertex3f(neck.x,neck.y,0);
167 glVertex3f(leftfeet.x,leftfeet.y,0);
168 glVertex3f(hips.x,hips.y,0);
170 glVertex3f(rightfeet.x,rightfeet.y,0);
171 glVertex3f(hips.x,hips.y,0);
172 glEnd();
173 Ponto rightelbow = getCotovelo(neck,rightarm+neck);
174 Ponto leftelbow = getCotovelo(neck,leftarm+neck);
175 glPushMatrix();
176 glTranslatef(neck.x,neck.y,0);
177 glRotatef(getAngle()*180.0/PI,0,0,-1);
178 glBegin(GL_LINES);
179 glVertex3f(0,0,-1);
180 glVertex3f(leftelbow.x,leftelbow.y,-1);
181 glVertex3f(leftelbow.x,leftelbow.y,-1);
182 glVertex3f(leftarm.x,leftarm.y,-1);
184 glVertex3f(0,0,1);
185 glVertex3f(rightelbow.x,rightelbow.y,1);
186 glVertex3f(rightelbow.x,rightelbow.y,1);
187 glVertex3f(rightarm.x,rightarm.y,1);
188 glEnd();
189 if (weapon != NULL) weapon->desenha();
190 glPopMatrix();
191 glPushMatrix();
192 glTranslatef(neck.x,neck.y-10,0);
193 drawCircle(10,30);
194 glPopMatrix();
195 glPopMatrix();
199 Linha Shooter::getBaseLine() {
200 Ponto leftfeet = leftFeet();
201 Ponto rightfeet = rightFeet();
202 Linha ret(leftfeet.x+getX(),leftfeet.y+getY(),rightfeet.x+getX(),rightfeet.y+getY());
203 return ret;
206 Polygon Shooter::getCollision() {
207 Polygon poly;
208 Ponto atual(getX(),getY());
209 Linha a(leftFeet()+atual,rightFeet()+atual);
210 Linha b(rightFeet()+atual,cintura()+atual);
211 Linha c(cintura()+atual,rightArm()+atual);
212 Linha d(rightArm()+atual,pescoco()+atual);
213 Linha e(pescoco()+atual,leftArm()+atual);
214 Linha f(leftArm()+atual,cintura()+atual);
215 Linha g(cintura()+atual,leftFeet()+atual);
216 poly.addLinha(a);
217 poly.addLinha(b);
218 poly.addLinha(c);
219 poly.addLinha(d);
220 poly.addLinha(e);
221 poly.addLinha(f);
222 poly.addLinha(g);
223 return poly;
226 void Shooter::setAim(double x, double y) {
227 aim.x = x;
228 aim.y = y;