X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;ds=sidebyside;f=core%2Fsrc%2Fru%2Fdeadsoftware%2Fcavedroid%2Fgame%2FGameRenderer.java;h=e063e09af073cb21899d389e6613f7fae6bdcf34;hb=0d6ab84418440a30f2de555cb30ce21af8dac12e;hp=4b418a7b566ac26b03c72a926c8b382ecc3c69db;hpb=13157246344c2b94d24354040f0f2d2fb5beb7ea;p=cavedroid.git diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java index 4b418a7..e063e09 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java @@ -1,15 +1,18 @@ package ru.deadsoftware.cavedroid.game; import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Input; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.math.Rectangle; -import com.badlogic.gdx.scenes.scene2d.ui.Label; -import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable; -import com.badlogic.gdx.utils.Align; +import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.ObjectMap; +import com.badlogic.gdx.utils.TimeUtils; +import org.jetbrains.annotations.Nullable; import ru.deadsoftware.cavedroid.MainConfig; -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler; +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler; +import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler; +import ru.deadsoftware.cavedroid.game.input.Joystick; import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction; import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction; import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey; @@ -22,10 +25,12 @@ import ru.deadsoftware.cavedroid.game.objects.TouchButton; import ru.deadsoftware.cavedroid.game.render.IGameRenderer; import ru.deadsoftware.cavedroid.game.ui.TooltipManager; import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager; +import ru.deadsoftware.cavedroid.game.world.GameWorld; import ru.deadsoftware.cavedroid.misc.Assets; import ru.deadsoftware.cavedroid.misc.Renderer; +import ru.deadsoftware.cavedroid.misc.utils.MeasureUnitsUtilsKt; +import ru.deadsoftware.cavedroid.misc.utils.RenderingUtilsKt; -import javax.annotation.CheckForNull; import javax.inject.Inject; import java.util.ArrayList; import java.util.Comparator; @@ -35,36 +40,54 @@ import java.util.Set; @GameScope public class GameRenderer extends Renderer { + private static final float CAMERA_SPEED = 72f; + private static final float MAX_CAM_DISTANCE_FROM_PLAYER = 64f; + private static final float DRAG_THRESHOLD = 1f; private static final TouchButton nullButton = new TouchButton(null, -1, true); private final MainConfig mMainConfig; private final MobsController mMobsController; + private final GameWorld mGameWorld; private final List mRenderers; private final CursorMouseInputHandler mCursorMouseInputHandler; private final MouseInputActionMapper mMouseInputActionMapper; private final KeyboardInputActionMapper mKeyboardInputActionMapper; - private final Set> mMouseInputHandlers; - private final Set> mKeyboardInputHandlers; + private final Set mMouseInputHandlers; + private final Set mKeyboardInputHandlers; private final GameWindowsManager mGameWindowsManager; private final TooltipManager mTooltipManager; + private final TouchButton mouseLeftTouchButton, mouseRightTouchButton; + + private final Vector2 mCamCenterToPlayer = new Vector2(); + + private float mTouchDownX, mTouchDownY; + private long mCameraDelayMs = 0L; + @Inject GameRenderer(MainConfig mainConfig, MobsController mobsController, + GameWorld gameWorld, Set renderers, CursorMouseInputHandler cursorMouseInputHandler, MouseInputActionMapper mouseInputActionMapper, KeyboardInputActionMapper keyboardInputActionMapper, - Set> mouseInputHandlers, - Set> keyboardInputHandlers, + Set mouseInputHandlers, + Set keyboardInputHandlers, GameWindowsManager gameWindowsManager, TooltipManager tooltipManager) { super(mainConfig.getWidth(), mainConfig.getHeight()); mMainConfig = mainConfig; mMobsController = mobsController; + mGameWorld = gameWorld; mRenderers = new ArrayList<>(renderers); - mRenderers.sort(Comparator.comparingInt(IGameRenderer::getRenderLayer)); + kotlin.collections.CollectionsKt.sortWith(mRenderers, new Comparator() { + @Override + public int compare(IGameRenderer o1, IGameRenderer o2) { + return o1.getRenderLayer() - o2.getRenderLayer(); + } + }); mCursorMouseInputHandler = cursorMouseInputHandler; mMouseInputActionMapper = mouseInputActionMapper; mKeyboardInputActionMapper = keyboardInputActionMapper; @@ -73,15 +96,103 @@ public class GameRenderer extends Renderer { mGameWindowsManager = gameWindowsManager; mTooltipManager = tooltipManager; + mouseLeftTouchButton = new TouchButton(new Rectangle(getWidth() / 2, 0f, getWidth() / 2, getHeight() / 2), Input.Buttons.LEFT, true); + mouseRightTouchButton = new TouchButton(new Rectangle(getWidth() / 2, getHeight() / 2, getWidth() / 2, getHeight() / 2), Input.Buttons.RIGHT, true); + + mMainConfig.setJoystick(new Joystick(mMobsController.getPlayer().getSpeed())); + Gdx.gl.glClearColor(0f, .6f, .6f, 1f); } - private float mTouchDownX, mTouchDownY; + private void updateDynamicCameraPosition(float delta) { + Player player = mMobsController.getPlayer(); + + float plTargetX = player.getX() + player.getWidth() / 2; + float plTargetY = player.getY() + player.getHeight() / 2; + + float camCenterX = getCamX() + getWidth() / 2; + float camCenterY = getCamY() + getHeight() / 2; - private void updateCameraPosition() { + float camTargetX, camTargetY; + + boolean followPlayer = player.controlMode == Player.ControlMode.WALK || !mMainConfig.isTouch(); + + if (followPlayer) { + camTargetX = plTargetX + Math.min(player.getVelocity().x * 2, getWidth() / 2); + camTargetY = plTargetY + player.getVelocity().y; + } else { + camTargetX = MeasureUnitsUtilsKt.getPx(player.cursorX) + MeasureUnitsUtilsKt.getPx(1) / 2; + camTargetY = MeasureUnitsUtilsKt.getPx(player.cursorY) + MeasureUnitsUtilsKt.getPx(1) / 2; + } + + Vector2 moveVector = new Vector2(camTargetX - camCenterX, camTargetY - camCenterY); + + if (followPlayer && player.getVelocity().isZero()) { + mCameraDelayMs = TimeUtils.millis(); + mCamCenterToPlayer.x = plTargetX - camCenterX; + mCamCenterToPlayer.y = plTargetY - camCenterY; + } + + if (TimeUtils.timeSinceMillis(mCameraDelayMs) < 500L && !player.getVelocity().isZero()) { + updateStaticCameraPosition(plTargetX - mCamCenterToPlayer.x, + camCenterY + moveVector.y * delta * 2); + return; + } + + float camX = getCamX(); + float camY = getCamY(); + float worldWidth = MeasureUnitsUtilsKt.getPx(mGameWorld.getWidth()) - getWidth() / 2; + + if (moveVector.x >= worldWidth) { + camX += mGameWorld.getWidthPx(); + moveVector.x -= mGameWorld.getWidthPx(); + } else if (moveVector.x <= -worldWidth) { + camX -= mGameWorld.getWidthPx(); + moveVector.x += mGameWorld.getWidthPx(); + } + + setCamPos(camX + moveVector.x * delta * 2, camY + moveVector.y * delta * 2); + + + camX = getCamX(); + camY = getCamY(); + + if (camX + getWidth() / 2 > plTargetX + MAX_CAM_DISTANCE_FROM_PLAYER) { + camX = plTargetX + MAX_CAM_DISTANCE_FROM_PLAYER - getWidth() / 2; + } + + if (camY + getHeight() / 2 > plTargetY + MAX_CAM_DISTANCE_FROM_PLAYER) { + camY = plTargetY + MAX_CAM_DISTANCE_FROM_PLAYER - getHeight() / 2; + } + + if (camX + getWidth() / 2 < plTargetX - MAX_CAM_DISTANCE_FROM_PLAYER) { + camX = plTargetX - MAX_CAM_DISTANCE_FROM_PLAYER - getWidth() / 2; + } + + if (camY + getHeight() / 2 < plTargetY - MAX_CAM_DISTANCE_FROM_PLAYER) { + camY = plTargetY - MAX_CAM_DISTANCE_FROM_PLAYER - getHeight() / 2; + } + + setCamPos(camX, camY); + } + + private void updateStaticCameraPosition(float targetX, float targetY) { + setCamPos(targetX - getWidth() / 2, targetY - getHeight() / 2); + } + + private void updateStaticCameraPosition() { Player player = mMobsController.getPlayer(); - setCamPos(player.getX() + player.getWidth() / 2 - getWidth() / 2, - player.getY() + player.getHeight() / 2 - getHeight() / 2); + + updateStaticCameraPosition(player.getX() + player.getWidth() / 2, + player.getY() + player.getHeight() / 2); + } + + private void updateCameraPosition(float delta) { + if (mMainConfig.isUseDynamicCamera()) { + updateDynamicCameraPosition(delta); + } else { + updateStaticCameraPosition(); + } } private float transformScreenX(int screenX) { @@ -107,25 +218,19 @@ public class GameRenderer extends Renderer { mCursorMouseInputHandler.handle(action); if (!mTooltipManager.getCurrentMouseTooltip().isEmpty()) { - final Label.LabelStyle style = new Label.LabelStyle(Assets.minecraftFont, Color.WHITE); - style.background = new TextureRegionDrawable(Assets.textureRegions.get("background")); - final Label label = new Label(mTooltipManager.getCurrentMouseTooltip(), style); - label.setX(screenX); - label.setY(screenY); -// label.setHeight(10f); -// label.setAlignment(Align.left, Align.top); - label.draw(spriter, 1f); + RenderingUtilsKt.drawString(spriter, mTooltipManager.getCurrentMouseTooltip(), screenX + 1, screenY + 1, Color.BLACK); + RenderingUtilsKt.drawString(spriter, mTooltipManager.getCurrentMouseTooltip(), screenX, screenY, Color.WHITE); } } - private boolean handleMouseAction(@CheckForNull MouseInputAction action) { + private boolean handleMouseAction(@Nullable MouseInputAction action) { if (action == null) { return false; } boolean anyProcessed = false; - for (IGameInputHandler handler : mMouseInputHandlers) { + for (IMouseInputHandler handler : mMouseInputHandlers) { final boolean conditions = handler.checkConditions(action); if (conditions) { anyProcessed = true; @@ -137,9 +242,9 @@ public class GameRenderer extends Renderer { return anyProcessed; } - private boolean onMouseActionEvent(int mouseX, int mouseY, int button, boolean touchUp) { - @CheckForNull MouseInputAction action = mMouseInputActionMapper - .map((float) mouseX, (float) mouseY, getCameraViewport(), button, touchUp); + private boolean onMouseActionEvent(int mouseX, int mouseY, int button, boolean touchUp, int pointer) { + @Nullable MouseInputAction action = mMouseInputActionMapper + .map((float) mouseX, (float) mouseY, getCameraViewport(), button, touchUp, pointer); return handleMouseAction(action); } @@ -148,16 +253,22 @@ public class GameRenderer extends Renderer { float touchX = transformScreenX(screenX); float touchY = transformScreenY(screenY); + final Joystick joy = mMainConfig.getJoystick(); + if (mMainConfig.isTouch()) { + if (joy != null && joy.getActive() && joy.getPointer() == pointer) { + return onMouseActionEvent(screenX, screenY, nullButton.getCode(), true, pointer); + } + TouchButton touchedKey = getTouchedKey(touchX, touchY); if (touchedKey.isMouse()) { - return onMouseActionEvent(screenX, screenY, touchedKey.getCode(), true); + return onMouseActionEvent(screenX, screenY, touchedKey.getCode(), true, pointer); } else { return keyUp(touchedKey.getCode()); } } - return onMouseActionEvent(screenX, screenY, button, true); + return onMouseActionEvent(screenX, screenY, button, true, pointer); } private TouchButton getTouchedKey(float touchX, float touchY) { @@ -170,6 +281,15 @@ public class GameRenderer extends Renderer { return button; } } + + if (mouseLeftTouchButton.getRect().contains(touchX, touchY)) { + return mouseLeftTouchButton; + } + + if (mouseRightTouchButton.getRect().contains(touchX, touchY)) { + return mouseRightTouchButton; + } + return nullButton; } @@ -184,13 +304,13 @@ public class GameRenderer extends Renderer { if (mMainConfig.isTouch()) { TouchButton touchedKey = getTouchedKey(touchX, touchY); if (touchedKey.isMouse()) { - return onMouseActionEvent(screenX, screenY, touchedKey.getCode(), false); + return onMouseActionEvent(screenX, screenY, touchedKey.getCode(), false, pointer); } else { return keyDown(touchedKey.getCode()); } } - return onMouseActionEvent(screenX, screenY, button, false); + return onMouseActionEvent(screenX, screenY, button, false, pointer); } @Override @@ -198,24 +318,24 @@ public class GameRenderer extends Renderer { float touchX = transformScreenX(screenX); float touchY = transformScreenY(screenY); - if (Math.abs(touchX - mTouchDownX) < 16 && Math.abs(touchY - mTouchDownY) < 16) { + if (Math.abs(touchX - mTouchDownX) < 16 && Math.abs(touchY - mTouchDownY) < DRAG_THRESHOLD) { return false; } - @CheckForNull MouseInputAction action = - mMouseInputActionMapper.mapDragged(screenX, screenY, getCameraViewport()); + @Nullable MouseInputAction action = + mMouseInputActionMapper.mapDragged(screenX, screenY, getCameraViewport(), pointer); return handleMouseAction(action); } @Override public boolean scrolled(float amountX, float amountY) { - @CheckForNull MouseInputAction action = mMouseInputActionMapper + @Nullable MouseInputAction action = mMouseInputActionMapper .mapScrolled(Gdx.input.getX(), Gdx.input.getY(), amountX, amountY, getCameraViewport()); return handleMouseAction(action); } private boolean handleKeyboardAction(int keycode, boolean isKeyDown) { - @CheckForNull final KeyboardInputAction action = mKeyboardInputActionMapper + @Nullable final KeyboardInputAction action = mKeyboardInputActionMapper .map(keycode, isKeyDown); if (action == null) { @@ -224,7 +344,7 @@ public class GameRenderer extends Renderer { boolean anyProcessed = false; - for (IGameInputHandler handler : mKeyboardInputHandlers) { + for (IKeyboardInputHandler handler : mKeyboardInputHandlers) { final boolean conditions = handler.checkConditions(action); if (conditions) { anyProcessed = true; @@ -248,12 +368,21 @@ public class GameRenderer extends Renderer { @Override public void render(float delta) { - updateCameraPosition(); + updateCameraPosition(delta); + + if (mMainConfig.getJoystick() != null && mMainConfig.getJoystick().getActive()) { + mMainConfig.getJoystick().updateState( + transformScreenX(Gdx.input.getX(mMainConfig.getJoystick().getPointer())), + transformScreenY(Gdx.input.getY(mMainConfig.getJoystick().getPointer())) + ); + } Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); spriter.begin(); - mRenderers.forEach(iGameRenderer -> iGameRenderer.draw(spriter, shaper, getCameraViewport(), delta)); + for (IGameRenderer iGameRenderer : mRenderers) { + iGameRenderer.draw(spriter, shaper, getCameraViewport(), delta); + } handleMousePosition(); spriter.end();