-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTower.java
More file actions
136 lines (121 loc) · 4.14 KB
/
Tower.java
File metadata and controls
136 lines (121 loc) · 4.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import java.util.List;
import java.util.Random;
import greenfoot.Actor;
import greenfoot.Greenfoot;
/**
* An abstract class that determines the plan for a tower, but needs to be specialized as a special
* tower (one of the subclasses).
*/
public abstract class Tower extends Actor {
private int range;
private int reloadTime;
private int shootCountDown;
private int damage;
/**
* Creates an tower object with given characteristics, used at its subclasses.
*
* @param range - how far it can attack
* @param reloadTime - how long it needs to reload and shoot again
* @param damage - how much damage it deals
*/
public Tower(int range, int reloadTime, int damage) {
this.range = range;
this.reloadTime = reloadTime;
this.damage = damage;
this.shootCountDown = 0;
}
/**
* Shoots on zombies when the world is not paused and has to reload. Can be deleted after placed by
* the player.
*/
@Override
public void act() {
if(!getWorld().isPaused()) {
if(reload()) {
shoot();
}
}
checkRemoveTowerClick();
}
/**
* Deletes the tower when clicking on it while using the delete tool. The player gets his coins
* back.
*/
private void checkRemoveTowerClick() {
if(Greenfoot.mouseClicked(this) && Greenfoot.getMouseInfo().getButton() == 1) {
CursorImage.MouseState mouseState = getWorld().getCursorImage().getMouseState();
if(mouseState == CursorImage.MouseState.DELETE_TOOL) {
getWorld().getCoinsCounter().add(this.getPrice());
getWorld().removeObject(this);
}
}
}
/**
* Shoots at a zombie in range that got set as target.
*/
private void shoot() {
if(areZombiesInRange()) {
int index = new Random().nextInt(getZombiesInRange().size());
Zombie target = getZombiesInRange().get(index);
shootProjectileAt(target, damage);
shootCountDown = reloadTime;
}
}
/**
* Predicts the movement of the targeted zombie and shoots a projectile to it.
*
* @param target - the zombie that was set as target.
* @param damage - sets the damage the projectile will deal
*/
public void shootProjectileAt(Zombie target, int damage) {
double distanceX = target.getExactX() - this.getX();
double distanceY = target.getExactY() - this.getY();
double travelTime = Math.sqrt(distanceX * distanceX + distanceY * distanceY) / getProjetile(0, 0, 0).getSpeed();
int destinationX = (int) Math.round(target.getExactX() + (target.getMovement().getX() * travelTime));
int destinationY = (int) Math.round(target.getExactY() + (target.getMovement().getY() * travelTime));
System.out.println("(" + this.getX() + "+" + distanceX + "=" + target.getExactX() + ";" + this.getY() + "+" + distanceY + "="
+ target.getExactY() + ")" + " " + travelTime + " (" + destinationX + ";" + destinationY + ")");
getWorld().addObject(getProjetile(destinationX, destinationY, damage), getX(), getY());
}
/**
* Reloads a new projectile for the tower which needs some time (the countdown).
*
* @return <code>true</code> - if the countdown is zero (the projectile reloaded)
* <p>
* <code>false</code> - if the countdown is not zero (not reloaded)
*/
private boolean reload() {
if(shootCountDown > 0) {
shootCountDown--;
return false;
} else {
return true;
}
}
private boolean areZombiesInRange() {
return getZombiesInRange().size() > 0;
}
private List<Zombie> getZombiesInRange() {
return getObjectsInRange(range, Zombie.class);
}
public abstract int getPrice();
/**
*
* @return how many steps forward the tower thinks the {@link Zombie} will walk in the time while
* the {@link Projectile} flies towards it
*/
public abstract int getZombieMovementForwardPrediction();
/**
* get the {@link Projectile} respective for that Tower
*
* @param destinationX x-coordinate where the projectile should fly towards
* @param destinationY y-coordinate where the projectile should fly towards
* @param damage how much damage the projectile will deal if it hits
* @return the projectile
*/
public abstract Projectile getProjetile(int destinationX, int destinationY, int damage);
@Override
public GameWorld getWorld() {
return (GameWorld) super.getWorld();
}
}