DEADSOFTWARE

Fix controls in creative inventory #18
[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, dragging;
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.getMove().add(0, -7);
41 } else if (!GP.player.isFlyMode() && GP.player.gameMode == 1) {
42 GP.player.setFlyMode(true);
43 GP.player.getMove().y = 0;
44 } else if (GP.player.isFlyMode()) {
45 GP.player.getMove().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.getMove().x = -GamePhysics.PL_SPEED;
63 GP.player.setDir(Mob.Direction.LEFT);
64 if (CaveGame.TOUCH && checkSwim()) {
65 GP.player.swim = true;
66 }
67 break;
68 case Input.Keys.D:
69 GP.player.getMove().x = GamePhysics.PL_SPEED;
70 GP.player.setDir(Mob.Direction.RIGHT);
71 if (CaveGame.TOUCH && checkSwim()) {
72 GP.player.swim = true;
73 }
74 break;
75 case Input.Keys.W:
76 case Input.Keys.SPACE:
77 goUpwards();
78 break;
79 case Input.Keys.S:
80 case Input.Keys.CONTROL_LEFT:
81 GP.player.getMove().y = GamePhysics.PL_SPEED;
82 break;
83 }
84 } else {
85 switch (keycode) {
86 case Input.Keys.A:
87 curX--;
88 break;
89 case Input.Keys.D:
90 curX++;
91 break;
92 case Input.Keys.W:
93 curY--;
94 break;
95 case Input.Keys.S:
96 curY++;
97 break;
98 }
99 blockDamage = 0;
103 private boolean isNotAutoselectable(int x, int y) {
104 return (!GP.world.hasForeAt(x, y) || !GP.world.getForeMapBlock(x, y).hasCollision());
107 private void checkCursorBounds() {
108 if (curY < 0) {
109 curY = 0;
110 } else if (curY >= GP.world.getHeight()) {
111 curY = GP.world.getHeight() - 1;
114 if (GP.controlMode == ControlMode.CURSOR) {
115 if (curX * 16 + 8 < GP.player.getX() + GP.player.getWidth() / 2) {
116 GP.player.setDir(Mob.Direction.LEFT);
117 } else {
118 GP.player.setDir(Mob.Direction.RIGHT);
123 private void moveCursor() {
124 int pastX = curX;
125 int pastY = curY;
127 if (GP.controlMode == ControlMode.WALK && CaveGame.TOUCH) {
128 curX = GP.player.getMapX() + (GP.player.looksLeft() ? -1 : 1);
129 curY = GP.player.getUpperMapY();
130 for (int i = 0; i < 2 && isNotAutoselectable(curX, curY); i++) {
131 curY++;
133 if (isNotAutoselectable(curX, curY)) {
134 curX += GP.player.looksLeft() ? 1 : -1;
136 } else if (!CaveGame.TOUCH) {
137 curX = (int) (Gdx.input.getX() * (GP.renderer.getWidth() /
138 GameScreen.getWidth()) + GP.renderer.getCamX()) / 16;
140 curY = (int) (Gdx.input.getY() * (GP.renderer.getHeight() /
141 GameScreen.getHeight()) + GP.renderer.getCamY()) / 16;
142 if (curX < 0) {
143 curX--;
147 if (pastX != curX || pastY != curY) {
148 blockDamage = 0;
151 checkCursorBounds();
154 private void useItem(int x, int y, int id, boolean bg) {
155 String key = getItem(id).isBlock() ? getBlockKey(id) : getItemKey(id);
156 if (id > 0) {
157 if (getItem(id).isBlock()) {
158 if (!bg) {
159 GP.world.placeToForeground(x, y, getBlockIdByItemId(id));
160 } else {
161 GP.world.placeToBackground(x, y, getBlockIdByItemId(id));
163 } else {
164 switch (key) {
165 case "bucket_water":
166 GP.world.placeToForeground(x, y, getBlockId("water"));
167 GP.player.inventory[GP.player.slot] = getItemId("bucket_empty");
168 break;
169 case "bucket_lava":
170 GP.world.placeToForeground(x, y, getBlockId("lava"));
171 GP.player.inventory[GP.player.slot] = getItemId("bucket_empty");
172 break;
178 private void pressLMB() {
179 if (CaveGame.GAME_STATE == GameState.PLAY &&
180 ((GP.world.hasForeAt(curX, curY) && GP.world.getForeMapBlock(curX, curY).getHp() >= 0) ||
181 (!GP.world.hasForeAt(curX, curY) && GP.world.hasBackAt(curX, curY) &&
182 GP.world.getBackMapBlock(curX, curY).getHp() >= 0))) {
183 if (GP.player.gameMode == 0) {
184 blockDamage++;
185 if (GP.world.hasForeAt(curX, curY)) {
186 if (blockDamage >= GP.world.getForeMapBlock(curX, curY).getHp()) {
187 GP.world.destroyForeMap(curX, curY);
188 blockDamage = 0;
190 } else if (GP.world.hasBackAt(curX, curY)) {
191 if (blockDamage >= GP.world.getBackMapBlock(curX, curY).getHp()) {
192 GP.world.destroyBackMap(curX, curY);
193 blockDamage = 0;
196 } else {
197 if (GP.world.hasForeAt(curX, curY)) {
198 GP.world.placeToForeground(curX, curY, 0);
199 } else if (GP.world.hasBackAt(curX, curY)) {
200 GP.world.placeToBackground(curX, curY, 0);
202 touchedDown = false;
207 private boolean insideHotbar(float x, float y) {
208 TextureRegion hotbar = Assets.textureRegions.get("hotbar");
209 return y < hotbar.getRegionHeight() &&
210 Range.open(GP.renderer.getWidth() / 2 - (float) hotbar.getRegionWidth() / 2,
211 GP.renderer.getWidth() / 2 + (float) hotbar.getRegionWidth() / 2).contains(x);
214 private void holdMB() {
215 if (touchDownBtn == Input.Buttons.RIGHT) {
216 useItem(curX, curY, GP.player.inventory[GP.player.slot], true);
217 touchedDown = false;
218 } else {
219 if (insideHotbar(touchDownX, touchDownY)) {
220 CaveGame.GAME_STATE = GameState.CREATIVE_INV;
221 touchedDown = false;
226 public void keyDown(int keycode) {
227 keyDown = true;
228 keyDownCode = keycode;
229 switch (keycode) {
230 case Input.Keys.A:
231 case Input.Keys.D:
232 case Input.Keys.W:
233 case Input.Keys.S:
234 case Input.Keys.SPACE:
235 case Input.Keys.CONTROL_LEFT:
236 wasdPressed(keycode);
237 break;
239 case Input.Keys.ALT_LEFT:
240 if (CaveGame.TOUCH) {
241 GP.controlMode = GP.controlMode == ControlMode.WALK ? ControlMode.CURSOR : ControlMode.WALK;
243 break;
245 case Input.Keys.E:
246 if (CaveGame.GAME_STATE == GameState.PLAY) {
247 switch (GP.player.gameMode) {
248 case 0:
249 //TODO survival inv
250 break;
251 case 1:
252 CaveGame.GAME_STATE = GameState.CREATIVE_INV;
253 break;
255 } else {
256 CaveGame.GAME_STATE = GameState.PLAY;
258 break;
260 case Input.Keys.G:
261 GP.mobs.add(new Pig(curX * 16, curY * 16));
262 break;
264 case Input.Keys.Q:
265 GP.world.placeToForeground(curX, curY, 8);
266 break;
268 case Input.Keys.ESCAPE:
269 case Input.Keys.BACK:
270 CaveGame.APP_STATE = AppState.SAVE;
271 CaveGame.GAME_STATE = GameState.PAUSE;
272 break;
274 case Input.Keys.F1:
275 GameScreen.SHOW_DEBUG = !GameScreen.SHOW_DEBUG;
276 break;
278 case Input.Keys.M:
279 GameScreen.SHOW_MAP = !GameScreen.SHOW_MAP;
280 break;
284 public void keyUp(int keycode) {
285 switch (keycode) {
286 case Input.Keys.A:
287 case Input.Keys.D:
288 GP.player.getMove().x = 0;
289 if (CaveGame.TOUCH && GP.player.swim) {
290 GP.player.swim = false;
292 break;
294 case Input.Keys.W:
295 case Input.Keys.S:
296 case Input.Keys.SPACE:
297 case Input.Keys.CONTROL_LEFT:
298 if (GP.player.isFlyMode()) {
299 GP.player.getMove().y = 0;
301 if (GP.player.swim) {
302 GP.player.swim = false;
304 break;
308 public void touchDown(float touchX, float touchY, int button) {
309 touchDownTime = TimeUtils.millis();
310 touchedDown = true;
311 touchDownBtn = button;
312 touchDownX = touchX;
313 touchDownY = touchY;
316 public void touchUp(float screenX, float screenY, int button) {
317 if (dragging) {
318 dragging = false;
319 return;
322 if (CaveGame.TOUCH && keyDown) {
323 keyUp(keyDownCode);
324 keyDown = false;
326 TextureRegion hotbar = Assets.textureRegions.get("hotbar");
327 TextureRegion creative = Assets.textureRegions.get("creative");
328 if (touchedDown) {
329 if (CaveGame.GAME_STATE == GameState.CREATIVE_INV && insideCreativeInv(screenX, screenY)) {
330 int ix = (int) (screenX - (GP.renderer.getWidth() / 2 - creative.getRegionWidth() / 2 + 8)) / 18;
331 int iy = (int) (screenY - (GP.renderer.getHeight() / 2 - creative.getRegionHeight() / 2 + 18)) / 18;
332 int item = creativeScroll * 8 + (ix + iy * 8);
333 if (ix >= 8 || ix < 0 || iy < 0 || iy >= 5) {
334 item = -1;
336 if (item >= 0 && item < GameItems.getItemsSize()) {
337 System.arraycopy(GP.player.inventory, 0, GP.player.inventory, 1, 8);
338 GP.player.inventory[0] = item;
340 } else if (CaveGame.GAME_STATE == GameState.CREATIVE_INV) {
341 CaveGame.GAME_STATE = GameState.PLAY;
342 } else if (screenY < hotbar.getRegionHeight() &&
343 screenX > GP.renderer.getWidth() / 2 - (float) hotbar.getRegionWidth() / 2 &&
344 screenX < GP.renderer.getWidth() / 2 + (float) hotbar.getRegionWidth() / 2) {
345 GP.player.slot = (int) ((screenX - (GP.renderer.getWidth() / 2 - hotbar.getRegionWidth() / 2)) / 20);
346 } else if (button == Input.Buttons.RIGHT) {
347 useItem(curX, curY,
348 GP.player.inventory[GP.player.slot], false);
349 } else if (button == Input.Buttons.LEFT) {
350 blockDamage = 0;
353 touchedDown = false;
356 public void touchDragged(float screenX, float screenY) {
357 dragging = true;
358 if (CaveGame.GAME_STATE == GameState.CREATIVE_INV && Math.abs(screenY - touchDownY) > 16) {
359 if (insideCreativeInv(screenX, screenY)) {
360 creativeScroll -= (screenY - touchDownY) / 16;
361 touchDownX = screenX;
362 touchDownY = screenY;
363 if (creativeScroll < 0) {
364 creativeScroll = 0;
366 if (creativeScroll > GameProc.MAX_CREATIVE_SCROLL) {
367 creativeScroll = GameProc.MAX_CREATIVE_SCROLL;
373 public void scrolled(int amount) {
374 switch (CaveGame.GAME_STATE) {
375 case PLAY:
376 GP.player.slot += amount;
377 if (GP.player.slot < 0) {
378 GP.player.slot = 8;
380 if (GP.player.slot > 8) {
381 GP.player.slot = 0;
383 break;
384 case CREATIVE_INV:
385 creativeScroll += amount;
386 if (creativeScroll < 0) {
387 creativeScroll = 0;
389 if (creativeScroll > GameProc.MAX_CREATIVE_SCROLL) {
390 creativeScroll = GameProc.MAX_CREATIVE_SCROLL;
392 break;
396 public int getKeyDownCode() {
397 return keyDownCode;
400 public boolean isKeyDown() {
401 return keyDown;
404 int getBlockDamage() {
405 return blockDamage;
408 int getCurX() {
409 return curX;
412 int getCurY() {
413 return curY;
416 int getCreativeScroll() {
417 return creativeScroll;
420 void update() {
421 moveCursor();
422 if (touchedDown && touchDownBtn == Input.Buttons.LEFT) {
423 pressLMB();
425 if (touchedDown && TimeUtils.timeSinceMillis(touchDownTime) > 500) {
426 holdMB();