5 #include "shotmanager.h"
6 #include "usereventtype.h"
9 Shooter::Shooter(Game
* agame
, Ponto pos
, Ponto speed
) {
11 setPosition(pos
.x
, pos
.y
);
12 setSpeed(speed
.x
, speed
.y
);
14 game
->gravityManager
->subscribe(this);
30 void Shooter::equip(Weapon
* aweapon
) {
31 //desequipar a anterior aqui mais tarde
35 static void allowFireFunc(void* param
) {
36 ((Shooter
*)param
)->allowFire();
39 static Uint32
allowFireCallback(Uint32 interval
, void *param
) {
41 SDL_UserEvent userevent
;
42 userevent
.type
= SDL_USEREVENT
;
43 userevent
.code
= FUNCTIONCALL
;
44 userevent
.data1
= (void*)allowFireFunc
;
45 userevent
.data2
= (void*)param
;
47 event
.type
= SDL_USEREVENT
;
48 event
.user
= userevent
;
50 SDL_PushEvent(&event
);
55 void Shooter::allowFire() {
59 void Shooter::fire() {
60 if (!canfire
|| weapon
== NULL
)
62 SDL_AddTimer(weapon
->fireRate
*game
->rate
,allowFireCallback
,this);
64 Ponto tiplinha
= weapon
->getTip();
65 double angle
= getAngle();
66 double cosAngle
= cos(angle
);
67 double sinAngle
= sin(angle
);
69 tip
.x
= (cosAngle
*tiplinha
.x
+sinAngle
*tiplinha
.y
);
70 tip
.y
= -(sinAngle
*tiplinha
.x
-cosAngle
*tiplinha
.y
);
71 Ponto leftfeet
= leftFeet();
72 Ponto rightfeet
= rightFeet();
73 weapon
->position
= pescoco();
74 weapon
->position
.x
= direction
*weapon
->position
.x
;
75 weapon
->position
.y
+= + std::min(-rightfeet
.y
,-leftfeet
.y
);
76 weapon
->position
= weapon
->position
+ getPosition();
77 weapon
->fire(tip
,angle
,this);
81 Ponto
Shooter::leftFeet() {
83 Ponto hips
= cintura();
84 Ponto feetFromHips
= realLeftfeet
- hips
;
85 double cosTheta
= cos(bodyAngle
);
86 double sinTheta
= sin(bodyAngle
);
87 ret
.x
= (cosTheta
*feetFromHips
.x
-sinTheta
*feetFromHips
.y
);
88 ret
.y
= (sinTheta
*feetFromHips
.x
+cosTheta
*feetFromHips
.y
);
92 Ponto
Shooter::rightFeet() {
94 Ponto hips
= cintura();
95 Ponto feetFromHips
= realRightfeet
- hips
;
96 double cosTheta
= cos(bodyAngle
);
97 double sinTheta
= sin(bodyAngle
);
98 ret
.x
= (cosTheta
*feetFromHips
.x
-sinTheta
*feetFromHips
.y
);
99 ret
.y
= (sinTheta
*feetFromHips
.x
+cosTheta
*feetFromHips
.y
);
103 Ponto
Shooter::imaginaryLeftfeet() {
106 if (onGround
&& abs(getSpeedX()) < 0.05) {
113 t
*= 1.0+abs(getSpeedX());
114 pe
.x
= 6*cos(PI
+t
/30.0);
115 pe
.y
= 2.5*sin(PI
+t
/30.0)-2.5;
128 Ponto
Shooter::imaginaryRightfeet() {
131 if (onGround
&& abs(getSpeedX()) < 0.05) {
138 t
*= 1.0+abs(getSpeedX());
139 pe
.x
= 6*cos(t
/30.0);
140 pe
.y
= 2.5*sin(t
/30.0)-2.5;
153 double Shooter::imaginaryBodyAngle() {
157 if ((bypass
&& !onGround
) || bodyAngle
> PI
/2) {
158 return 2*PI
*((t
% 360) / 360.0) + addToAngle
;
162 return addToAngle
+ PI
/2;
166 void Shooter::updateFeetTime() {
167 if (onGround
&& abs(getSpeedX()) >= 0.05)
173 void Shooter::updateAngleTime() {
174 if ((bypass
&& !onGround
) || bodyAngle
> PI
/2)
181 void Shooter::animate() {
184 Ponto il
= imaginaryLeftfeet();
185 Ponto ir
= imaginaryRightfeet();
187 realLeftfeet
.x
+= closerToZero(sign(il
.x
- realLeftfeet
.x
)*0.5, il
.x
- realLeftfeet
.x
);
188 realLeftfeet
.y
+= closerToZero(sign(il
.y
- realLeftfeet
.y
)*0.5,il
.y
- realLeftfeet
.y
);
190 realRightfeet
.x
+= closerToZero(sign(ir
.x
- realRightfeet
.x
)*0.5,ir
.x
- realRightfeet
.x
);
191 realRightfeet
.y
+= closerToZero(sign(ir
.y
- realRightfeet
.y
)*0.5,ir
.y
- realRightfeet
.y
);
193 double iangle
= imaginaryBodyAngle();
194 double dif
= iangle
- bodyAngle
;
199 bodyAngle
+= closerToZero(sign(dif
)*0.2,dif
);
200 bodyAngle
= fmod(bodyAngle
,2*PI
);
201 if (abs(addToAngle
) > 0.2)
202 addToAngle
+= -sign(addToAngle
)*0.2;
205 double dl
= distance(il
,realLeftfeet
);
206 double dr
= distance(ir
,realRightfeet
);
210 Ponto
Shooter::leftArm(bool w
) {
211 if (!w
|| (weapon
== NULL
)) {
212 Ponto
braco(-10,-30);
216 return weapon
->getLeftHand();
219 Ponto
Shooter::rightArm(bool w
) {
220 if (!w
|| (weapon
== NULL
)) {
225 return weapon
->getRightHand();
228 Ponto
Shooter::cintura() {
233 Ponto
Shooter::pescoco() {
234 Ponto hips
= cintura();
235 Ponto
neck (0,-30); //em relaçao a cintura
237 double cosTheta
= cos(bodyAngle
);
238 double sinTheta
= sin(bodyAngle
);
239 ret
.x
= (cosTheta
*neck
.x
-sinTheta
*neck
.y
);
240 ret
.y
= (sinTheta
*neck
.x
+cosTheta
*neck
.y
);
244 Ponto
Shooter::cabeca() {
245 Ponto hips
= cintura();
246 Ponto
head(0,-11 -30); //-30 é pelo pescoco
248 double cosTheta
= cos(bodyAngle
);
249 double sinTheta
= sin(bodyAngle
);
250 ret
.x
= (cosTheta
*head
.x
-sinTheta
*head
.y
);
251 ret
.y
= (sinTheta
*head
.x
+cosTheta
*head
.y
);
255 double areaTriangle(double a
, double b
, double c
) {
256 if (a
< b
) std::swap(a
,b
);
257 if (a
< c
) std::swap(a
,c
);
258 if (b
< c
) std::swap(b
,c
);
261 return sqrt((a
+(b
+c
))*(c
-(a
-b
))*(c
+(a
-b
))*(a
+(b
-c
)))/4.0;
264 //retorna cotovelo em relacao ao ombro, usa matematica levemente pesada, cuidado ao mexer
265 Ponto
Shooter::getJunta(Ponto superior
, Ponto inferior
,
266 double tamanhoSuperior
, double tamanhoInferior
) {
267 double a
= tamanhoSuperior
;
268 double b
= tamanhoInferior
;
269 double d
= distance(superior
,inferior
);
270 double area
= areaTriangle(a
,b
,d
);
271 double ylinha
= 2.0*area
/d
;
272 double xlinha
= sqrt(a
*a
-ylinha
*ylinha
);
274 double sinTheta
= (inferior
.y
-superior
.y
)/d
;
275 double cosTheta
= (inferior
.x
-superior
.x
)/d
;
278 ret
.x
= (cosTheta
*xlinha
-sinTheta
*ylinha
);
279 ret
.y
= (sinTheta
*xlinha
+cosTheta
*ylinha
);
283 //cuidado, distancia da arma nao pode exceder tamanhoBraco+tamanhoAntebraco
284 double Shooter::tamanhoBraco() {
288 double Shooter::tamanhoAntebraco() {
292 double Shooter::tamanhoCoxa() {
296 double Shooter::tamanhoPerna() {
300 double Shooter::getAngle() {
301 Ponto leftfeet
= leftFeet();
302 Ponto rightfeet
= rightFeet();
303 Ponto gameneck
= pescoco() + getPosition();
304 gameneck
.y
+= std::min(-rightfeet
.y
,-leftfeet
.y
);
305 double hyp
= sqrt((aim
.x
-gameneck
.x
)*(aim
.x
-gameneck
.x
) +
306 (aim
.y
-gameneck
.y
)*(aim
.y
-gameneck
.y
));
307 if (aim
.y
<= gameneck
.y
)
308 return -acos((-aim
.x
+gameneck
.x
)/hyp
);
310 return acos((-aim
.x
+gameneck
.x
)/hyp
);
313 void Shooter::desenha() {
315 glTranslatef(getX(),getY(),0);
316 glScalef(direction
,1,1);
317 //getCollision().desenha();
318 Ponto leftfeet
= leftFeet();
319 Ponto rightfeet
= rightFeet();
320 glTranslatef(0,std::min(-rightfeet
.y
,-leftfeet
.y
),0);
321 Ponto hips
= cintura();
322 Ponto leftarm
= leftArm(true);
323 Ponto rightarm
= rightArm(true);
324 Ponto neck
= pescoco();
325 Ponto rightknee
= getJunta(rightfeet
,hips
,tamanhoPerna(),tamanhoCoxa()) + rightfeet
;
326 Ponto leftknee
= getJunta(leftfeet
,hips
,tamanhoPerna(),tamanhoCoxa()) + leftfeet
;
328 glVertex3f(hips
.x
,hips
.y
,0);
329 glVertex3f(neck
.x
,neck
.y
,0);
331 glVertex3f(leftfeet
.x
,leftfeet
.y
,0);
332 glVertex3f(leftknee
.x
,leftknee
.y
,0);
334 glVertex3f(leftknee
.x
,leftknee
.y
,0);
335 glVertex3f(hips
.x
,hips
.y
,0);
337 glVertex3f(rightfeet
.x
,rightfeet
.y
,0);
338 glVertex3f(rightknee
.x
,rightknee
.y
,0);
340 glVertex3f(rightknee
.x
,rightknee
.y
,0);
341 glVertex3f(hips
.x
,hips
.y
,0);
343 Ponto rightelbow
= getJunta(neck
,rightarm
+neck
,tamanhoBraco(),tamanhoAntebraco());
344 Ponto leftelbow
= getJunta(neck
,leftarm
+neck
,tamanhoBraco(),tamanhoAntebraco());
346 glTranslatef(neck
.x
,neck
.y
,0);
347 glScalef(direction
,direction
,1);
348 glRotatef(direction
*getAngle()*180.0/PI
,0,0,-1);
351 glVertex3f(leftelbow
.x
,leftelbow
.y
,-1);
352 glVertex3f(leftelbow
.x
,leftelbow
.y
,-1);
353 glVertex3f(leftarm
.x
,leftarm
.y
,-1);
356 glVertex3f(rightelbow
.x
,rightelbow
.y
,1);
357 glVertex3f(rightelbow
.x
,rightelbow
.y
,1);
358 glVertex3f(rightarm
.x
,rightarm
.y
,1);
360 if (weapon
!= NULL
) weapon
->desenha();
362 Ponto head
= cabeca();
364 glTranslatef(head
.x
,head
.y
,0);
372 Linha
Shooter::getBaseLine() {
375 return Linha(left
, right
);
378 Polygon
Shooter::getCollision() {
380 Ponto leftfeet
= leftFeet();
381 Ponto rightfeet
= rightFeet();
382 double deslocy
= std::min(-rightfeet
.y
,-leftfeet
.y
);
383 Ponto hips
= cintura();
384 Ponto leftarm
= leftArm(false);
385 Ponto rightarm
= rightArm(false);
386 Ponto head
= cabeca();
388 leftfeet
.y
+= deslocy
;
389 rightfeet
.y
+= deslocy
;
392 leftarm
.y
+= deslocy
;
393 rightarm
.y
+= deslocy
;
395 Linha
a(leftfeet
,rightfeet
);
396 Linha
b(rightfeet
,hips
);
397 Linha
c(hips
,rightarm
);
398 Linha
d(rightarm
,head
);
399 Linha
e(head
,leftarm
);
400 Linha
f(leftarm
,hips
);
401 Linha
g(hips
,leftfeet
);
412 void Shooter::setAim(double x
, double y
) {