X-Git-Url: https://deadsoftware.ru/gitweb?a=blobdiff_plain;f=core%2Fsrc%2Fru%2Fdeadsoftware%2Fcavedroid%2Fgame%2FGamePhysics.java;h=9edffe4a9f3c41e128b1cfb30ee5e2561a6db5f1;hb=1c004c0ce7e183e773b5b486295c25e39732e899;hp=6695d6e76864606e4fe06a6aaaa80e8dcf3e97b1;hpb=f4d52e3e4a3712050532786fca0aded5ff8b5a03;p=cavedroid.git diff --git a/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java b/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java index 6695d6e..9edffe4 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java @@ -8,30 +8,41 @@ import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.game.mobs.Mob; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.mobs.Player; +import ru.deadsoftware.cavedroid.game.model.block.Block; import ru.deadsoftware.cavedroid.game.objects.Drop; +import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.world.GameWorld; +import javax.annotation.CheckForNull; import javax.inject.Inject; import java.util.Iterator; @GameScope -class GamePhysics { +public class GamePhysics { - static final int PL_SPEED = 2; + public static final float PL_JUMP_VELOCITY = -133.332f; + public static final float PL_TERMINAL_VELOCITY = 1254.4f; - private final Vector2 gravity = new Vector2(0, .9f); + private final Vector2 gravity = new Vector2(0, 444.44f); private final GameWorld mGameWorld; private final MainConfig mMainConfig; private final MobsController mMobsController; + private final DropController mDropController; + private final GameItemsHolder mGameItemsHolder; @Inject public GamePhysics(GameWorld gameWorld, MainConfig mainConfig, - MobsController mobsController) { + MobsController mobsController, + DropController dropController, + GameItemsHolder gameItemsHolder) { mGameWorld = gameWorld; mMainConfig = mainConfig; mMobsController = mobsController; + mDropController = dropController; + mGameItemsHolder = gameItemsHolder; } /** @@ -43,14 +54,14 @@ class GamePhysics { int dir = mob.looksLeft() ? 0 : 1; int blX = (int) (mob.getX() + mob.getWidth() * dir - 8 + 16 * dir); int blY = (int) (mob.getY() + mob.getHeight() - 8); - int block = mGameWorld.getForeMap(blX / 16, blY / 16); + Block block = mGameWorld.getForeMap(blX / 16, blY / 16); if (checkColl(new Rectangle(blX, mob.getY() - 18, mob.getWidth(), mob.getHeight()))) { - block = 0; + return false; } - return (block > 0 && GameItems.getBlock(block).toJump() && - (mob.getY() + mob.getHeight()) - GameItems.getBlock(block).getRectangle(blX / 16, blY / 16).y > 8); + return (block.toJump() && + (mob.getY() + mob.getHeight()) - block.getRectangle(blX / 16, blY / 16).y > 8); } private boolean checkColl(Rectangle rect) { @@ -67,12 +78,15 @@ class GamePhysics { maxY = mGameWorld.getHeight(); } - int block; + Block block; for (int y = minY; y < maxY; y++) { for (int x = minX; x < maxX; x++) { + if (!mGameWorld.hasForeAt(x, y)) { + continue; + } block = mGameWorld.getForeMap(x, y); - if (block > 0 && GameItems.getBlock(block).hasCollision()) { - if (Intersector.overlaps(rect, GameItems.getBlock(block).getRectangle(x, y))) { + if (block.hasCollision()) { + if (Intersector.overlaps(rect, block.getRectangle(x, y))) { return true; } } @@ -82,36 +96,77 @@ class GamePhysics { return false; } - private int getBlock(Rectangle rect) { + private Block getBlock(Rectangle rect) { return mGameWorld.getForeMap((int) (rect.x + rect.width / 2) / 16, (int) (rect.y + rect.height / 8 * 7) / 16); } - private void dropPhy(Drop drop) { - int dropToPlayer = drop.closeToPlayer(mGameWorld, mMobsController.getPlayer()); - if (dropToPlayer > 0) { - drop.moveToPlayer(mGameWorld, mMobsController.getPlayer(), dropToPlayer); + private Rectangle getShiftedPlayerRect(float shift) { + final Player player = mMobsController.getPlayer(); + return new Rectangle(player.x + shift, player.y, player.width, player.height); + } + + /** + * @return Rectangle representing magneting target for this drop + */ + @CheckForNull + private Rectangle getShiftedMagnetingPlayerRect(Drop drop) { + final Player player = mMobsController.getPlayer(); + + if (drop.canMagnetTo(player)) { + return getShiftedPlayerRect(0); + } + + final Rectangle shiftedLeft = getShiftedPlayerRect(-mGameWorld.getWidthPx()); + if (drop.canMagnetTo(shiftedLeft)) { + return shiftedLeft; + } + + final Rectangle shiftedRight = getShiftedPlayerRect(mGameWorld.getWidthPx()); + if (drop.canMagnetTo(shiftedRight)) { + return shiftedRight; + } + + return null; + } + + private void pickUpDropIfPossible(Rectangle shiftedPlayerTarget, Drop drop) { + final Player player = mMobsController.getPlayer(); + + if (Intersector.overlaps(shiftedPlayerTarget, drop)) { + player.pickUpDrop(drop); + } + } + + private void dropPhy(Drop drop, float delta) { + final Rectangle playerMagnetTarget = getShiftedMagnetingPlayerRect(drop); + final Vector2 dropVelocity = drop.getVelocity(); + + + if (playerMagnetTarget != null) { + final Vector2 magnetVector = new Vector2(playerMagnetTarget.x - drop.x, + playerMagnetTarget.y - drop.y); + magnetVector.nor().scl(Drop.MAGNET_VELOCITY * delta); + dropVelocity.add(magnetVector); } else { - if (drop.getMove().x >= .5f) { - drop.getMove().x -= .5f; - } else if (drop.getMove().x <= -.5f) { - drop.getMove().x += .5f; - } else { - drop.getMove().x = 0; - } - if (drop.getMove().y < 9) { - drop.getMove().y += gravity.y / 4; - } + dropVelocity.y += gravity.y * delta; } - drop.move(); + dropVelocity.x = MathUtils.clamp(dropVelocity.x, -Drop.MAGNET_VELOCITY, Drop.MAGNET_VELOCITY); + dropVelocity.y = MathUtils.clamp(dropVelocity.y, -Drop.MAGNET_VELOCITY, Drop.MAGNET_VELOCITY); + + drop.x += dropVelocity.x * delta; + drop.y += dropVelocity.y * delta; if (checkColl(drop)) { - drop.getMove().set(0, -1); + dropVelocity.setZero(); do { - drop.move(); + drop.y--; } while (checkColl(drop)); - drop.getMove().setZero(); + } + + if (playerMagnetTarget != null) { + pickUpDropIfPossible(playerMagnetTarget, drop); } } @@ -128,9 +183,9 @@ class GamePhysics { int d = 0; - if (mob.getMove().x < 0) { + if (mob.getVelocity().x < 0) { d = 1; - } else if (mob.getMove().x > 0) { + } else if (mob.getVelocity().x > 0) { d = -1; } @@ -153,13 +208,18 @@ class GamePhysics { if (checkColl(mob)) { int d = -1; - if (mob.getMove().y < 0) { + if (mob.getVelocity().y < 0) { d = 1; } if (d == -1) { mob.setCanJump(true); mob.setFlyMode(false); + + int dmg = ((int)Math.max(0f, (((mob.getVelocity().y * mob.getVelocity().y) / (2 * gravity.y)) - 48f) / 16f)); + if (dmg > 0) { + mob.damage(dmg); + } } mob.y = MathUtils.round(mob.getY()); @@ -168,10 +228,12 @@ class GamePhysics { mob.y += d; } - mob.getMove().y = 0; + mob.getVelocity().y = 0; } else { - mob.setCanJump(false); + mob.y += 1; + mob.setCanJump(checkColl(mob)); + mob.y -= 1; } if (mob.getY() > mGameWorld.getHeightPx()) { @@ -179,104 +241,102 @@ class GamePhysics { } } - private void playerPhy(Player player) { - player.y += player.getMove().y; - mobYColl(player); - + private void playerPhy(Player player, float delta) { if (player.isDead()) { return; } - if (GameItems.isFluid(getBlock(player))) { - if (mMainConfig.isTouch() && player.getMove().x != 0 && !player.swim && !player.isFlyMode()) { + if (getBlock(player).isFluid()) { + if (mMainConfig.isTouch() && player.getVelocity().x != 0 && !player.swim && !player.isFlyMode()) { player.swim = true; } if (!player.swim) { - if (!player.isFlyMode() && player.getMove().y < 4.5f) { - player.getMove().add(gravity.x / 4, gravity.y / 4); + if (!player.isFlyMode() && player.getVelocity().y < 32f) { + player.getVelocity().y += gravity.y * delta; } - if (!player.isFlyMode() && player.getMove().y > 4.5f) { - player.getMove().add(0, -1f); + if (!player.isFlyMode() && player.getVelocity().y > 32f) { + player.getVelocity().y -= player.getVelocity().y * 32f * delta; } } else { - player.getMove().add(0, -.5f); - if (player.getMove().y < -3) { - player.getMove().y = -3; + player.getVelocity().y += PL_JUMP_VELOCITY * delta; + if (player.getVelocity().y < -player.getSpeed()) { + player.getVelocity().y = -player.getSpeed(); } } } else { - if (!player.isFlyMode() && player.getMove().y < 18) { - player.getMove().add(gravity); + if (!player.isFlyMode() && player.getVelocity().y < PL_TERMINAL_VELOCITY) { + player.getVelocity().y += gravity.y * delta; } } - player.x += player.getMove().x * (player.isFlyMode() ? 1.5f : 1) * - (GameItems.isFluid(getBlock(player)) && !player.isFlyMode() ? .8f : 1); + player.y += player.getVelocity().y * delta; + mobYColl(player); + + player.x += player.getVelocity().x * (player.isFlyMode() ? 1.5f : 1) * + (getBlock(player).isFluid() && !player.isFlyMode() ? .8f : 1) * delta; mobXColl(player); - if (mMainConfig.isTouch() && !player.isFlyMode() && player.canJump() && player.getMove().x != 0 && checkJump(player)) { - player.getMove().add(0, -8); + if (mMainConfig.isTouch() && !player.isFlyMode() && player.canJump() && player.getVelocity().x != 0 && checkJump(player)) { + player.jump(); player.setCanJump(false); } } - private void mobPhy(Mob mob) { - if (mob.getType() == Mob.Type.MOB && GameItems.isFluid(getBlock(mob))) { - if (mob.getMove().y > 9) { - mob.getMove().add(0, -.9f); + private void mobPhy(Mob mob, float delta) { + if (mob.getType() == Mob.Type.MOB && getBlock(mob).isFluid()) { + if (mob.getVelocity().y > 32f) { + mob.getVelocity().y -= mob.getVelocity().y * 32f * delta; } - mob.getMove().add(0, -.5f); + mob.getVelocity().y += PL_JUMP_VELOCITY * delta; - if (mob.getMove().y < -3) { - mob.getMove().y = -3; + if (mob.getVelocity().y < -mob.getSpeed()) { + mob.getVelocity().y = -mob.getSpeed(); } - } else if (!mob.isFlyMode() && mob.getMove().y < 18) { - mob.getMove().add(gravity); + } else if (!mob.isFlyMode() && mob.getVelocity().y < PL_TERMINAL_VELOCITY) { + mob.getVelocity().y += gravity.y * delta; } - mob.y += mob.getMove().y; + mob.y += mob.getVelocity().y * delta; mobYColl(mob); if (mob.isDead()) { return; } - mob.x += mob.getMove().x; + mob.x += mob.getVelocity().x * delta; mobXColl(mob); - if (mob.canJump() && mob.getMove().x != 0 && checkJump(mob)) { - mob.getMove().add(0, -8); + if (mob.canJump() && mob.getVelocity().x != 0 && checkJump(mob)) { + mob.jump(); mob.setCanJump(false); } } - void update() { -// for (Iterator it = GP.drops.iterator(); it.hasNext(); ) { -// Drop drop = it.next(); -// dropPhy(drop); -// if (Intersector.overlaps(drop, GP.player)) { -// drop.pickUpDrop(GP.player); -// } -// if (drop.isPickedUp()) { -// it.remove(); -// } -// } - - for (Iterator it = mMobsController.getIterator(); it.hasNext(); ) { + void update(float delta) { + Player player = mMobsController.getPlayer(); + + for (Iterator it = mDropController.getIterator(); it.hasNext(); ) { + Drop drop = it.next(); + dropPhy(drop, delta); + if (drop.getPickedUp()) { + it.remove(); + } + } + + for (Iterator it = mMobsController.getMobs().iterator(); it.hasNext(); ) { Mob mob = it.next(); - mob.ai(mGameWorld); - mobPhy(mob); + mob.ai(mGameWorld, mGameItemsHolder, delta); + mobPhy(mob, delta); if (mob.isDead()) { it.remove(); } } - Player player = mMobsController.getPlayer(); - playerPhy(player); + playerPhy(player, delta); if (player.isDead()) { - player.respawn(mGameWorld); + player.respawn(mGameWorld, mGameItemsHolder); } }