1 package ru
.deadsoftware
.cavedroid
.game
;
3 import com
.badlogic
.gdx
.Gdx
;
4 import com
.badlogic
.gdx
.Input
;
5 import com
.badlogic
.gdx
.graphics
.g2d
.TextureRegion
;
6 import com
.badlogic
.gdx
.utils
.Disposable
;
7 import com
.badlogic
.gdx
.utils
.TimeUtils
;
8 import com
.google
.common
.collect
.Range
;
9 import ru
.deadsoftware
.cavedroid
.CaveGame
;
10 import ru
.deadsoftware
.cavedroid
.GameScreen
;
11 import ru
.deadsoftware
.cavedroid
.game
.mobs
.FallingGravel
;
12 import ru
.deadsoftware
.cavedroid
.game
.mobs
.FallingSand
;
13 import ru
.deadsoftware
.cavedroid
.game
.mobs
.Mob
;
14 import ru
.deadsoftware
.cavedroid
.game
.objects
.Drop
;
15 import ru
.deadsoftware
.cavedroid
.game
.objects
.Player
;
16 import ru
.deadsoftware
.cavedroid
.misc
.Assets
;
17 import ru
.deadsoftware
.cavedroid
.misc
.ControlMode
;
18 import ru
.deadsoftware
.cavedroid
.misc
.states
.GameState
;
20 import java
.io
.Serializable
;
21 import java
.util
.ArrayList
;
23 import static ru
.deadsoftware
.cavedroid
.game
.GameItems
.*;
25 public class GameProc
implements Serializable
, Disposable
{
27 static final int MAX_CREATIVE_SCROLL
= getItemsSize() / 8;
29 private static final int WORLD_WIDTH
= 1024;
30 private static final int WORLD_HEIGHT
= 256;
31 private static final int UPD_RANGE
= 16;
33 static boolean DO_UPD
= false;
34 static int UPD_X
= -1, UPD_Y
= -1;
36 private transient GameFluidsThread fluidThread
;
37 public transient GameWorld world
;
38 public transient GameRenderer renderer
;
39 transient GamePhysics physics
;
41 public ControlMode controlMode
;
43 public ArrayList
<Mob
> mobs
;
44 ArrayList
<Drop
> drops
;
46 public boolean isKeyDown
;
47 public int keyDownCode
;
49 float touchDownX
, touchDownY
;
57 public GameProc(int gameMode
) {
58 world
= new GameWorld(WORLD_WIDTH
, WORLD_HEIGHT
);
59 player
= new Player(gameMode
);
60 drops
= new ArrayList
<>();
61 mobs
= new ArrayList
<>();
62 physics
= new GamePhysics();
63 controlMode
= CaveGame
.TOUCH ? ControlMode
.WALK
: ControlMode
.CURSOR
;
68 public void resetRenderer() {
69 int scale
= CaveGame
.TOUCH ?
320 : 480;
70 renderer
= new GameRenderer(scale
, scale
* GameScreen
.getHeight() / GameScreen
.getWidth());
73 private void startFluidThread() {
74 fluidThread
= new GameFluidsThread();
78 private boolean isNotAutoselectable(int x
, int y
) {
79 return (!world
.hasForeAt(x
, y
) || !world
.getForeMapBlock(x
, y
).hasCollision());
82 private void checkCursorBounds() {
85 } else if (curY
>= world
.getHeight()) {
86 curY
= world
.getHeight() - 1;
89 if (controlMode
== ControlMode
.CURSOR
) {
90 if (curX
* 16 + 8 < player
.pos
.x
+ player
.getWidth() / 2) {
98 private void moveCursor() {
102 if (controlMode
== ControlMode
.WALK
&& CaveGame
.TOUCH
) {
103 curX
= player
.getMapX() + (player
.looksLeft() ?
-1 : 1);
104 curY
= player
.getUpperMapY();
105 for (int i
= 0; i
< 2 && isNotAutoselectable(curX
, curY
); i
++) {
108 if (isNotAutoselectable(curX
, curY
)) {
109 curX
+= player
.looksLeft() ?
1 : -1;
111 } else if (!CaveGame
.TOUCH
) {
112 curX
= (int) (Gdx
.input
.getX() * (renderer
.getWidth() / GameScreen
.getWidth()) + renderer
.getCamX()) / 16;
113 curY
= (int) (Gdx
.input
.getY() * (renderer
.getHeight() / GameScreen
.getHeight()) + renderer
.getCamY()) / 16;
114 if (curX
< 0) curX
--;
117 if (pastX
!= curX
|| pastY
!= curY
) {
124 private void updateBlock(int x
, int y
) {
125 if (world
.getForeMap(x
, y
) == 10) {
126 if (!world
.hasForeAt(x
, y
+ 1) || !world
.getForeMapBlock(x
, y
+ 1).hasCollision()) {
127 world
.setForeMap(x
, y
, 0);
128 mobs
.add(new FallingSand(x
* 16, y
* 16));
129 updateBlock(x
, y
- 1);
133 if (world
.getForeMap(x
, y
) == 11) {
134 if (!world
.hasForeAt(x
, y
+ 1) || !world
.getForeMapBlock(x
, y
+ 1).hasCollision()) {
135 world
.setForeMap(x
, y
, 0);
136 mobs
.add(new FallingGravel(x
* 16, y
* 16));
137 updateBlock(x
, y
- 1);
141 if (world
.hasForeAt(x
, y
) && world
.getForeMapBlock(x
, y
).requiresBlock()) {
142 if (!world
.hasForeAt(x
, y
+ 1) || !world
.getForeMapBlock(x
, y
+ 1).hasCollision()) {
143 world
.destroyForeMap(x
, y
);
144 updateBlock(x
, y
- 1);
148 if (world
.getForeMap(x
, y
) == 2) {
149 if (world
.hasForeAt(x
, y
- 1) && (world
.getForeMapBlock(x
, y
- 1).hasCollision() ||
150 isFluid(world
.getForeMap(x
, y
- 1)))) {
151 world
.setForeMap(x
, y
, 3);
156 private void blockUpdater() {
158 for (int y
= UPD_Y
; y
< UPD_Y
+ UPD_RANGE
; y
++) {
159 for (int x
= UPD_X
; x
< UPD_X
+ UPD_RANGE
; x
++) {
167 void useItem(int x
, int y
, int id
, boolean bg
) {
168 String key
= getItem(id
).isBlock() ?
getBlockKey(id
) : getItemKey(id
);
170 if (getItem(id
).isBlock()) {
172 world
.placeToForeground(x
, y
, getBlockIdByItemId(id
));
174 world
.placeToBackground(x
, y
, getBlockIdByItemId(id
));
179 world
.placeToForeground(x
, y
, getBlockId("water"));
180 player
.inventory
[player
.slot
] = getItemId("bucket_empty");
183 world
.placeToForeground(x
, y
, getBlockId("lava"));
184 player
.inventory
[player
.slot
] = getItemId("bucket_empty");
191 private void pressLMB() {
192 if ((world
.hasForeAt(curX
, curY
) && world
.getForeMapBlock(curX
, curY
).getHp() >= 0) ||
193 (!world
.hasForeAt(curX
, curY
) && world
.hasBackAt(curX
, curY
) &&
194 world
.getBackMapBlock(curX
, curY
).getHp() >= 0)) {
195 if (player
.gameMode
== 0) {
197 if (world
.hasForeAt(curX
, curY
)) {
198 if (blockDmg
>= world
.getForeMapBlock(curX
, curY
).getHp()) {
199 world
.destroyForeMap(curX
, curY
);
202 } else if (world
.hasBackAt(curX
, curY
)) {
203 if (blockDmg
>= world
.getBackMapBlock(curX
, curY
).getHp()) {
204 world
.destroyBackMap(curX
, curY
);
209 if (world
.hasForeAt(curX
, curY
)) {
210 world
.placeToForeground(curX
, curY
, 0);
211 } else if (world
.hasBackAt(curX
, curY
)) {
212 world
.placeToBackground(curX
, curY
, 0);
219 private boolean insideHotbar(float x
, float y
) {
220 TextureRegion hotbar
= Assets
.textureRegions
.get("hotbar");
221 return y
< hotbar
.getRegionHeight() &&
222 Range
.open(renderer
.getWidth() / 2 - (float) hotbar
.getRegionWidth() / 2,
223 renderer
.getWidth() / 2 + (float) hotbar
.getRegionWidth() / 2).contains(x
);
226 private void holdMB() {
227 if (touchDownBtn
== Input
.Buttons
.RIGHT
) {
228 useItem(curX
, curY
, player
.inventory
[player
.slot
], true);
231 if (insideHotbar(touchDownX
, touchDownY
)) {
232 CaveGame
.GAME_STATE
= GameState
.CREATIVE_INV
;
238 public void update() {
242 if (isTouchDown
&& touchDownBtn
== Input
.Buttons
.LEFT
) pressLMB();
243 if (isTouchDown
&& TimeUtils
.timeSinceMillis(touchDownTime
) > 500) holdMB();
244 if (fluidThread
== null || !fluidThread
.isAlive()) startFluidThread();
248 public void dispose() {
249 fluidThread
.interrupt();