DEADSOFTWARE

Reimplement mobs
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / GameInput.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.TimeUtils;
7 import com.google.common.collect.Range;
8 import ru.deadsoftware.cavedroid.CaveGame;
9 import ru.deadsoftware.cavedroid.GameScreen;
10 import ru.deadsoftware.cavedroid.game.mobs.Mob;
11 import ru.deadsoftware.cavedroid.game.mobs.Pig;
12 import ru.deadsoftware.cavedroid.misc.Assets;
13 import ru.deadsoftware.cavedroid.misc.ControlMode;
14 import ru.deadsoftware.cavedroid.misc.states.AppState;
15 import ru.deadsoftware.cavedroid.misc.states.GameState;
17 import static ru.deadsoftware.cavedroid.GameScreen.GP;
18 import static ru.deadsoftware.cavedroid.game.GameItems.*;
20 public class GameInput {
22 private boolean keyDown, touchedDown;
24 private int keyDownCode, touchDownBtn;
25 private float touchDownX, touchDownY;
26 private long touchDownTime;
28 private int curX, curY;
29 private int creativeScroll;
30 private int blockDamage;
32 private boolean checkSwim() {
33 return GameItems.isFluid(GP.world.getForeMap(GP.player.getMapX(), GP.player.getLowerMapY()));
34 }
36 private void goUpwards() {
37 if (checkSwim()) {
38 GP.player.swim = true;
39 } else if (GP.player.canJump()) {
40 GP.player.getMov().add(0, -7);
41 } else if (!GP.player.isFlyMode() && GP.player.gameMode == 1) {
42 GP.player.setFlyMode(true);
43 GP.player.getMov().y = 0;
44 } else if (GP.player.isFlyMode()) {
45 GP.player.getMov().y = -GamePhysics.PL_SPEED;
46 }
47 }
49 @SuppressWarnings("IntegerDivisionInFloatingPointContext")
50 private boolean insideCreativeInv(float screenX, float screenY) {
51 TextureRegion creative = Assets.textureRegions.get("creative");
52 return (screenX > GP.renderer.getWidth() / 2 - creative.getRegionWidth() / 2 &&
53 screenX < GP.renderer.getWidth() / 2 + creative.getRegionWidth() / 2 &&
54 screenY > GP.renderer.getHeight() / 2 - creative.getRegionHeight() / 2 &&
55 screenY < GP.renderer.getHeight() / 2 + creative.getRegionHeight() / 2);
56 }
58 private void wasdPressed(int keycode) {
59 if (GP.controlMode == ControlMode.WALK || !CaveGame.TOUCH) {
60 switch (keycode) {
61 case Input.Keys.A:
62 GP.player.getMov().x = -GamePhysics.PL_SPEED;
63 GP.player.setDir(Mob.LEFT);
64 if (CaveGame.TOUCH && checkSwim()) GP.player.swim = true;
65 break;
66 case Input.Keys.D:
67 GP.player.getMov().x = GamePhysics.PL_SPEED;
68 GP.player.setDir(Mob.RIGHT);
69 if (CaveGame.TOUCH && checkSwim()) GP.player.swim = true;
70 break;
71 case Input.Keys.W:
72 case Input.Keys.SPACE:
73 goUpwards();
74 break;
75 case Input.Keys.S:
76 case Input.Keys.CONTROL_LEFT:
77 GP.player.getMov().y = GamePhysics.PL_SPEED;
78 break;
79 }
80 } else {
81 switch (keycode) {
82 case Input.Keys.A:
83 curX--;
84 break;
85 case Input.Keys.D:
86 curX++;
87 break;
88 case Input.Keys.W:
89 curY--;
90 break;
91 case Input.Keys.S:
92 curY++;
93 break;
94 }
95 blockDamage = 0;
96 }
97 }
99 private boolean isNotAutoselectable(int x, int y) {
100 return (!GP.world.hasForeAt(x, y) || !GP.world.getForeMapBlock(x, y).hasCollision());
103 private void checkCursorBounds() {
104 if (curY < 0) {
105 curY = 0;
106 } else if (curY >= GP.world.getHeight()) {
107 curY = GP.world.getHeight() - 1;
110 if (GP.controlMode == ControlMode.CURSOR) {
111 if (curX * 16 + 8 < GP.player.getX() + GP.player.getWidth() / 2) {
112 GP.player.setDir(Mob.LEFT);
113 } else {
114 GP.player.setDir(Mob.RIGHT);
119 private void moveCursor() {
120 int pastX = curX;
121 int pastY = curY;
123 if (GP.controlMode == ControlMode.WALK && CaveGame.TOUCH) {
124 curX = GP.player.getMapX() + (GP.player.looksLeft() ? -1 : 1);
125 curY = GP.player.getUpperMapY();
126 for (int i = 0; i < 2 && isNotAutoselectable(curX, curY); i++) {
127 curY++;
129 if (isNotAutoselectable(curX, curY)) {
130 curX += GP.player.looksLeft() ? 1 : -1;
132 } else if (!CaveGame.TOUCH) {
133 curX = (int) (Gdx.input.getX() * (GP.renderer.getWidth() / GameScreen.getWidth()) + GP.renderer.getCamX()) / 16;
134 curY = (int) (Gdx.input.getY() * (GP.renderer.getHeight() / GameScreen.getHeight()) + GP.renderer.getCamY()) / 16;
135 if (curX < 0) curX--;
138 if (pastX != curX || pastY != curY) {
139 blockDamage = 0;
142 checkCursorBounds();
145 private void useItem(int x, int y, int id, boolean bg) {
146 String key = getItem(id).isBlock() ? getBlockKey(id) : getItemKey(id);
147 if (id > 0) {
148 if (getItem(id).isBlock()) {
149 if (!bg) {
150 GP.world.placeToForeground(x, y, getBlockIdByItemId(id));
151 } else {
152 GP.world.placeToBackground(x, y, getBlockIdByItemId(id));
154 } else {
155 switch (key) {
156 case "bucket_water":
157 GP.world.placeToForeground(x, y, getBlockId("water"));
158 GP.player.inventory[GP.player.slot] = getItemId("bucket_empty");
159 break;
160 case "bucket_lava":
161 GP.world.placeToForeground(x, y, getBlockId("lava"));
162 GP.player.inventory[GP.player.slot] = getItemId("bucket_empty");
163 break;
169 private void pressLMB() {
170 if ((GP.world.hasForeAt(curX, curY) && GP.world.getForeMapBlock(curX, curY).getHp() >= 0) ||
171 (!GP.world.hasForeAt(curX, curY) && GP.world.hasBackAt(curX, curY) &&
172 GP.world.getBackMapBlock(curX, curY).getHp() >= 0)) {
173 if (GP.player.gameMode == 0) {
174 blockDamage++;
175 if (GP.world.hasForeAt(curX, curY)) {
176 if (blockDamage >= GP.world.getForeMapBlock(curX, curY).getHp()) {
177 GP.world.destroyForeMap(curX, curY);
178 blockDamage = 0;
180 } else if (GP.world.hasBackAt(curX, curY)) {
181 if (blockDamage >= GP.world.getBackMapBlock(curX, curY).getHp()) {
182 GP.world.destroyBackMap(curX, curY);
183 blockDamage = 0;
186 } else {
187 if (GP.world.hasForeAt(curX, curY)) {
188 GP.world.placeToForeground(curX, curY, 0);
189 } else if (GP.world.hasBackAt(curX, curY)) {
190 GP.world.placeToBackground(curX, curY, 0);
192 touchedDown = false;
197 private boolean insideHotbar(float x, float y) {
198 TextureRegion hotbar = Assets.textureRegions.get("hotbar");
199 return y < hotbar.getRegionHeight() &&
200 Range.open(GP.renderer.getWidth() / 2 - (float) hotbar.getRegionWidth() / 2,
201 GP.renderer.getWidth() / 2 + (float) hotbar.getRegionWidth() / 2).contains(x);
204 private void holdMB() {
205 if (touchDownBtn == Input.Buttons.RIGHT) {
206 useItem(curX, curY, GP.player.inventory[GP.player.slot], true);
207 touchedDown = false;
208 } else {
209 if (insideHotbar(touchDownX, touchDownY)) {
210 CaveGame.GAME_STATE = GameState.CREATIVE_INV;
211 touchedDown = false;
216 public void keyDown(int keycode) {
217 keyDown = true;
218 keyDownCode = keycode;
219 switch (keycode) {
220 case Input.Keys.A:
221 case Input.Keys.D:
222 case Input.Keys.W:
223 case Input.Keys.S:
224 case Input.Keys.SPACE:
225 case Input.Keys.CONTROL_LEFT:
226 wasdPressed(keycode);
227 break;
229 case Input.Keys.ALT_LEFT:
230 if (CaveGame.TOUCH) {
231 GP.controlMode = GP.controlMode == ControlMode.WALK ? ControlMode.CURSOR : ControlMode.WALK;
233 break;
235 case Input.Keys.E:
236 if (CaveGame.GAME_STATE == GameState.PLAY) {
237 switch (GP.player.gameMode) {
238 case 0:
239 //TODO survival inv
240 break;
241 case 1:
242 CaveGame.GAME_STATE = GameState.CREATIVE_INV;
243 break;
245 } else {
246 CaveGame.GAME_STATE = GameState.PLAY;
248 break;
250 case Input.Keys.G:
251 GP.mobs.add(new Pig(curX * 16, curY * 16));
252 break;
254 case Input.Keys.Q:
255 GP.world.placeToForeground(curX, curY, 8);
256 break;
258 case Input.Keys.ESCAPE:
259 case Input.Keys.BACK:
260 CaveGame.APP_STATE = AppState.SAVE;
261 CaveGame.GAME_STATE = GameState.PAUSE;
262 break;
264 case Input.Keys.F1:
265 GameScreen.SHOW_DEBUG = !GameScreen.SHOW_DEBUG;
266 break;
268 case Input.Keys.M:
269 GameScreen.SHOW_MAP = !GameScreen.SHOW_MAP;
270 break;
274 public void keyUp(int keycode) {
275 switch (keycode) {
276 case Input.Keys.A:
277 case Input.Keys.D:
278 GP.player.getMov().x = 0;
279 if (CaveGame.TOUCH && GP.player.swim) GP.player.swim = false;
280 break;
282 case Input.Keys.W:
283 case Input.Keys.S:
284 case Input.Keys.SPACE:
285 case Input.Keys.CONTROL_LEFT:
286 if (GP.player.isFlyMode()) GP.player.getMov().y = 0;
287 if (GP.player.swim) GP.player.swim = false;
288 break;
292 public void touchDown(float touchX, float touchY, int button) {
293 touchDownTime = TimeUtils.millis();
294 touchedDown = true;
295 touchDownBtn = button;
296 touchDownX = touchX;
297 touchDownY = touchY;
300 public void touchUp(float screenX, float screenY, int button) {
301 if (CaveGame.TOUCH && keyDown) {
302 keyUp(keyDownCode);
303 keyDown = false;
305 TextureRegion hotbar = Assets.textureRegions.get("hotbar");
306 TextureRegion creative = Assets.textureRegions.get("creative");
307 if (touchedDown) {
308 if (CaveGame.GAME_STATE == GameState.CREATIVE_INV && insideCreativeInv(screenX, screenY)) {
309 int ix = (int) (screenX - (GP.renderer.getWidth() / 2 - creative.getRegionWidth() / 2 + 8)) / 18;
310 int iy = (int) (screenY - (GP.renderer.getHeight() / 2 - creative.getRegionHeight() / 2 + 18)) / 18;
311 int item = creativeScroll * 8 + (ix + iy * 8);
312 if (ix >= 8 || ix < 0 || iy < 0 || iy >= 5) item = -1;
313 if (item >= 0 && item < GameItems.getItemsSize()) {
314 System.arraycopy(GP.player.inventory, 0, GP.player.inventory, 1, 8);
315 GP.player.inventory[0] = item;
317 } else if (CaveGame.GAME_STATE == GameState.CREATIVE_INV) {
318 CaveGame.GAME_STATE = GameState.PLAY;
319 } else if (screenY < hotbar.getRegionHeight() &&
320 screenX > GP.renderer.getWidth() / 2 - (float) hotbar.getRegionWidth() / 2 &&
321 screenX < GP.renderer.getWidth() / 2 + (float) hotbar.getRegionWidth() / 2) {
322 GP.player.slot = (int) ((screenX - (GP.renderer.getWidth() / 2 - hotbar.getRegionWidth() / 2)) / 20);
323 } else if (button == Input.Buttons.RIGHT) {
324 useItem(curX, curY,
325 GP.player.inventory[GP.player.slot], false);
326 } else if (button == Input.Buttons.LEFT) {
327 blockDamage = 0;
330 touchedDown = false;
333 public void touchDragged(float screenX, float screenY) {
334 if (CaveGame.GAME_STATE == GameState.CREATIVE_INV && Math.abs(screenY - touchDownY) > 16) {
335 if (insideCreativeInv(screenX, screenY)) {
336 creativeScroll -= (screenY - touchDownY) / 16;
337 touchDownX = screenX;
338 touchDownY = screenY;
339 if (creativeScroll < 0) creativeScroll = 0;
340 if (creativeScroll > GameProc.MAX_CREATIVE_SCROLL)
341 creativeScroll = GameProc.MAX_CREATIVE_SCROLL;
346 public void scrolled(int amount) {
347 switch (CaveGame.GAME_STATE) {
348 case PLAY:
349 GP.player.slot += amount;
350 if (GP.player.slot < 0) GP.player.slot = 8;
351 if (GP.player.slot > 8) GP.player.slot = 0;
352 break;
353 case CREATIVE_INV:
354 creativeScroll += amount;
355 if (creativeScroll < 0) creativeScroll = 0;
356 if (creativeScroll > GameProc.MAX_CREATIVE_SCROLL)
357 creativeScroll = GameProc.MAX_CREATIVE_SCROLL;
358 break;
362 public int getKeyDownCode() {
363 return keyDownCode;
366 public boolean isKeyDown() {
367 return keyDown;
370 int getBlockDamage() {
371 return blockDamage;
374 int getCurX() {
375 return curX;
378 int getCurY() {
379 return curY;
382 int getCreativeScroll() {
383 return creativeScroll;
386 void update() {
387 moveCursor();
388 if (touchedDown && touchDownBtn == Input.Buttons.LEFT) {
389 pressLMB();
391 if (touchedDown && TimeUtils.timeSinceMillis(touchDownTime) > 500) {
392 holdMB();