DEADSOFTWARE

Refactor
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / GameProc.java
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;
42 public Player player;
43 public ArrayList<Mob> mobs;
44 ArrayList<Drop> drops;
46 public boolean isKeyDown;
47 public int keyDownCode;
48 boolean isTouchDown;
49 float touchDownX, touchDownY;
50 int touchDownBtn;
51 long touchDownTime;
53 int curX, curY;
54 int creativeScroll;
55 int blockDmg = 0;
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;
64 resetRenderer();
65 startFluidThread();
66 }
68 public void resetRenderer() {
69 int scale = CaveGame.TOUCH ? 320 : 480;
70 renderer = new GameRenderer(scale, scale * GameScreen.getHeight() / GameScreen.getWidth());
71 }
73 private void startFluidThread() {
74 fluidThread = new GameFluidsThread();
75 fluidThread.start();
76 }
78 private boolean isNotAutoselectable(int x, int y) {
79 return (!world.hasForeAt(x, y) || !world.getForeMapBlock(x, y).hasCollision());
80 }
82 private void checkCursorBounds() {
83 if (curY < 0) {
84 curY = 0;
85 } else if (curY >= world.getHeight()) {
86 curY = world.getHeight() - 1;
87 }
89 if (controlMode == ControlMode.CURSOR) {
90 if (curX * 16 + 8 < player.pos.x + player.getWidth() / 2) {
91 player.setDir(0);
92 } else {
93 player.setDir(1);
94 }
95 }
96 }
98 private void moveCursor() {
99 int pastX = curX;
100 int pastY = curY;
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++) {
106 curY++;
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) {
118 blockDmg = 0;
121 checkCursorBounds();
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() {
157 if (DO_UPD) {
158 for (int y = UPD_Y; y < UPD_Y + UPD_RANGE; y++) {
159 for (int x = UPD_X; x < UPD_X + UPD_RANGE; x++) {
160 updateBlock(x, y);
163 DO_UPD = false;
167 void useItem(int x, int y, int id, boolean bg) {
168 String key = getItem(id).isBlock() ? getBlockKey(id) : getItemKey(id);
169 if (id > 0) {
170 if (getItem(id).isBlock()) {
171 if (!bg) {
172 world.placeToForeground(x, y, getBlockIdByItemId(id));
173 } else {
174 world.placeToBackground(x, y, getBlockIdByItemId(id));
176 } else {
177 switch (key) {
178 case "bucket_water":
179 world.placeToForeground(x, y, getBlockId("water"));
180 player.inventory[player.slot] = getItemId("bucket_empty");
181 break;
182 case "bucket_lava":
183 world.placeToForeground(x, y, getBlockId("lava"));
184 player.inventory[player.slot] = getItemId("bucket_empty");
185 break;
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) {
196 blockDmg++;
197 if (world.hasForeAt(curX, curY)) {
198 if (blockDmg >= world.getForeMapBlock(curX, curY).getHp()) {
199 world.destroyForeMap(curX, curY);
200 blockDmg = 0;
202 } else if (world.hasBackAt(curX, curY)) {
203 if (blockDmg >= world.getBackMapBlock(curX, curY).getHp()) {
204 world.destroyBackMap(curX, curY);
205 blockDmg = 0;
208 } else {
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);
214 isTouchDown = false;
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);
229 isTouchDown = false;
230 } else {
231 if (insideHotbar(touchDownX, touchDownY)) {
232 CaveGame.GAME_STATE = GameState.CREATIVE_INV;
233 isTouchDown = false;
238 public void update() {
239 physics.update();
240 moveCursor();
242 if (isTouchDown && touchDownBtn == Input.Buttons.LEFT) pressLMB();
243 if (isTouchDown && TimeUtils.timeSinceMillis(touchDownTime) > 500) holdMB();
244 if (fluidThread == null || !fluidThread.isAlive()) startFluidThread();
247 @Override
248 public void dispose() {
249 fluidThread.interrupt();