Adicionado campo velocidade ao tiro
[Projeto-PCG.git] / shooter.cpp
blob8877a73ad90304f81174be202786316938e18df9
1 #include <math.h>
2 #include "shooter.h"
3 #include "gravity.h"
4 #include "shot.h"
5 #include "shotmanager.h"
7 Shooter::Shooter(Game* agame, Ponto pos, Ponto speed) {
8 weapon = NULL;
9 setPosition(pos.x, pos.y);
10 setSpeed(speed.x, speed.y);
11 game = agame;
12 game->gravityManager->subscribe(this);
13 maxspeed.x = 5;
14 maxspeed.y = 20;
15 canfire = true;
18 void Shooter::equip(Weapon* aweapon) {
19 //desequipar a anterior aqui mais tarde
20 weapon = aweapon;
23 static void allowFireFunc(void* param) {
24 ((Shooter*)param)->allowFire();
27 static Uint32 allowFireCallback(Uint32 interval, void *param) {
28 SDL_Event event;
29 SDL_UserEvent userevent;
30 userevent.type = SDL_USEREVENT;
31 userevent.code = 0;
32 userevent.data1 = (void*)allowFireFunc;
33 userevent.data2 = (void*)param;
35 event.type = SDL_USEREVENT;
36 event.user = userevent;
38 SDL_PushEvent(&event);
40 return 0;
43 void Shooter::allowFire() {
44 canfire = true;
49 void Shooter::fire() {
50 if (!canfire || weapon == NULL)
51 return;
52 SDL_AddTimer(weapon->fireRate,allowFireCallback,this);
53 canfire = false;
54 Ponto tiplinha = weapon->getTip();
55 double angle = getAngle();
56 double cosAngle = cos(angle);
57 double sinAngle = sin(angle);
58 Ponto tip;
59 tip.x = (cosAngle*tiplinha.x-sinAngle*tiplinha.y);
60 tip.y = -(sinAngle*tiplinha.x+cosAngle*tiplinha.y);
61 tip = tip + pescoco();
62 tip.x += getX();
63 tip.y += getY();
65 weapon->fire(tip,angle);
69 Ponto Shooter::leftFeet() {
70 Ponto pe(-10,0);
71 return pe;
74 Ponto Shooter::rightFeet() {
75 Ponto pe(10,0);
76 return pe;
79 Ponto Shooter::leftArm() {
80 if (weapon == NULL) {
81 Ponto braco(-10,-30);
82 return braco;
84 else
85 return weapon->getLeftHand();
88 Ponto Shooter::rightArm() {
89 if (weapon == NULL) {
90 Ponto braco(10,-30);
91 return braco;
93 else
94 return weapon->getRightHand();
97 Ponto Shooter::cintura() {
98 Ponto c(0,-30);
99 return c;
102 Ponto Shooter::pescoco() {
103 Ponto neck(0,-60);
104 return neck;
107 double areaTriangle(double a, double b, double c) {
108 if (a < b) std::swap(a,b);
109 if (a < c) std::swap(a,c);
110 if (b < c) std::swap(b,c);
111 //a >= b >= c
113 return sqrt((a+(b+c))*(c-(a-b))*(c+(a-b))*(a+(b-c)))/4.0;
116 //retorna cotovelo em relacao ao ombro, usa matematica levemente pesada, cuidado ao mexer
117 Ponto Shooter::getCotovelo(Ponto ombro, Ponto hand) {
118 double a = tamanhoBraco();
119 double b = tamanhoAntebraco();
120 double d = distance(ombro,hand);
121 double area = areaTriangle(a,b,d);
122 double ylinha = 2.0*area/d;
123 double xlinha = sqrt(a*a-ylinha*ylinha);
124 double sinTheta = (hand.y-ombro.y)/d;
125 double cosTheta = (hand.x-ombro.x)/d;
126 Ponto ret;
127 ret.x = (cosTheta*xlinha-sinTheta*ylinha);
128 ret.y = (sinTheta*xlinha+cosTheta*ylinha);
129 return ret;
132 //cuidado, distancia da arma nao pode exceder tamanhoBraco+tamanhoAntebraco
133 double Shooter::tamanhoBraco() {
134 return 20.0;
137 double Shooter::tamanhoAntebraco() {
138 return 13.0;
141 double Shooter::getAngle() {
142 Ponto gameaim(aim.x+game->camera.x,aim.y+game->camera.y);
143 Ponto gameneck(pescoco().x+getX(),pescoco().y+getY());
144 double hyp = sqrt((gameaim.x-gameneck.x)*(gameaim.x-gameneck.x) +
145 (gameaim.y-gameneck.y)*(gameaim.y-gameneck.y));
146 if (gameaim.y <= gameneck.y)
147 return -acos((-gameaim.x+gameneck.x)/hyp);
148 else
149 return acos((-gameaim.x+gameneck.x)/hyp);
152 void Shooter::desenha() {
153 glPushMatrix();
154 glTranslatef(getX(),getY(),0);
155 Ponto leftfeet = leftFeet();
156 Ponto rightfeet = rightFeet();
157 Ponto hips = cintura();
158 Ponto leftarm = leftArm();
159 Ponto rightarm = rightArm();
160 Ponto neck = pescoco();
161 glBegin(GL_LINES);
162 glVertex3f(hips.x,hips.y,0);
163 glVertex3f(neck.x,neck.y,0);
165 glVertex3f(leftfeet.x,leftfeet.y,0);
166 glVertex3f(hips.x,hips.y,0);
168 glVertex3f(rightfeet.x,rightfeet.y,0);
169 glVertex3f(hips.x,hips.y,0);
170 glEnd();
171 Ponto rightelbow = getCotovelo(neck,rightarm+neck);
172 Ponto leftelbow = getCotovelo(neck,leftarm+neck);
173 glPushMatrix();
174 glTranslatef(neck.x,neck.y,0);
175 glRotatef(getAngle()*180.0/PI,0,0,-1);
176 glBegin(GL_LINES);
177 glVertex3f(0,0,0);
178 glVertex3f(leftelbow.x,leftelbow.y,0);
179 glVertex3f(leftelbow.x,leftelbow.y,0);
180 glVertex3f(leftarm.x,leftarm.y,0);
182 glVertex3f(0,0,0);
183 glVertex3f(rightelbow.x,rightelbow.y,0);
184 glVertex3f(rightelbow.x,rightelbow.y,0);
185 glVertex3f(rightarm.x,rightarm.y,0);
186 glEnd();
187 if (weapon != NULL) weapon->desenha();
188 glPopMatrix();
189 glPushMatrix();
190 glTranslatef(neck.x,neck.y-10,0);
191 drawCircle(10,30);
192 glPopMatrix();
193 glPopMatrix();
197 Linha Shooter::getBaseLine() {
198 Ponto leftfeet = leftFeet();
199 Ponto rightfeet = rightFeet();
200 Linha ret(leftfeet.x+getX(),leftfeet.y+getY(),rightfeet.x+getX(),rightfeet.y+getY());
201 return ret;
204 void Shooter::setAim(double x, double y) {
205 aim.x = x;
206 aim.y = y;