DEADSOFTWARE

3a5e3c4ff47044665b0d69cac4384f0c7bd7072c
[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.MainConfig;
9 import ru.deadsoftware.cavedroid.game.mobs.Mob;
10 import ru.deadsoftware.cavedroid.game.mobs.MobsController;
11 import ru.deadsoftware.cavedroid.game.mobs.Pig;
12 import ru.deadsoftware.cavedroid.game.mobs.Player;
13 import ru.deadsoftware.cavedroid.misc.Assets;
14 import ru.deadsoftware.cavedroid.misc.ControlMode;
16 import javax.inject.Inject;
18 import static ru.deadsoftware.cavedroid.game.GameItems.*;
20 @GameScope
21 public class GameInput {
23 private final MainConfig mMainConfig;
24 private final GameWorld mGameWorld;
25 private final MobsController mMobsController;
26 private final Player mPlayer;
28 private ControlMode mControlMode;
30 private boolean mKeyDown;
31 private boolean mTouchedDown;
32 private boolean mDragging;
34 private int mKeyDownCode;
35 private int mTouchDownBtn;
36 private float mTouchDownX;
37 private float mTouchDownY;
38 private long mTouchDownTime;
40 private int mCurX;
41 private int mCurY;
42 private int mCreativeScroll;
43 private int mBlockDamage;
45 @Inject
46 public GameInput(MainConfig mainConfig,
47 GameWorld gameWorld,
48 MobsController mobsController) {
49 mMainConfig = mainConfig;
50 mGameWorld = gameWorld;
51 mMobsController = mobsController;
53 mPlayer = mMobsController.getPlayer();
55 mControlMode = mMainConfig.isTouch() ? ControlMode.WALK : ControlMode.CURSOR;
56 }
58 private boolean checkSwim() {
59 return GameItems.isFluid(mGameWorld.getForeMap(mPlayer.getMapX(), mPlayer.getLowerMapY()));
60 }
62 private void goUpwards() {
63 if (checkSwim()) {
64 mPlayer.swim = true;
65 } else if (mPlayer.canJump()) {
66 mPlayer.getMove().add(0, -7);
67 } else if (!mPlayer.isFlyMode() && mPlayer.gameMode == 1) {
68 mPlayer.setFlyMode(true);
69 mPlayer.getMove().y = 0;
70 } else if (mPlayer.isFlyMode()) {
71 mPlayer.getMove().y = -GamePhysics.PL_SPEED;
72 }
73 }
75 @SuppressWarnings("IntegerDivisionInFloatingPointContext")
76 private boolean insideCreativeInv(float screenX, float screenY) {
77 TextureRegion creative = Assets.textureRegions.get("creative");
78 return (screenX > mMainConfig.getWidth() / 2 - creative.getRegionWidth() / 2 &&
79 screenX < mMainConfig.getWidth() / 2 + creative.getRegionWidth() / 2 &&
80 screenY > mMainConfig.getHeight() / 2 - creative.getRegionHeight() / 2 &&
81 screenY < mMainConfig.getHeight() / 2 + creative.getRegionHeight() / 2);
82 }
84 private void wasdPressed(int keycode) {
85 if (mControlMode == ControlMode.WALK || !mMainConfig.isTouch()) {
86 switch (keycode) {
87 case Input.Keys.A:
88 mPlayer.getMove().x = -GamePhysics.PL_SPEED;
89 mPlayer.setDir(Mob.Direction.LEFT);
90 if (mMainConfig.isTouch() && checkSwim()) {
91 mPlayer.swim = true;
92 }
93 break;
94 case Input.Keys.D:
95 mPlayer.getMove().x = GamePhysics.PL_SPEED;
96 mPlayer.setDir(Mob.Direction.RIGHT);
97 if (mMainConfig.isTouch() && checkSwim()) {
98 mPlayer.swim = true;
99 }
100 break;
101 case Input.Keys.W:
102 case Input.Keys.SPACE:
103 goUpwards();
104 break;
105 case Input.Keys.S:
106 case Input.Keys.CONTROL_LEFT:
107 mPlayer.getMove().y = GamePhysics.PL_SPEED;
108 break;
110 } else {
111 switch (keycode) {
112 case Input.Keys.A:
113 mCurX--;
114 break;
115 case Input.Keys.D:
116 mCurX++;
117 break;
118 case Input.Keys.W:
119 mCurY--;
120 break;
121 case Input.Keys.S:
122 mCurY++;
123 break;
125 mBlockDamage = 0;
129 private boolean isNotAutoselectable(int x, int y) {
130 return (!mGameWorld.hasForeAt(x, y) || !mGameWorld.getForeMapBlock(x, y).hasCollision());
133 private void checkCursorBounds() {
134 if (mCurY < 0) {
135 mCurY = 0;
136 } else if (mCurY >= mGameWorld.getHeight()) {
137 mCurY = mGameWorld.getHeight() - 1;
140 if (mControlMode == ControlMode.CURSOR) {
141 if (mCurX * 16 + 8 < mPlayer.getX() + mPlayer.getWidth() / 2) {
142 mPlayer.setDir(Mob.Direction.LEFT);
143 } else {
144 mPlayer.setDir(Mob.Direction.RIGHT);
149 public void moveCursor(GameRenderer gameRenderer) {
150 int pastX = mCurX;
151 int pastY = mCurY;
153 if (mControlMode == ControlMode.WALK && mMainConfig.isTouch()) {
154 mCurX = mPlayer.getMapX() + (mPlayer.looksLeft() ? -1 : 1);
155 mCurY = mPlayer.getUpperMapY();
156 for (int i = 0; i < 2 && isNotAutoselectable(mCurX, mCurY); i++) {
157 mCurY++;
159 if (isNotAutoselectable(mCurX, mCurY)) {
160 mCurX += mPlayer.looksLeft() ? 1 : -1;
162 } else if (!mMainConfig.isTouch()) {
163 mCurX = (int) (Gdx.input.getX() * (mMainConfig.getWidth() /
164 Gdx.graphics.getWidth()) + gameRenderer.getCamX()) / 16;
166 mCurY = (int) (Gdx.input.getY() * (mMainConfig.getHeight() /
167 Gdx.graphics.getHeight()) + gameRenderer.getCamY()) / 16;
168 if (mCurX < 0) {
169 mCurX--;
173 if (pastX != mCurX || pastY != mCurY) {
174 mBlockDamage = 0;
177 checkCursorBounds();
180 private void useItem(int x, int y, int id, boolean bg) {
181 String key = getItem(id).isBlock() ? getBlockKey(id) : getItemKey(id);
182 if (id > 0) {
183 if (getItem(id).isBlock()) {
184 if (!bg) {
185 mGameWorld.placeToForeground(x, y, getBlockIdByItemId(id));
186 } else {
187 mGameWorld.placeToBackground(x, y, getBlockIdByItemId(id));
189 } else {
190 switch (key) {
191 case "bucket_water":
192 mGameWorld.placeToForeground(x, y, getBlockId("water"));
193 mPlayer.inventory[mPlayer.slot] = getItemId("bucket_empty");
194 break;
195 case "bucket_lava":
196 mGameWorld.placeToForeground(x, y, getBlockId("lava"));
197 mPlayer.inventory[mPlayer.slot] = getItemId("bucket_empty");
198 break;
204 private void pressLMB() {
205 if (mMainConfig.checkGameUiWindow(GameUiWindow.NONE) &&
206 ((mGameWorld.hasForeAt(mCurX, mCurY) && mGameWorld.getForeMapBlock(mCurX, mCurY).getHp() >= 0) ||
207 (!mGameWorld.hasForeAt(mCurX, mCurY) && mGameWorld.hasBackAt(mCurX, mCurY) &&
208 mGameWorld.getBackMapBlock(mCurX, mCurY).getHp() >= 0))) {
209 if (mPlayer.gameMode == 0) {
210 mBlockDamage++;
211 if (mGameWorld.hasForeAt(mCurX, mCurY)) {
212 if (mBlockDamage >= mGameWorld.getForeMapBlock(mCurX, mCurY).getHp()) {
213 mGameWorld.destroyForeMap(mCurX, mCurY);
214 mBlockDamage = 0;
216 } else if (mGameWorld.hasBackAt(mCurX, mCurY)) {
217 if (mBlockDamage >= mGameWorld.getBackMapBlock(mCurX, mCurY).getHp()) {
218 mGameWorld.destroyBackMap(mCurX, mCurY);
219 mBlockDamage = 0;
222 } else {
223 if (mGameWorld.hasForeAt(mCurX, mCurY)) {
224 mGameWorld.placeToForeground(mCurX, mCurY, 0);
225 } else if (mGameWorld.hasBackAt(mCurX, mCurY)) {
226 mGameWorld.placeToBackground(mCurX, mCurY, 0);
228 mTouchedDown = false;
233 private boolean insideHotbar(float x, float y) {
234 TextureRegion hotbar = Assets.textureRegions.get("hotbar");
235 return y < hotbar.getRegionHeight() &&
236 Range.open(mMainConfig.getWidth() / 2 - (float) hotbar.getRegionWidth() / 2,
237 mMainConfig.getWidth() / 2 + (float) hotbar.getRegionWidth() / 2).contains(x);
240 private void holdMB() {
241 if (mTouchDownBtn == Input.Buttons.RIGHT) {
242 useItem(mCurX, mCurY, mPlayer.inventory[mPlayer.slot], true);
243 mTouchedDown = false;
244 } else {
245 if (insideHotbar(mTouchDownX, mTouchDownY)) {
246 // CaveGame.GAME_STATE = GameState.CREATIVE_INV;
247 mTouchedDown = false;
252 public void keyDown(int keycode) {
253 mKeyDown = true;
254 mKeyDownCode = keycode;
255 switch (keycode) {
256 case Input.Keys.A:
257 case Input.Keys.D:
258 case Input.Keys.W:
259 case Input.Keys.S:
260 case Input.Keys.SPACE:
261 case Input.Keys.CONTROL_LEFT:
262 wasdPressed(keycode);
263 break;
265 case Input.Keys.ALT_LEFT:
266 if (mMainConfig.isTouch()) {
267 mControlMode = mControlMode == ControlMode.WALK ? ControlMode.CURSOR : ControlMode.WALK;
269 break;
271 case Input.Keys.E:
272 if (mMainConfig.checkGameUiWindow(GameUiWindow.NONE)) {
273 switch (mPlayer.gameMode) {
274 case 0:
275 //TODO survival inv
276 break;
277 case 1:
278 mMainConfig.setGameUiWindow(GameUiWindow.CREATIVE_INVENTORY);
279 break;
281 } else {
282 mMainConfig.setGameUiWindow(GameUiWindow.NONE);
284 break;
286 case Input.Keys.G:
287 mMobsController.addMob(Pig.class, mCurX * 16, mCurY * 16);
288 break;
290 case Input.Keys.Q:
291 mGameWorld.placeToForeground(mCurX, mCurY, 8);
292 break;
294 // case Input.Keys.ESCAPE:
295 // case Input.Keys.BACK:
296 // CaveGame.APP_STATE = AppState.SAVE;
297 // CaveGame.GAME_STATE = GameState.PAUSE;
298 // break;
300 case Input.Keys.F1:
301 mMainConfig.setShowInfo(!mMainConfig.isShowInfo());
302 break;
304 case Input.Keys.M:
305 mMainConfig.setShowMap(!mMainConfig.isShowMap());
306 break;
310 public void keyUp(int keycode) {
311 switch (keycode) {
312 case Input.Keys.A:
313 case Input.Keys.D:
314 mPlayer.getMove().x = 0;
315 if (mMainConfig.isTouch() && mPlayer.swim) {
316 mPlayer.swim = false;
318 break;
320 case Input.Keys.W:
321 case Input.Keys.S:
322 case Input.Keys.SPACE:
323 case Input.Keys.CONTROL_LEFT:
324 if (mPlayer.isFlyMode()) {
325 mPlayer.getMove().y = 0;
327 if (mPlayer.swim) {
328 mPlayer.swim = false;
330 break;
334 public void touchDown(float touchX, float touchY, int button) {
335 mTouchDownTime = TimeUtils.millis();
336 mTouchedDown = true;
337 mTouchDownBtn = button;
338 mTouchDownX = touchX;
339 mTouchDownY = touchY;
342 public void touchUp(float screenX, float screenY, int button) {
343 if (mDragging) {
344 mDragging = false;
345 return;
348 if (mMainConfig.isTouch() && mKeyDown) {
349 keyUp(mKeyDownCode);
350 mKeyDown = false;
352 TextureRegion hotbar = Assets.textureRegions.get("hotbar");
353 TextureRegion creative = Assets.textureRegions.get("creative");
354 if (mTouchedDown) {
355 if (mMainConfig.checkGameUiWindow(GameUiWindow.CREATIVE_INVENTORY) && insideCreativeInv(screenX, screenY)) {
356 int ix = (int) (screenX - (mMainConfig.getWidth() / 2 - creative.getRegionWidth() / 2 + 8)) / 18;
357 int iy = (int) (screenY - (mMainConfig.getHeight() / 2 - creative.getRegionHeight() / 2 + 18)) / 18;
358 int item = mCreativeScroll * 8 + (ix + iy * 8);
359 if (ix >= 8 || ix < 0 || iy < 0 || iy >= 5) {
360 item = -1;
362 if (item >= 0 && item < GameItems.getItemsSize()) {
363 System.arraycopy(mPlayer.inventory, 0, mPlayer.inventory, 1, 8);
364 mPlayer.inventory[0] = item;
366 } else if (mMainConfig.checkGameUiWindow(GameUiWindow.CREATIVE_INVENTORY)) {
367 mMainConfig.setGameUiWindow(GameUiWindow.NONE);
368 } else if (screenY < hotbar.getRegionHeight() &&
369 screenX > mMainConfig.getWidth() / 2 - (float) hotbar.getRegionWidth() / 2 &&
370 screenX < mMainConfig.getWidth() / 2 + (float) hotbar.getRegionWidth() / 2) {
371 mPlayer.slot = (int) ((screenX - (mMainConfig.getWidth() / 2 - hotbar.getRegionWidth() / 2)) / 20);
372 } else if (button == Input.Buttons.RIGHT) {
373 useItem(mCurX, mCurY,
374 mPlayer.inventory[mPlayer.slot], false);
375 } else if (button == Input.Buttons.LEFT) {
376 mBlockDamage = 0;
379 mTouchedDown = false;
382 public void touchDragged(float screenX, float screenY) {
383 mDragging = true;
384 if (mMainConfig.checkGameUiWindow(GameUiWindow.CREATIVE_INVENTORY) && Math.abs(screenY - mTouchDownY) > 16) {
385 if (insideCreativeInv(screenX, screenY)) {
386 mCreativeScroll -= (screenY - mTouchDownY) / 16;
387 mTouchDownX = screenX;
388 mTouchDownY = screenY;
389 if (mCreativeScroll < 0) {
390 mCreativeScroll = 0;
392 if (mCreativeScroll > GameProc.MAX_CREATIVE_SCROLL) {
393 mCreativeScroll = GameProc.MAX_CREATIVE_SCROLL;
399 public void scrolled(int amount) {
400 switch (mMainConfig.getGameUiWindow()) {
401 case NONE:
402 mPlayer.slot += amount;
403 if (mPlayer.slot < 0) {
404 mPlayer.slot = 8;
406 if (mPlayer.slot > 8) {
407 mPlayer.slot = 0;
409 break;
410 case CREATIVE_INVENTORY:
411 mCreativeScroll += amount;
412 if (mCreativeScroll < 0) {
413 mCreativeScroll = 0;
415 if (mCreativeScroll > GameProc.MAX_CREATIVE_SCROLL) {
416 mCreativeScroll = GameProc.MAX_CREATIVE_SCROLL;
418 break;
422 public int getKeyDownCode() {
423 return mKeyDownCode;
426 public boolean isKeyDown() {
427 return mKeyDown;
430 int getBlockDamage() {
431 return mBlockDamage;
434 int getCurX() {
435 return mCurX;
438 int getCurY() {
439 return mCurY;
442 int getCreativeScroll() {
443 return mCreativeScroll;
446 public ControlMode getControlMode() {
447 return mControlMode;
450 public void setControlMode(ControlMode controlMode) {
451 mControlMode = controlMode;
454 void update() {
455 if (mTouchedDown && mTouchDownBtn == Input.Buttons.LEFT) {
456 pressLMB();
458 if (mTouchedDown && TimeUtils.timeSinceMillis(mTouchDownTime) > 500) {
459 holdMB();