1 | /* |
2 | Copyright (C) 1998-2001 Andreas Zehender <az@azweb.de> |
3 | Copyright (C) 2006-2008 Dirk Rathlev <dirkrathlev@gmx.de> |
4 | |
5 | This program is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published by |
7 | the Free Software Foundation; either version 2 of the License, or |
8 | (at your option) any later version. |
9 | |
10 | This program is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | GNU General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU General Public License |
16 | along with this program; if not, write to the Free Software |
17 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
18 | */ |
19 | |
20 | #include "sprites.h" |
21 | |
22 | #include <math.h> |
23 | |
24 | #include <QGraphicsScene> |
25 | |
26 | #include <kdebug.h> |
27 | |
28 | #include "mathroutines.h" |
29 | |
30 | SunSprite::SunSprite(QSvgRenderer* svg, const QString& element) |
31 | :SimpleSprite(svg, element) |
32 | { |
33 | setZValue(0); |
34 | } |
35 | |
36 | |
37 | PowerupSprite::PowerupSprite(QSvgRenderer* svg, const QString& element, int t, |
38 | double lifetime) |
39 | :SimpleSprite(svg, element) |
40 | { |
41 | time=lifetime; |
42 | mtype=t; |
43 | } |
44 | |
45 | ShipSprite::ShipSprite(QSvgRenderer* svg, const QString& element, int pn) |
46 | :MobileSprite(svg, element,pn) |
47 | { |
48 | hitpoints=MAX_HP; |
49 | energy=MAX_ENERGY; |
50 | explosion=-1; |
51 | setZValue(-20); |
52 | rotation=0; |
53 | bulletPowerups=0; |
54 | minePowerups=0; |
55 | angle = 0; |
56 | } |
57 | |
58 | void ShipSprite::setRotation(double r) |
59 | { |
60 | rotation=r; |
61 | if(rotation<0) |
62 | rotation-=((int)(rotation/(2*M_PI))-1)*2*M_PI; |
63 | if(rotation>=2*M_PI) |
64 | rotation-=(int)(rotation/(2*M_PI))*2*M_PI; |
65 | |
66 | translate(center().x(),center().y()); |
67 | rotate(-(rotation-angle)*57.3); |
68 | translate(-center().x(),-center().y()); |
69 | angle = rotation; |
70 | } |
71 | |
72 | void ShipSprite::forward(double mult) |
73 | { |
74 | MobileSprite::forward(mult); |
75 | if(explosion>0) |
76 | { |
77 | explosion--; |
78 | if(explosion==0) |
79 | hide(); |
80 | } |
81 | if(reloadBulletTime>0) |
82 | reloadBulletTime-=mult; |
83 | if(reloadMineTime>0) |
84 | reloadMineTime-=mult; |
85 | } |
86 | |
87 | void ShipSprite::forward(double mult,int fr) |
88 | { |
89 | MobileSprite::forward(mult,fr); |
90 | rotation=fr/ROTNUM*M_PI*2; |
91 | if(explosion>0) |
92 | { |
93 | explosion--; |
94 | if(explosion==0) |
95 | hide(); |
96 | } |
97 | if(reloadBulletTime>0) |
98 | reloadBulletTime-=mult; |
99 | if(reloadMineTime>0) |
100 | reloadMineTime-=mult; |
101 | } |
102 | |
103 | void ShipSprite::calculateGravityAndEnergy(double gravity,double sunEnergy, |
104 | double mult) |
105 | { |
106 | double nx,ny,ex,ey,abs_2,phi,sq,eg; |
107 | |
108 | if(!stopped) |
109 | { |
110 | ex=x()+center().x()-scene()->width()/2.0; |
111 | ey=y()+center().y()-scene()->height()/2.0; |
112 | |
113 | abs_2=ex*ex+ey*ey; |
114 | sq=sqrt(abs_2); |
115 | |
116 | if ( explodes() && (sq<20) ) |
117 | stopped = true; |
118 | else |
119 | { |
120 | nx=ex/sq; |
121 | ny=ey/sq; |
122 | eg=gravity*mult; |
123 | setVelocity(xVelocity()-eg*nx/abs_2, |
124 | yVelocity()-eg*ny/abs_2); |
125 | if(hitpoints!=0) |
126 | { |
127 | if(energy<99.8) |
128 | { |
129 | phi=rectToAngle(nx,ny); |
130 | energy+=fabs(sunEnergy*mult/(abs_2)*cos(phi+rotation)); |
131 | } |
132 | } |
133 | } |
134 | } |
135 | } |
136 | |
137 | void ShipSprite::rotateRight(double rotationEnergyNeed,double rotationSpeed) |
138 | { |
139 | if(energy>rotationEnergyNeed) |
140 | { |
141 | energy-=rotationEnergyNeed; |
142 | setRotation(rotation-rotationSpeed); |
143 | } |
144 | } |
145 | |
146 | void ShipSprite::rotateLeft(double rotationEnergyNeed,double rotationSpeed) |
147 | { |
148 | if(energy>rotationEnergyNeed) |
149 | { |
150 | energy-=rotationEnergyNeed; |
151 | setRotation(rotation+rotationSpeed); |
152 | } |
153 | } |
154 | |
155 | BulletSprite::BulletSprite(QSvgRenderer* svg, const QString& element, int pn,double lifetime) |
156 | :MobileSprite(svg,element,pn) |
157 | { |
158 | setZValue(-10); |
159 | time=lifetime; |
160 | } |
161 | |
162 | void BulletSprite::forward(double mult) |
163 | { |
164 | MobileSprite::forward(mult); |
165 | time-=mult; |
166 | } |
167 | |
168 | void BulletSprite::forward(double mult,int fr) |
169 | { |
170 | MobileSprite::forward(mult,fr); |
171 | time-=mult; |
172 | } |
173 | |
174 | MineSprite::MineSprite(QSvgRenderer* svg, const QList<QString>& animation, const QList<QString>& exploanimation, int pn,double atime,double f) |
175 | :AnimatedSprite(svg, animation,pn) |
176 | { |
177 | exploframes = exploanimation; |
178 | activateTime=atime; |
179 | setZValue(-25); |
180 | fuel=f; |
181 | explosiontime=0; |
182 | timeToGo=0.0; |
183 | expl=false; |
184 | active=false; |
185 | } |
186 | |
187 | void MineSprite::explode() |
188 | { |
189 | setAnimation(exploframes); |
190 | timeToGo=frameCount(); |
191 | expl=true; |
192 | explosiontime=0.0; |
193 | setZValue(-8); |
194 | setFuel(0.0); |
195 | } |
196 | |
197 | void MineSprite::forward(double mult) |
198 | { |
199 | if(active) |
200 | { |
201 | if(expl) |
202 | { |
203 | explosiontime+=mult; |
204 | if(explosiontime>(timeToGo-0.001)) |
205 | explosiontime=timeToGo-0.01; |
206 | setFrame((int)explosiontime); |
207 | } |
208 | } |
209 | else |
210 | { |
211 | activateTime-=(double)mult; |
212 | if(activateTime<0.0) |
213 | { |
214 | active=true; |
215 | setFrame(1); |
216 | } |
217 | } |
218 | if(fuel<0.001) |
219 | MobileSprite::forward(mult); |
220 | } |
221 | |
222 | void MineSprite::calculateGravity(double gravity,double mult) |
223 | { |
224 | double abs_2,nx,ny,ex,ey,sq,eg; |
225 | |
226 | if(!stopped) |
227 | { |
228 | ex=x()-scene()->width()/2.0; |
229 | ey=y()-scene()->height()/2.0; |
230 | |
231 | abs_2=ex*ex+ey*ey; |
232 | sq=sqrt(abs_2); |
233 | nx=ex/sq; |
234 | ny=ey/sq; |
235 | eg=gravity*mult; |
236 | if(fuel<0.001) |
237 | setVelocity(xVelocity()-eg*nx/abs_2, |
238 | yVelocity()-eg*ny/abs_2); |
239 | else |
240 | fuel-=eg/abs_2; |
241 | } |
242 | } |
243 | |
244 | ExplosionSprite::ExplosionSprite(QSvgRenderer* svg, const QList<QString>& animation, MobileSprite *sp) |
245 | :AnimatedSprite(svg, animation) |
246 | { |
247 | over=false; |
248 | setZValue(5); |
249 | obj=sp; |
250 | timeToGo = frameCount(); |
251 | time=0; |
252 | |
253 | setPos(QPointF(sp->x(),sp->y())); |
254 | } |
255 | |
256 | void ExplosionSprite::forward(double mult) |
257 | { |
258 | int of=frame(); |
259 | setPos(QPointF(obj->x(),obj->y())); |
260 | time+=mult; |
261 | |
262 | if(time>=timeToGo) |
263 | { |
264 | over=true; |
265 | hide(); |
266 | } |
267 | else |
268 | if((int)time!=of) |
269 | setFrame((int)time); |
270 | } |
271 | |