1 package ru
.deadsoftware
.cavedroid
.game
;
3 import com
.badlogic
.gdx
.Gdx
;
4 import com
.badlogic
.gdx
.Input
;
5 import com
.badlogic
.gdx
.utils
.Disposable
;
6 import com
.badlogic
.gdx
.utils
.TimeUtils
;
7 import ru
.deadsoftware
.cavedroid
.CaveGame
;
8 import ru
.deadsoftware
.cavedroid
.GameScreen
;
9 import ru
.deadsoftware
.cavedroid
.game
.mobs
.FallingGravel
;
10 import ru
.deadsoftware
.cavedroid
.game
.mobs
.FallingSand
;
11 import ru
.deadsoftware
.cavedroid
.game
.mobs
.Mob
;
12 import ru
.deadsoftware
.cavedroid
.game
.objects
.Drop
;
13 import ru
.deadsoftware
.cavedroid
.game
.objects
.Player
;
14 import ru
.deadsoftware
.cavedroid
.misc
.ControlMode
;
15 import ru
.deadsoftware
.cavedroid
.misc
.Assets
;
16 import ru
.deadsoftware
.cavedroid
.misc
.states
.GameState
;
18 import java
.io
.Serializable
;
19 import java
.util
.ArrayList
;
21 import static ru
.deadsoftware
.cavedroid
.game
.GameItems
.*;
23 public class GameProc
implements Serializable
, Disposable
{
25 static final int MAX_CREATIVE_SCROLL
= getItemsSize() / 8;
27 private static final int WORLD_WIDTH
= 1024;
28 private static final int WORLD_HEIGHT
= 256;
29 private static final int UPD_RANGE
= 16;
31 static boolean DO_UPD
= false;
32 static int UPD_X
= -1, UPD_Y
= -1;
34 private transient GameFluidsThread fluidThread
;
35 public transient GameWorld world
;
36 public transient GameRenderer renderer
;
37 transient GamePhysics physics
;
39 public ControlMode controlMode
;
41 public ArrayList
<Mob
> mobs
;
42 ArrayList
<Drop
> drops
;
44 public boolean isTouchDown
, isKeyDown
;
45 public int touchDownX
, touchDownY
, touchDownBtn
, keyDownCode
;
52 public GameProc(int gameMode
) {
53 world
= new GameWorld(WORLD_WIDTH
, WORLD_HEIGHT
);
54 player
= new Player(gameMode
);
55 drops
= new ArrayList
<>();
56 mobs
= new ArrayList
<>();
57 physics
= new GamePhysics();
58 controlMode
= CaveGame
.TOUCH ? ControlMode
.WALK
: ControlMode
.CURSOR
;
63 public void resetRenderer() {
64 int scale
= CaveGame
.TOUCH ?
320 : 480;
65 renderer
= new GameRenderer(scale
, scale
* GameScreen
.getHeight() / GameScreen
.getWidth());
68 private void startFluidThread() {
69 fluidThread
= new GameFluidsThread();
73 private boolean isNotAutoselectable(int x
, int y
) {
74 return (!world
.hasForeAt(x
, y
) || !world
.getForeMapBlock(x
, y
).hasCollision());
77 private void checkCursorBounds() {
80 } else if (curY
>= world
.getHeight()) {
81 curY
= world
.getHeight() - 1;
84 if (controlMode
== ControlMode
.CURSOR
) {
85 if (curX
* 16 + 8 < player
.pos
.x
+ player
.getWidth() / 2) {
93 private void moveCursor() {
97 if (controlMode
== ControlMode
.WALK
&& CaveGame
.TOUCH
) {
98 curX
= player
.getMapX();
99 curY
= (int) (player
.pos
.y
+ player
.getWidth() / 16);
100 while (curY
- pastY
< 2 && isNotAutoselectable(curX
, curY
)) {
103 if (!isNotAutoselectable(curX
, curY
)) {
104 curX
+= player
.looksLeft() ?
1 : -1;
106 } else if (!CaveGame
.TOUCH
) {
107 curX
= (int) (Gdx
.input
.getX() * (renderer
.getWidth() / GameScreen
.getWidth()) + renderer
.getCamX()) / 16;
108 curY
= (int) (Gdx
.input
.getY() * (renderer
.getHeight() / GameScreen
.getHeight()) + renderer
.getCamY()) / 16;
109 if (curX
< 0) curX
--;
112 if (pastX
!= curX
|| pastY
!= curY
) {
119 private void updateBlock(int x
, int y
) {
120 if (world
.getForeMap(x
, y
) == 10) {
121 if (!world
.hasForeAt(x
, y
+ 1) || !world
.getForeMapBlock(x
, y
+ 1).hasCollision()) {
122 world
.setForeMap(x
, y
, 0);
123 mobs
.add(new FallingSand(x
* 16, y
* 16));
124 updateBlock(x
, y
- 1);
128 if (world
.getForeMap(x
, y
) == 11) {
129 if (!world
.hasForeAt(x
, y
+ 1) || !world
.getForeMapBlock(x
, y
+ 1).hasCollision()) {
130 world
.setForeMap(x
, y
, 0);
131 mobs
.add(new FallingGravel(x
* 16, y
* 16));
132 updateBlock(x
, y
- 1);
136 if (world
.hasForeAt(x
, y
) && world
.getForeMapBlock(x
, y
).requiresBlock()) {
137 if (!world
.hasForeAt(x
, y
+ 1) || !world
.getForeMapBlock(x
, y
+ 1).hasCollision()) {
138 world
.destroyForeMap(x
, y
);
139 updateBlock(x
, y
- 1);
143 if (world
.getForeMap(x
, y
) == 2) {
144 if (world
.hasForeAt(x
, y
- 1) && (world
.getForeMapBlock(x
, y
- 1).hasCollision() ||
145 isFluid(world
.getForeMap(x
, y
- 1)))) {
146 world
.setForeMap(x
, y
, 3);
151 private void blockUpdater() {
153 for (int y
= UPD_Y
; y
< UPD_Y
+ UPD_RANGE
; y
++) {
154 for (int x
= UPD_X
; x
< UPD_X
+ UPD_RANGE
; x
++) {
162 void useItem(int x
, int y
, int id
, boolean bg
) {
163 String key
= getItem(id
).isBlock() ?
getBlockKey(id
) : getItemKey(id
);
165 if (getItem(id
).isBlock()) {
167 world
.placeToForeground(x
, y
, getBlockIdByItemId(id
));
169 world
.placeToBackground(x
, y
, getBlockIdByItemId(id
));
174 world
.placeToForeground(x
, y
, getBlockId("water"));
175 player
.inventory
[player
.slot
] = getItemId("bucket_empty");
178 world
.placeToForeground(x
, y
, getBlockId("lava"));
179 player
.inventory
[player
.slot
] = getItemId("bucket_empty");
186 private void pressLMB() {
187 if ((world
.hasForeAt(curX
, curY
) && world
.getForeMapBlock(curX
, curY
).getHp() >= 0) ||
188 (!world
.hasForeAt(curX
, curY
) && world
.hasBackAt(curX
, curY
) &&
189 world
.getBackMapBlock(curX
, curY
).getHp() >= 0)) {
190 if (player
.gameMode
== 0) {
192 if (world
.hasForeAt(curX
, curY
)) {
193 if (blockDmg
>= world
.getForeMapBlock(curX
, curY
).getHp()) {
194 world
.destroyForeMap(curX
, curY
);
197 } else if (world
.hasBackAt(curX
, curY
)) {
198 if (blockDmg
>= world
.getBackMapBlock(curX
, curY
).getHp()) {
199 world
.destroyBackMap(curX
, curY
);
204 if (world
.hasForeAt(curX
, curY
)) {
205 world
.placeToForeground(curX
, curY
, 0);
206 } else if (world
.hasBackAt(curX
, curY
)) {
207 world
.placeToBackground(curX
, curY
, 0);
214 private void holdMB() {
215 if (touchDownBtn
== Input
.Buttons
.RIGHT
) {
216 useItem(curX
, curY
, player
.inventory
[player
.slot
], true);
218 } else if (touchDownBtn
== Input
.Buttons
.LEFT
) {
219 if (touchDownY
< Assets
.invBar
.getRegionHeight() &&
220 touchDownX
> renderer
.getWidth() / 2 - (float) Assets
.invBar
.getRegionWidth() / 2 &&
221 touchDownX
< renderer
.getWidth() / 2 + (float) Assets
.invBar
.getRegionWidth() / 2) {
222 CaveGame
.GAME_STATE
= GameState
.CREATIVE_INV
;
228 public void update() {
232 if (isTouchDown
&& touchDownBtn
== Input
.Buttons
.LEFT
) pressLMB();
233 if (isTouchDown
&& TimeUtils
.timeSinceMillis(touchDownTime
) > 500) holdMB();
234 if (fluidThread
== null || !fluidThread
.isAlive()) startFluidThread();
238 public void dispose() {
239 fluidThread
.interrupt();