Merge branch 'weaponitem'
[Projeto-PCG.git] / shooter.cpp
blob424afc57af737a9eb58608caab57c8e95e5c73f4
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() + getPosition();
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 gameneck = pescoco() + getPosition();
143 double hyp = sqrt((aim.x-gameneck.x)*(aim.x-gameneck.x) +
144 (aim.y-gameneck.y)*(aim.y-gameneck.y));
145 if (aim.y <= gameneck.y)
146 return -acos((-aim.x+gameneck.x)/hyp);
147 else
148 return acos((-aim.x+gameneck.x)/hyp);
151 void Shooter::desenha() {
152 glPushMatrix();
153 glTranslatef(getX(),getY(),0);
154 Ponto leftfeet = leftFeet();
155 Ponto rightfeet = rightFeet();
156 Ponto hips = cintura();
157 Ponto leftarm = leftArm();
158 Ponto rightarm = rightArm();
159 Ponto neck = pescoco();
160 glBegin(GL_LINES);
161 glVertex3f(hips.x,hips.y,0);
162 glVertex3f(neck.x,neck.y,0);
164 glVertex3f(leftfeet.x,leftfeet.y,0);
165 glVertex3f(hips.x,hips.y,0);
167 glVertex3f(rightfeet.x,rightfeet.y,0);
168 glVertex3f(hips.x,hips.y,0);
169 glEnd();
170 Ponto rightelbow = getCotovelo(neck,rightarm+neck);
171 Ponto leftelbow = getCotovelo(neck,leftarm+neck);
172 glPushMatrix();
173 glTranslatef(neck.x,neck.y,0);
174 glRotatef(getAngle()*180.0/PI,0,0,-1);
175 glBegin(GL_LINES);
176 glVertex3f(0,0,-1);
177 glVertex3f(leftelbow.x,leftelbow.y,-1);
178 glVertex3f(leftelbow.x,leftelbow.y,-1);
179 glVertex3f(leftarm.x,leftarm.y,-1);
181 glVertex3f(0,0,1);
182 glVertex3f(rightelbow.x,rightelbow.y,1);
183 glVertex3f(rightelbow.x,rightelbow.y,1);
184 glVertex3f(rightarm.x,rightarm.y,1);
185 glEnd();
186 if (weapon != NULL) weapon->desenha();
187 glPopMatrix();
188 glPushMatrix();
189 glTranslatef(neck.x,neck.y-10,0);
190 drawCircle(10,30);
191 glPopMatrix();
192 glPopMatrix();
196 Linha Shooter::getBaseLine() {
197 return Linha(leftFeet(), rightFeet());
200 Polygon Shooter::getCollision() {
201 Polygon poly;
202 Linha a(leftFeet(),rightFeet());
203 Linha b(rightFeet(),cintura());
204 Linha c(cintura(),rightArm());
205 Linha d(rightArm(),pescoco());
206 Linha e(pescoco(),leftArm());
207 Linha f(leftArm(),cintura());
208 Linha g(cintura(),leftFeet());
209 poly.addLinha(a);
210 poly.addLinha(b);
211 poly.addLinha(c);
212 poly.addLinha(d);
213 poly.addLinha(e);
214 poly.addLinha(f);
215 poly.addLinha(g);
216 return poly;
219 void Shooter::setAim(double x, double y) {
220 aim.x = x;
221 aim.y = y;