1 package ru
.deadsoftware
.cavedroid
.game
.world
;
3 import com
.badlogic
.gdx
.utils
.Disposable
;
4 import com
.badlogic
.gdx
.utils
.Timer
;
6 import ru
.deadsoftware
.cavedroid
.game
.GameItems
;
7 import ru
.deadsoftware
.cavedroid
.game
.GameScope
;
8 import ru
.deadsoftware
.cavedroid
.game
.mobs
.FallingGravel
;
9 import ru
.deadsoftware
.cavedroid
.game
.mobs
.FallingSand
;
10 import ru
.deadsoftware
.cavedroid
.game
.mobs
.MobsController
;
11 import ru
.deadsoftware
.cavedroid
.game
.model
.world
.generator
.WorldGeneratorConfig
;
12 import ru
.deadsoftware
.cavedroid
.game
.objects
.Block
;
13 import ru
.deadsoftware
.cavedroid
.game
.objects
.DropController
;
15 import javax
.annotation
.CheckForNull
;
16 import javax
.inject
.Inject
;
19 public class GameWorld
implements Disposable
{
21 private static final int UPDATE_RANGE
= 16;
23 private final DropController mDropController
;
24 private final MobsController mMobsController
;
26 private final Timer mGameFluidsTimer
;
27 private final GameFluidsThread mGameFluidsThread
;
29 private final int mWidth
;
30 private final int mHeight
;
31 private final int[][] mForeMap
;
32 private final int[][] mBackMap
;
34 private boolean mShouldUpdate
;
39 public GameWorld(DropController dropController
,
40 MobsController mobsController
,
41 @CheckForNull int[][] foreMap
,
42 @CheckForNull int[][] backMap
) {
43 mDropController
= dropController
;
44 mMobsController
= mobsController
;
46 boolean isNewGame
= foreMap
== null || backMap
== null;
49 final WorldGeneratorConfig config
= WorldGeneratorConfig
.Companion
.getDefault();
50 mWidth
= config
.getWidth();
51 mHeight
= config
.getHeight();
52 Pair
<int[][], int[][]> maps
= new GameWorldGenerator(config
).generate();
53 mForeMap
= maps
.getFirst();
54 mBackMap
= maps
.getSecond();
55 mMobsController
.getPlayer().respawn(this);
59 mWidth
= mForeMap
.length
;
60 mHeight
= mForeMap
[0].length
;
63 mGameFluidsThread
= new GameFluidsThread(this, mMobsController
);
65 mGameFluidsTimer
= new Timer();
66 mGameFluidsTimer
.scheduleTask(mGameFluidsThread
, 0, GameFluidsThread
.FLUID_UPDATE_INTERVAL_SEC
);
69 public int getWidth() {
73 public int getHeight() {
77 public float getWidthPx() {
81 public float getHeightPx() {
85 public int[][] getFullForeMap() {
89 public int[][] getFullBackMap() {
93 private int transformX(int x
) {
96 x
= getWidth() - Math
.abs(x
);
101 private int getMap(int x
, int y
, int layer
) {
105 map
= (layer
== 0) ? mForeMap
[x
][y
] : mBackMap
[x
][y
];
106 } catch (ArrayIndexOutOfBoundsException ignored
) {
111 private void setMap(int x
, int y
, int layer
, int value
) {
115 mForeMap
[x
][y
] = value
;
117 mBackMap
[x
][y
] = value
;
119 } catch (ArrayIndexOutOfBoundsException ignored
) {
123 public boolean hasForeAt(int x
, int y
) {
124 return getMap(x
, y
, 0) != 0;
127 public boolean hasBackAt(int x
, int y
) {
128 return getMap(x
, y
, 1) != 0;
131 public int getForeMap(int x
, int y
) {
132 return getMap(x
, y
, 0);
135 public Block
getForeMapBlock(int x
, int y
) {
136 return GameItems
.getBlock(getMap(x
, y
, 0));
139 public void setForeMap(int x
, int y
, int id
) {
143 public int getBackMap(int x
, int y
) {
144 return getMap(x
, y
, 1);
147 public Block
getBackMapBlock(int x
, int y
) {
148 return GameItems
.getBlock(getMap(x
, y
, 1));
151 public void setBackMap(int x
, int y
, int id
) {
155 private void placeSlab(int x
, int y
, int value
) {
158 setForeMap(x
, y
, 52);
161 setForeMap(x
, y
, 21);
170 setForeMap(x
, y
, 28);
173 setForeMap(x
, y
, 57);
178 public void placeToForeground(int x
, int y
, int value
) {
179 if (!hasForeAt(x
, y
) || value
== 0 || !GameItems
.getBlock(getForeMap(x
, y
)).hasCollision()) {
180 setForeMap(x
, y
, value
);
181 } else if (GameItems
.isSlab(value
) && getForeMap(x
, y
) == value
) {
182 placeSlab(x
, y
, value
);
186 mShouldUpdate
= true;
189 public void placeToBackground(int x
, int y
, int value
) {
190 if (value
== 0 || (getBackMap(x
, y
) == 0 && GameItems
.getBlock(value
).hasCollision()) &&
191 (!GameItems
.getBlock(value
).isTransparent() || value
== 18)) {
192 setBackMap(x
, y
, value
);
196 public void destroyForeMap(int x
, int y
) {
197 Block block
= GameItems
.getBlock(getForeMap(x
, y
));
198 if (block
.hasDrop()) {
199 mDropController
.addDrop(transformX(x
) * 16 + 4, y
* 16 + 4, GameItems
.getItemId(block
.getDrop()));
201 placeToForeground(x
, y
, 0);
204 public void destroyBackMap(int x
, int y
) {
205 Block block
= GameItems
.getBlock(getBackMap(x
, y
));
206 if (block
.hasDrop()) {
207 mDropController
.addDrop(transformX(x
) * 16 + 4, y
* 16 + 4, GameItems
.getItemId(block
.getDrop()));
209 placeToBackground(x
, y
, 0);
212 private void updateBlock(int x
, int y
) {
213 if (getForeMap(x
, y
) == 10) {
214 if (!hasForeAt(x
, y
+ 1) || !getForeMapBlock(x
, y
+ 1).hasCollision()) {
216 mMobsController
.addMob(new FallingSand(x
* 16, y
* 16));
217 updateBlock(x
, y
- 1);
221 if (getForeMap(x
, y
) == 11) {
222 if (!hasForeAt(x
, y
+ 1) || !getForeMapBlock(x
, y
+ 1).hasCollision()) {
224 mMobsController
.addMob(new FallingGravel(x
* 16, y
* 16));
225 updateBlock(x
, y
- 1);
229 if (hasForeAt(x
, y
) && getForeMapBlock(x
, y
).requiresBlock()) {
230 if (!hasForeAt(x
, y
+ 1) || !getForeMapBlock(x
, y
+ 1).hasCollision()) {
231 destroyForeMap(x
, y
);
232 updateBlock(x
, y
- 1);
236 if (getForeMap(x
, y
) == 2) {
237 if (hasForeAt(x
, y
- 1) && (getForeMapBlock(x
, y
- 1).hasCollision() ||
238 GameItems
.isFluid(getForeMap(x
, y
- 1)))) {
244 public void update() {
246 for (int y
= mUpdateY
; y
< mUpdateY
+ UPDATE_RANGE
; y
++) {
247 for (int x
= mUpdateX
; x
< mUpdateX
+ UPDATE_RANGE
; x
++) {
251 mShouldUpdate
= false;
256 public void dispose() {
257 mGameFluidsThread
.cancel();