DEADSOFTWARE

Implement DI for menu and refactor #13
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / GameWorld.java
1 package ru.deadsoftware.cavedroid.game;
3 import com.badlogic.gdx.utils.Disposable;
4 import ru.deadsoftware.cavedroid.game.mobs.FallingGravel;
5 import ru.deadsoftware.cavedroid.game.mobs.FallingSand;
6 import ru.deadsoftware.cavedroid.game.mobs.MobsController;
7 import ru.deadsoftware.cavedroid.game.objects.Block;
8 import ru.deadsoftware.cavedroid.game.objects.DropController;
10 import javax.annotation.CheckForNull;
11 import javax.inject.Inject;
13 @GameScope
14 public class GameWorld implements Disposable {
16 private static final int DEFAULT_WIDTH = 1024;
17 private static final int DEFAULT_HEIGHT = 256;
18 private static final int UPDATE_RANGE = 16;
20 private final DropController mDropController;
21 private final MobsController mMobsController;
22 private final GameFluidsThread mGameFluidsThread;
24 private final int mWidth;
25 private final int mHeight;
26 private final int[][] mForeMap;
27 private final int[][] mBackMap;
29 private boolean mShouldUpdate;
30 private int mUpdateX;
31 private int mUpdateY;
33 @Inject
34 public GameWorld(DropController dropController,
35 MobsController mobsController,
36 @CheckForNull int[][] foreMap,
37 @CheckForNull int[][] backMap) {
38 mDropController = dropController;
39 mMobsController = mobsController;
41 boolean isNewGame = foreMap == null || backMap == null;
43 if (isNewGame) {
44 mWidth = DEFAULT_WIDTH;
45 mHeight = DEFAULT_HEIGHT;
46 WorldGen.genWorld(mWidth, mHeight);
47 mForeMap = WorldGen.getForeMap();
48 mBackMap = WorldGen.getBackMap();
49 WorldGen.clear();
50 mMobsController.getPlayer().respawn(this);
51 } else {
52 mForeMap = foreMap;
53 mBackMap = backMap;
54 mWidth = mForeMap.length;
55 mHeight = mForeMap[0].length;
56 }
58 mGameFluidsThread = new GameFluidsThread(this, mMobsController, Thread.currentThread());
59 }
61 public int getWidth() {
62 return mWidth;
63 }
65 public int getHeight() {
66 return mHeight;
67 }
69 public float getWidthPx() {
70 return mWidth * 16f;
71 }
73 public float getHeightPx() {
74 return mHeight * 16f;
75 }
77 int[][] getFullForeMap() {
78 return mForeMap;
79 }
81 int[][] getFullBackMap() {
82 return mBackMap;
83 }
85 private int transformX(int x) {
86 x = x % getWidth();
87 if (x < 0) {
88 x = getWidth() - Math.abs(x);
89 }
90 return x;
91 }
93 private int getMap(int x, int y, int layer) {
94 int map = 0;
95 try {
96 x = transformX(x);
97 map = (layer == 0) ? mForeMap[x][y] : mBackMap[x][y];
98 } catch (ArrayIndexOutOfBoundsException ignored) {
99 }
100 return map;
103 private void setMap(int x, int y, int layer, int value) {
104 try {
105 x = transformX(x);
106 if (layer == 0) {
107 mForeMap[x][y] = value;
108 } else {
109 mBackMap[x][y] = value;
111 } catch (ArrayIndexOutOfBoundsException ignored) {
115 public boolean hasForeAt(int x, int y) {
116 return getMap(x, y, 0) != 0;
119 public boolean hasBackAt(int x, int y) {
120 return getMap(x, y, 1) != 0;
123 public int getForeMap(int x, int y) {
124 return getMap(x, y, 0);
127 public Block getForeMapBlock(int x, int y) {
128 return GameItems.getBlock(getMap(x, y, 0));
131 public void setForeMap(int x, int y, int id) {
132 setMap(x, y, 0, id);
135 public int getBackMap(int x, int y) {
136 return getMap(x, y, 1);
139 public Block getBackMapBlock(int x, int y) {
140 return GameItems.getBlock(getMap(x, y, 1));
143 public void setBackMap(int x, int y, int id) {
144 setMap(x, y, 1, id);
147 private void placeSlab(int x, int y, int value) {
148 switch (value) {
149 case 51:
150 setForeMap(x, y, 52);
151 break;
152 case 53:
153 setForeMap(x, y, 21);
154 break;
155 case 54:
156 setForeMap(x, y, 5);
157 break;
158 case 55:
159 setForeMap(x, y, 4);
160 break;
161 case 56:
162 setForeMap(x, y, 28);
163 break;
164 case 58:
165 setForeMap(x, y, 57);
166 break;
170 public void placeToForeground(int x, int y, int value) {
171 if (!hasForeAt(x, y) || value == 0 || !GameItems.getBlock(getForeMap(x, y)).hasCollision()) {
172 setForeMap(x, y, value);
173 } else if (GameItems.isSlab(value) && getForeMap(x, y) == value) {
174 placeSlab(x, y, value);
176 mUpdateX = x - 8;
177 mUpdateY = y - 8;
178 mShouldUpdate = true;
181 public void placeToBackground(int x, int y, int value) {
182 if (value == 0 || (getBackMap(x, y) == 0 && GameItems.getBlock(value).hasCollision()) &&
183 (!GameItems.getBlock(value).isTransparent() || value == 18)) {
184 setBackMap(x, y, value);
188 public void destroyForeMap(int x, int y) {
189 Block block = GameItems.getBlock(getForeMap(x, y));
190 if (block.hasDrop()) {
191 mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, GameItems.getItemId(block.getDrop()));
193 placeToForeground(x, y, 0);
196 public void destroyBackMap(int x, int y) {
197 Block block = GameItems.getBlock(getBackMap(x, y));
198 if (block.hasDrop()) {
199 mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, GameItems.getItemId(block.getDrop()));
201 placeToBackground(x, y, 0);
204 private void updateBlock(int x, int y) {
205 if (getForeMap(x, y) == 10) {
206 if (!hasForeAt(x, y + 1) || !getForeMapBlock(x, y + 1).hasCollision()) {
207 setForeMap(x, y, 0);
208 mMobsController.addMob(FallingSand.class, x * 16, y * 16);
209 updateBlock(x, y - 1);
210 }
213 if (getForeMap(x, y) == 11) {
214 if (!hasForeAt(x, y + 1) || !getForeMapBlock(x, y + 1).hasCollision()) {
215 setForeMap(x, y, 0);
216 mMobsController.addMob(FallingGravel.class, x * 16, y * 16);
217 updateBlock(x, y - 1);
221 if (hasForeAt(x, y) && getForeMapBlock(x, y).requiresBlock()) {
222 if (!hasForeAt(x, y + 1) || !getForeMapBlock(x, y + 1).hasCollision()) {
223 destroyForeMap(x, y);
224 updateBlock(x, y - 1);
228 if (getForeMap(x, y) == 2) {
229 if (hasForeAt(x, y - 1) && (getForeMapBlock(x, y - 1).hasCollision() ||
230 GameItems.isFluid(getForeMap(x, y - 1)))) {
231 setForeMap(x, y, 3);
236 public void update() {
237 if (mShouldUpdate) {
238 for (int y = mUpdateY; y < mUpdateY + UPDATE_RANGE; y++) {
239 for (int x = mUpdateX; x < mUpdateX + UPDATE_RANGE; x++) {
240 updateBlock(x, y);
243 mShouldUpdate = false;
246 if (!mGameFluidsThread.isAlive()) {
247 mGameFluidsThread.start();
251 public void startFluidsThread() {
252 mGameFluidsThread.start();
255 @Override
256 public void dispose() {
257 mGameFluidsThread.interrupt();