Coverage Summary for Class: FireTruck (com.mozarellabytes.kroy.Entities)
Class | Class, % | Method, % | Line, % |
---|---|---|---|
FireTruck | 100% (1/ 1) | 77.4% (24/ 31) | 80% (100/ 125) |
1 package com.mozarellabytes.kroy.Entities;
2
3 import com.badlogic.gdx.Gdx;
4 import com.badlogic.gdx.graphics.Color;
5 import com.badlogic.gdx.graphics.Texture;
6 import com.badlogic.gdx.graphics.g2d.Batch;
7 import com.badlogic.gdx.graphics.g2d.Sprite;
8 import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
9 import com.badlogic.gdx.math.Vector2;
10 import com.badlogic.gdx.utils.Queue;
11 import com.mozarellabytes.kroy.Screens.GameScreen;
12 import com.mozarellabytes.kroy.Utilities.SoundFX;
13
14 import java.util.ArrayList;
15
16 /**
17 * FireTruck is an entity that the player controls. It navigates the map on the
18 * roads defined in the Tiled Map by following a path that the user draws.
19 *
20 * Having 'A' held when within range of a Fortress will deal damage to it.
21 */
22 public class FireTruck extends Sprite {
23
24 /** Enables access to functions in GameScreen */
25 private final GameScreen gameScreen;
26
27 /** Defines set of pre-defined attributes */
28 public final FireTruckType type;
29
30 /** Health points */
31 private float HP;
32
33 /** Water Reserve */
34 private float reserve;
35
36 /** Position of FireTruck in tiles */
37 private Vector2 position;
38
39 /** Actual path the truck follows; the fewer item in
40 * the path the slower the truck will go */
41 public final Queue<Vector2> path;
42
43 /** The visual path that users can see when drawing
44 * a firetruck's path */
45 public final Queue<Vector2> trailPath;
46
47 /** If the truck is currently moving, determines whether the
48 * truck's position should be updated
49 *
50 * <code>true</code> once the player has drawn a
51 * path and has let go of the mouse click
52 * <code>false</code> once the truck has got to
53 * the end of the path */
54 private boolean moving;
55
56 /** If the truck is attacking a Fortress
57 *
58 * <code>true</code> 'A' key is pressed
59 * <code>false</code> 'A' key is not pressed */
60 private boolean attacking;
61
62 /** Whether the truck has an unresolved collision
63 * with another truck */
64 private boolean inCollision;
65
66 /** Used to check if the truck's image should be
67 * changed to match the direction it is facing */
68 private Vector2 previousTile;
69
70 /** Time since fortress has attacked the truck */
71 private long timeOfLastAttack;
72
73 /** List of particles that the truck uses to attack
74 * a Fortress */
75 private final ArrayList<WaterParticle> spray;
76
77 /** Texture for each direction the
78 * truck is facing */
79 private final Texture lookLeft;
80 private final Texture lookRight;
81 private final Texture lookUp;
82 private final Texture lookDown;
83
84 /**
85 * Constructs a new FireTruck at a position and of a certain type
86 * which have been passed in
87 *
88 * @param gameScreen used to access functions in GameScreen
89 * @param position initial location of the truck
90 * @param type used to have predefined attributes
91 */
92 public FireTruck(GameScreen gameScreen, Vector2 position, FireTruckType type) {
93 super(new Texture(Gdx.files.internal("sprites/firetruck/down.png")));
94
95 this.gameScreen = gameScreen;
96 this.type = type;
97 this.HP = type.getMaxHP();
98 this.reserve = type.getMaxReserve();
99 this.position = position;
100 this.path = new Queue<Vector2>();
101 this.trailPath = new Queue<Vector2>();
102 this.moving = false;
103 this.attacking = false;
104 this.inCollision = false;
105 this.spray = new ArrayList<WaterParticle>();
106 this.timeOfLastAttack = System.currentTimeMillis();
107 this.lookLeft = new Texture(Gdx.files.internal("sprites/firetruck/left.png"));
108 this.lookRight = new Texture(Gdx.files.internal("sprites/firetruck/right.png"));
109 this.lookUp = new Texture(Gdx.files.internal("sprites/firetruck/up.png"));
110 this.lookDown = new Texture(Gdx.files.internal("sprites/firetruck/down.png"));
111 }
112
113 /**
114 * Called every tick and updates the paths to simulate the truck moving along the
115 * path
116 */
117 public void move() {
118 if (moving) {
119 if (this.path.size > 0) {
120 Vector2 nextTile = path.first();
121 this.position = nextTile;
122
123 if (!this.trailPath.isEmpty() && (int) this.position.x == this.trailPath.first().x && (int) this.position.y == this.trailPath.first().y) {
124 this.trailPath.removeFirst();
125 }
126 if (!this.inCollision) {
127 changeSprite(nextTile);
128 }
129 previousTile = nextTile;
130 path.removeFirst();
131 } else {
132 moving = false;
133 }
134 if (this.path.isEmpty() && inCollision) {
135 inCollision = false;
136 }
137 }
138 }
139
140 /**
141 * Increases Health Points of the truck
142 *
143 * @param HP increased by this value
144 */
145 public void repair(float HP) {
146 this.HP += HP;
147 }
148
149 /**
150 * Increases the Reserve of the truck
151 *
152 * @param reserve increased by this value
153 */
154 public void refill(float reserve) {
155 this.reserve += reserve;
156 }
157
158 /**
159 * Called when the player drags mouse on GameScreen Coordinate is checked to see
160 * whether it is a valid tile to draw to, then adds it to the paths
161 *
162 * @param coordinate Position on the screen that the user's mouse is being
163 * dragged over
164 */
165 public void addTileToPath(Vector2 coordinate) {
166 if (isValidDraw(coordinate)) {
167 if (this.path.size > 0) {
168 Vector2 previous = this.path.last();
169 int interpolation = (int) (20/type.getSpeed());
170 for (int i=1; i<interpolation; i++) {
171 this.path.addLast(new Vector2((((previous.x - coordinate.x)*-1)/interpolation)*i + previous.x, (((previous.y - coordinate.y)*-1)/interpolation)*i + previous.y));
172 }
173 }
174 this.trailPath.addLast(new Vector2(((int) coordinate.x), ((int) coordinate.y)));
175 this.path.addLast(new Vector2(((int) coordinate.x), ((int) coordinate.y)));
176 }
177 }
178
179 /**
180 * Used when drawing the path to check whether the next tile to be added to the path is
181 * valid
182 *
183 * @param coordinate Position on the screen that the user's mouse is being dragged over
184 * @return <code>true</code> if the coordinate is a valid tile to be added to
185 * the paths
186 * <code>false</code> otherwise
187 */
188 private boolean isValidDraw(Vector2 coordinate) {
189 if (coordinate.y < 24) {
190 if (gameScreen.isRoad((Math.round(coordinate.x)), (Math.round(coordinate.y)))) {
191 if (this.path.isEmpty()) {
192 return this.getPosition().equals(coordinate);
193 } else {
194 if (!this.path.last().equals(coordinate)) {
195 return (int) Math.abs(this.path.last().x - coordinate.x) + (int) Math.abs(this.path.last().y - coordinate.y) <= 1;
196 }
197 }
198 }
199 }
200 return false;
201 }
202
203 /**
204 * Changes the direction of the truck depending on the previous tile and the next tile
205 *
206 * @param nextTile first tile in the queue (next to be followed)
207 */
208 private void changeSprite(Vector2 nextTile) {
209 if (previousTile != null) {
210 if (nextTile.x > previousTile.x) {
211 setTexture(lookRight);
212 } else if (nextTile.x < previousTile.x) {
213 setTexture(lookLeft);
214 } else if (nextTile.y > previousTile.y) {
215 setTexture(lookUp);
216 } else if (nextTile.y < previousTile.y) {
217 setTexture(lookDown);
218 }
219 }
220 }
221
222 /**
223 * Clears the two paths
224 */
225 public void resetPath() {
226 this.path.clear();
227 this.trailPath.clear();
228 }
229
230 /**
231 * Deals damage to Fortress by generating a WaterParticle and adding
232 * it to the spray
233 *
234 * @param fortress Fortress being attacked
235 */
236 public void attack(Fortress fortress) {
237 if (this.attacking && this.reserve > 0) {
238 this.spray.add(new WaterParticle(this, fortress));
239 this.reserve -= Math.min(this.reserve, this.type.getAP());
240 }
241 }
242
243 /**
244 * Called every tick to check if a Fortress is within the range of
245 * the truck
246 *
247 * @param fortress Fortress' position being checked
248 * @return <code>true</code> if Fortress is within range
249 * <code>false </code> otherwise
250 */
251 public boolean fortressInRange(Vector2 fortress) {
252 return this.getVisualPosition().dst(fortress) <= this.type.getRange();
253 }
254
255 /**
256 * Updates the position of each WaterParticle
257 */
258 public void updateSpray() {
259 if (this.spray != null) {
260 for (int i=0; i < this.spray.size(); i++) {
261 WaterParticle particle = this.spray.get(i);
262 particle.updatePosition();
263 if (particle.isHit()) {
264 this.damage(particle);
265 this.removeParticle(particle);
266 }
267 }
268 }
269 }
270
271 /**
272 * Remove the WaterParticle from the spray when it hits the Fortress
273 *
274 * @param particle The particle to be removed from spray
275 */
276 private void removeParticle(WaterParticle particle) {
277 this.spray.remove(particle);
278 }
279
280 /**
281 * Damages the Fortress depending on the truck's AP
282 *
283 * @param particle the particle which damages the fortress
284 */
285 private void damage(WaterParticle particle) {
286 particle.getTarget().damage(Math.min(this.type.getAP(), particle.getTarget().getHP()));
287 }
288
289 /**
290 * Damage inflicted on truck by a fortress, called when a bomb hits a truck it plays
291 * a sound and decreases the fire trucks HP by the amount of the fortresses AP
292 *
293 * @param HP amount of HP being taken away dependant
294 * on the AP of the attacking Fortress
295 */
296 public void fortressDamage(float HP) {
297 if (SoundFX.music_enabled) {
298 SoundFX.sfx_truck_damage.play();
299 }
300 this.HP -= Math.min(HP, this.HP);
301 }
302
303 /**
304 * Draws the visual, colourful path that the truck will follow
305 *
306 * @param mapBatch Batch that the path is being drawn to (map dependant)
307 */
308 public void drawPath(Batch mapBatch) {
309 if (!this.trailPath.isEmpty()) {
310 mapBatch.setColor(this.type.getTrailColour());
311 for (Vector2 tile : this.trailPath) {
312 if (tile.equals(this.trailPath.last())) {
313 mapBatch.draw(this.type.getTrailImageEnd(), tile.x, tile.y, 1, 1);
314 }
315 mapBatch.draw(this.type.getTrailImage(), tile.x, tile.y, 1, 1);
316 }
317 mapBatch.setColor(Color.WHITE);
318 }
319 }
320
321 /**
322 * Draws the mini health/reserve indicators relative to the truck
323 *
324 * @param shapeMapRenderer Renderer that the stats are being drawn to (map dependant)
325 */
326 public void drawStats(ShapeRenderer shapeMapRenderer) {
327 shapeMapRenderer.rect(this.getPosition().x + 0.2f, this.getPosition().y + 1.3f, 0.6f, 0.8f, Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE);
328 shapeMapRenderer.rect(this.getPosition().x + 0.266f, this.getPosition().y + 1.4f, 0.2f, 0.6f, Color.BLUE, Color.BLUE, Color.BLUE, Color.BLUE);
329 shapeMapRenderer.rect(this.getPosition().x + 0.266f, this.getPosition().y + 1.4f, 0.2f, this.getReserve() / this.type.getMaxReserve() * 0.6f, Color.CYAN, Color.CYAN, Color.CYAN, Color.CYAN);
330 shapeMapRenderer.rect(this.getPosition().x + 0.533f, this.getPosition().y + 1.4f, 0.2f, 0.6f, Color.FIREBRICK, Color.FIREBRICK, Color.FIREBRICK, Color.FIREBRICK);
331 shapeMapRenderer.rect(this.getPosition().x + 0.533f, this.getPosition().y + 1.4f, 0.2f, this.getHP() / this.type.getMaxHP() * 0.6f, Color.RED, Color.RED, Color.RED, Color.RED);
332 for (WaterParticle particle : this.getSpray()) {
333 shapeMapRenderer.rect(particle.getPosition().x, particle.getPosition().y, particle.getSize(), particle.getSize(), particle.getColour(), particle.getColour(), particle.getColour(), particle.getColour());
334 }
335 }
336
337 /**
338 * Draws the FireTruck sprite
339 *
340 * @param mapBatch Batch that the truck is being
341 * drawn to (map dependant)
342 */
343 public void drawSprite(Batch mapBatch) {
344 mapBatch.draw(this, this.position.x, this.position.y, 1, 1);
345 }
346
347 /**
348 * Helper method that returns where the truck is visually to the player. This is used when
349 * checking the range when attacking the Fortress and getting attacked by the Fortress
350 *
351 * @return a vector where the truck is visually
352 */
353 public Vector2 getVisualPosition() {
354 return new Vector2(this.position.x + 0.5f, this.position.y + 0.5f);
355 }
356
357 /**
358 * Sets time of last attack to unix timestamp provided
359 * @param timestamp timestamp set as time of last attack
360 */
361 public void setTimeOfLastAttack(long timestamp) {
362 this.timeOfLastAttack = timestamp;
363 }
364
365 public void setAttacking(boolean b) {
366 this.attacking = b;
367 }
368
369 public void setMoving(boolean t) {
370 this.moving = t;
371 }
372
373 public long getTimeOfLastAttack() {
374 return timeOfLastAttack;
375 }
376
377 public float getHP() {
378 return this.HP;
379 }
380
381 public float getReserve() {
382 return this.reserve;
383 }
384
385 public FireTruckType getType() {
386 return this.type;
387 }
388
389 public void setCollision() {
390 this.inCollision = true;
391 }
392
393 public Vector2 getPosition() {
394 return this.position;
395 }
396
397 public Queue<Vector2> getTrailPath() {
398 return this.trailPath;
399 }
400
401 public Queue<Vector2> getPath() {
402 return this.path;
403 }
404
405 private ArrayList<WaterParticle> getSpray() {
406 return this.spray;
407 }
408
409 public boolean getMoving() {
410 return this.moving;
411 }
412 }
413