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
.*;
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
;
42 private int mCreativeScroll
;
43 private int mBlockDamage
;
46 public GameInput(MainConfig mainConfig
,
48 MobsController mobsController
) {
49 mMainConfig
= mainConfig
;
50 mGameWorld
= gameWorld
;
51 mMobsController
= mobsController
;
53 mPlayer
= mMobsController
.getPlayer();
55 mControlMode
= mMainConfig
.isTouch() ? ControlMode
.WALK
: ControlMode
.CURSOR
;
58 private boolean checkSwim() {
59 return GameItems
.isFluid(mGameWorld
.getForeMap(mPlayer
.getMapX(), mPlayer
.getLowerMapY()));
62 private void goUpwards() {
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
;
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);
84 private void wasdPressed(int keycode
) {
85 if (mControlMode
== ControlMode
.WALK
|| !mMainConfig
.isTouch()) {
88 mPlayer
.getMove().x
= -GamePhysics
.PL_SPEED
;
89 mPlayer
.setDir(Mob
.Direction
.LEFT
);
90 if (mMainConfig
.isTouch() && checkSwim()) {
95 mPlayer
.getMove().x
= GamePhysics
.PL_SPEED
;
96 mPlayer
.setDir(Mob
.Direction
.RIGHT
);
97 if (mMainConfig
.isTouch() && checkSwim()) {
102 case Input
.Keys
.SPACE
:
106 case Input
.Keys
.CONTROL_LEFT
:
107 mPlayer
.getMove().y
= GamePhysics
.PL_SPEED
;
129 private boolean isNotAutoselectable(int x
, int y
) {
130 return (!mGameWorld
.hasForeAt(x
, y
) || !mGameWorld
.getForeMapBlock(x
, y
).hasCollision());
133 private void checkCursorBounds() {
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
);
144 mPlayer
.setDir(Mob
.Direction
.RIGHT
);
149 public void moveCursor(GameRenderer gameRenderer
) {
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
++) {
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;
173 if (pastX
!= mCurX
|| pastY
!= mCurY
) {
180 private void useItem(int x
, int y
, int id
, boolean bg
) {
181 String key
= getItem(id
).isBlock() ?
getBlockKey(id
) : getItemKey(id
);
183 if (getItem(id
).isBlock()) {
185 mGameWorld
.placeToForeground(x
, y
, getBlockIdByItemId(id
));
187 mGameWorld
.placeToBackground(x
, y
, getBlockIdByItemId(id
));
192 mGameWorld
.placeToForeground(x
, y
, getBlockId("water"));
193 mPlayer
.inventory
[mPlayer
.slot
] = getItemId("bucket_empty");
196 mGameWorld
.placeToForeground(x
, y
, getBlockId("lava"));
197 mPlayer
.inventory
[mPlayer
.slot
] = getItemId("bucket_empty");
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) {
211 if (mGameWorld
.hasForeAt(mCurX
, mCurY
)) {
212 if (mBlockDamage
>= mGameWorld
.getForeMapBlock(mCurX
, mCurY
).getHp()) {
213 mGameWorld
.destroyForeMap(mCurX
, mCurY
);
216 } else if (mGameWorld
.hasBackAt(mCurX
, mCurY
)) {
217 if (mBlockDamage
>= mGameWorld
.getBackMapBlock(mCurX
, mCurY
).getHp()) {
218 mGameWorld
.destroyBackMap(mCurX
, mCurY
);
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;
245 if (insideHotbar(mTouchDownX
, mTouchDownY
)) {
246 // CaveGame.GAME_STATE = GameState.CREATIVE_INV;
247 mTouchedDown
= false;
252 public void keyDown(int keycode
) {
254 mKeyDownCode
= keycode
;
260 case Input
.Keys
.SPACE
:
261 case Input
.Keys
.CONTROL_LEFT
:
262 wasdPressed(keycode
);
265 case Input
.Keys
.ALT_LEFT
:
266 if (mMainConfig
.isTouch()) {
267 mControlMode
= mControlMode
== ControlMode
.WALK ? ControlMode
.CURSOR
: ControlMode
.WALK
;
272 if (mMainConfig
.checkGameUiWindow(GameUiWindow
.NONE
)) {
273 switch (mPlayer
.gameMode
) {
278 mMainConfig
.setGameUiWindow(GameUiWindow
.CREATIVE_INVENTORY
);
282 mMainConfig
.setGameUiWindow(GameUiWindow
.NONE
);
287 mMobsController
.addMob(Pig
.class, mCurX
* 16, mCurY
* 16);
291 mGameWorld
.placeToForeground(mCurX
, mCurY
, 8);
294 // case Input.Keys.ESCAPE:
295 // case Input.Keys.BACK:
296 // CaveGame.APP_STATE = AppState.SAVE;
297 // CaveGame.GAME_STATE = GameState.PAUSE;
301 mMainConfig
.setShowInfo(!mMainConfig
.isShowInfo());
305 mMainConfig
.setShowMap(!mMainConfig
.isShowMap());
310 public void keyUp(int keycode
) {
314 mPlayer
.getMove().x
= 0;
315 if (mMainConfig
.isTouch() && mPlayer
.swim
) {
316 mPlayer
.swim
= false;
322 case Input
.Keys
.SPACE
:
323 case Input
.Keys
.CONTROL_LEFT
:
324 if (mPlayer
.isFlyMode()) {
325 mPlayer
.getMove().y
= 0;
328 mPlayer
.swim
= false;
334 public void touchDown(float touchX
, float touchY
, int button
) {
335 mTouchDownTime
= TimeUtils
.millis();
337 mTouchDownBtn
= button
;
338 mTouchDownX
= touchX
;
339 mTouchDownY
= touchY
;
342 public void touchUp(float screenX
, float screenY
, int button
) {
348 if (mMainConfig
.isTouch() && mKeyDown
) {
352 TextureRegion hotbar
= Assets
.textureRegions
.get("hotbar");
353 TextureRegion creative
= Assets
.textureRegions
.get("creative");
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) {
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
) {
379 mTouchedDown
= false;
382 public void touchDragged(float screenX
, float screenY
) {
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) {
392 if (mCreativeScroll
> GameProc
.MAX_CREATIVE_SCROLL
) {
393 mCreativeScroll
= GameProc
.MAX_CREATIVE_SCROLL
;
399 public void scrolled(int amount
) {
400 switch (mMainConfig
.getGameUiWindow()) {
402 mPlayer
.slot
+= amount
;
403 if (mPlayer
.slot
< 0) {
406 if (mPlayer
.slot
> 8) {
410 case CREATIVE_INVENTORY
:
411 mCreativeScroll
+= amount
;
412 if (mCreativeScroll
< 0) {
415 if (mCreativeScroll
> GameProc
.MAX_CREATIVE_SCROLL
) {
416 mCreativeScroll
= GameProc
.MAX_CREATIVE_SCROLL
;
422 public int getKeyDownCode() {
426 public boolean isKeyDown() {
430 int getBlockDamage() {
442 int getCreativeScroll() {
443 return mCreativeScroll
;
446 public ControlMode
getControlMode() {
450 public void setControlMode(ControlMode controlMode
) {
451 mControlMode
= controlMode
;
455 if (mTouchedDown
&& mTouchDownBtn
== Input
.Buttons
.LEFT
) {
458 if (mTouchedDown
&& TimeUtils
.timeSinceMillis(mTouchDownTime
) > 500) {