-
Notifications
You must be signed in to change notification settings - Fork 18
/
PlayingState.java
251 lines (198 loc) · 8.96 KB
/
PlayingState.java
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
package com.fundynamic.d2tm.game.state;
import com.fundynamic.d2tm.Game;
import com.fundynamic.d2tm.game.controls.Mouse;
import com.fundynamic.d2tm.game.entities.Entity;
import com.fundynamic.d2tm.game.entities.EntityRepository;
import com.fundynamic.d2tm.game.entities.Player;
import com.fundynamic.d2tm.game.entities.Predicate;
import com.fundynamic.d2tm.game.entities.entitiesdata.EntitiesData;
import com.fundynamic.d2tm.game.entities.entitiesdata.EntitiesDataReader;
import com.fundynamic.d2tm.game.event.DebugKeysListener;
import com.fundynamic.d2tm.game.event.MouseListener;
import com.fundynamic.d2tm.game.event.QuitGameKeyListener;
import com.fundynamic.d2tm.game.map.Map;
import com.fundynamic.d2tm.game.map.MapEditor;
import com.fundynamic.d2tm.game.rendering.gui.DummyGuiElement;
import com.fundynamic.d2tm.game.rendering.gui.GuiComposite;
import com.fundynamic.d2tm.game.rendering.gui.battlefield.BattleField;
import com.fundynamic.d2tm.game.rendering.gui.battlefield.Recolorer;
import com.fundynamic.d2tm.game.rendering.gui.sidebar.Sidebar;
import com.fundynamic.d2tm.game.rendering.gui.topbar.Topbar;
import com.fundynamic.d2tm.game.terrain.TerrainFactory;
import com.fundynamic.d2tm.graphics.ImageRepository;
import com.fundynamic.d2tm.graphics.Shroud;
import com.fundynamic.d2tm.math.MapCoordinate;
import com.fundynamic.d2tm.math.Vector2D;
import org.newdawn.slick.*;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;
import static com.fundynamic.d2tm.Game.*;
import static com.fundynamic.d2tm.game.entities.entitiesdata.EntitiesData.HARVESTER;
public class PlayingState extends BasicGameState {
public static int ID = 0;
private final TerrainFactory terrainFactory;
private final Shroud shroud;
private final Input input;
private final Vector2D screenResolution;
private final int tileSize;
private Player human;
private Player cpu;
private GuiComposite guiComposite;
private EntityRepository entityRepository;
private ImageRepository imageRepository;
private Predicate updatableEntitiesPredicate;
private Predicate destroyedEntitiesPredicate;// pixels
public static final int HEIGHT_OF_TOP_BAR = 42;// pixels
public static final int HEIGHT_OF_BOTTOM_BAR = 32;
public static final int HEIGHT_OF_MINIMAP = 128;
public static final int WIDTH_OF_SIDEBAR = 160;
private MapEditor mapEditor;
private Map map;
public PlayingState(GameContainer gameContainer, TerrainFactory terrainFactory, ImageRepository imageRepository, Shroud shroud, int tileSize) throws SlickException {
this.terrainFactory = terrainFactory;
this.shroud = shroud;
this.tileSize = tileSize;
this.input = gameContainer.getInput();
this.screenResolution = getResolution();
this.imageRepository = imageRepository;
}
@Override
public int getID() {
return ID;
}
@Override
public void init(GameContainer gameContainer, StateBasedGame game) throws SlickException {
Player human = new Player("Human", Recolorer.FactionColor.RED);
Player cpu = new Player("CPU", Recolorer.FactionColor.GREEN);
if (Game.RECORDING_VIDEO) {
human.setCredits(9999);
} else {
human.setCredits(3000);
}
cpu.setCredits(2000);
mapEditor = new MapEditor(terrainFactory);
map = new Map(shroud, 64, 64);
entityRepository = createEntityRepository();
guiComposite = new GuiComposite();
Mouse mouse = Mouse.create(
human,
gameContainer,
imageRepository,
guiComposite
);
BattleField battlefield = makeBattleField(human, mouse);
guiComposite.addGuiElement(battlefield);
// topbar
guiComposite.addGuiElement(new Topbar(0, 0, SCREEN_WIDTH, HEIGHT_OF_TOP_BAR, human));
// sidebar
guiComposite.addGuiElement(
new Sidebar(
SCREEN_WIDTH - WIDTH_OF_SIDEBAR,
HEIGHT_OF_TOP_BAR,
WIDTH_OF_SIDEBAR,
SCREEN_HEIGHT - (HEIGHT_OF_BOTTOM_BAR + HEIGHT_OF_MINIMAP + HEIGHT_OF_TOP_BAR)
)
);
// minimap
guiComposite.addGuiElement(
new DummyGuiElement(
SCREEN_WIDTH - WIDTH_OF_SIDEBAR,
SCREEN_HEIGHT - (HEIGHT_OF_BOTTOM_BAR + HEIGHT_OF_MINIMAP),
WIDTH_OF_SIDEBAR,
SCREEN_HEIGHT - HEIGHT_OF_BOTTOM_BAR
)
);
// bottombar
guiComposite.addGuiElement(new DummyGuiElement(0, SCREEN_HEIGHT - HEIGHT_OF_BOTTOM_BAR, SCREEN_WIDTH - WIDTH_OF_SIDEBAR, HEIGHT_OF_BOTTOM_BAR));
input.addMouseListener(new MouseListener(mouse));
input.addKeyListener(new DebugKeysListener(battlefield, human));
input.addKeyListener(new QuitGameKeyListener(gameContainer));
initializeMap(entityRepository, human, cpu);
}
public BattleField makeBattleField(Player human, Mouse mouse) {
// GUI element: the rendering of the battlefield
BattleField battlefield;
try {
float moveSpeed = 30 * tileSize;
Vector2D viewingVector = Vector2D.create(32, 32);
Vector2D guiAreas = Vector2D.create(WIDTH_OF_SIDEBAR, (HEIGHT_OF_TOP_BAR + HEIGHT_OF_BOTTOM_BAR));
Vector2D viewportResolution = getResolution().min(guiAreas);
// start drawing below the top gui bar
Vector2D viewportDrawingPosition = Vector2D.create(0, HEIGHT_OF_TOP_BAR);
Image image = imageRepository.createImage(screenResolution);
battlefield = new BattleField(
viewportResolution,
viewportDrawingPosition,
viewingVector,
getMap(),
mouse,
moveSpeed,
tileSize,
human,
image,
entityRepository);
} catch (SlickException e) {
throw new IllegalStateException("Unable to create new battlefield!", e);
}
return battlefield;
}
public Map getMap() {
return map;
}
public MapEditor getMapEditor() {
return mapEditor;
}
public EntityRepository createEntityRepository() throws SlickException {
return new EntityRepository(getMap(), new Recolorer(), new EntitiesDataReader().fromRulesIni());
}
public void initializeMap(EntityRepository entityRepository, Player human, Player cpu) throws SlickException {
map = getMapEditor().generateRandom(map);
this.human = human;
this.cpu = cpu;
// TODO: read from SCENARIO.INI file
// human entities
entityRepository.placeUnitOnMap(MapCoordinate.create(2, 2), HARVESTER, human);
entityRepository.placeUnitOnMap(MapCoordinate.create(3, 2), "QUAD", human);
entityRepository.placeStructureOnMap(MapCoordinate.create(5, 5), EntitiesData.CONSTRUCTION_YARD, human);
// cpu entities
// entityRepository.placeUnitOnMap(MapCoordinate.create(3, 3), "QUAD", cpu);
entityRepository.placeStructureOnMap(MapCoordinate.create(57, 57), EntitiesData.CONSTRUCTION_YARD, cpu);
}
@Override
public void render(GameContainer container, StateBasedGame game, Graphics graphics) throws SlickException {
// Render all GUI elements
guiComposite.render(graphics);
Font font = graphics.getFont();
if (cpu.aliveEntities() < 1) {
// why like this!?
font.drawString(10, 220, "Enemy player has been destroyed. You have won the game.", Color.green);
}
if (human.aliveEntities() < 1) {
font.drawString(10, 220, "All your units and structures are destroyed. You have lost the game.", Color.red);
}
}
@Override
public void update(GameContainer container, StateBasedGame game, int delta) throws SlickException {
float deltaInSeconds = delta / 1000f;
Predicate<Entity> updatableEntities = updatableEntitiesPredicate();
for (Entity entity : entityRepository.filter(updatableEntities)) {
entity.update(deltaInSeconds);
}
human.update(deltaInSeconds);
cpu.update(deltaInSeconds);
entityRepository.removeEntities(destroyedEntitiesPredicate());
guiComposite.update(deltaInSeconds);
}
private Predicate<Entity> updatableEntitiesPredicate() {
if (this.updatableEntitiesPredicate == null) {
this.updatableEntitiesPredicate = Predicate.builder().isUpdateable().build();
}
return this.updatableEntitiesPredicate;
}
private Predicate<Entity> destroyedEntitiesPredicate() {
if (this.destroyedEntitiesPredicate == null) {
this.destroyedEntitiesPredicate = Predicate.builder().isDestroyed().build();
}
return this.destroyedEntitiesPredicate;
}
}