From 17c1be4c02b27fefa1bf6abd0547ac7e9743d493 Mon Sep 17 00:00:00 2001 From: fred-boy Date: Mon, 23 Dec 2019 14:52:53 +0700 Subject: [PATCH] Refactor physics #3 --- .../cavedroid/game/GameInput.java | 24 +- .../cavedroid/game/GamePhysics.java | 244 ++++++++++++------ .../deadsoftware/cavedroid/game/GameProc.java | 12 +- .../cavedroid/game/GameRenderer.java | 14 +- .../cavedroid/game/mobs/FallingGravel.java | 15 +- .../cavedroid/game/mobs/FallingSand.java | 15 +- .../deadsoftware/cavedroid/game/mobs/Mob.java | 162 ++++++------ .../deadsoftware/cavedroid/game/mobs/Pig.java | 47 ++-- .../cavedroid/game/mobs/Player.java | 42 ++- .../cavedroid/game/objects/Drop.java | 59 +++-- 10 files changed, 364 insertions(+), 270 deletions(-) diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameInput.java b/core/src/ru/deadsoftware/cavedroid/game/GameInput.java index 2fc38b7..379f930 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameInput.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameInput.java @@ -37,12 +37,12 @@ public class GameInput { if (checkSwim()) { GP.player.swim = true; } else if (GP.player.canJump()) { - GP.player.getMov().add(0, -7); + GP.player.getMove().add(0, -7); } else if (!GP.player.isFlyMode() && GP.player.gameMode == 1) { GP.player.setFlyMode(true); - GP.player.getMov().y = 0; + GP.player.getMove().y = 0; } else if (GP.player.isFlyMode()) { - GP.player.getMov().y = -GamePhysics.PL_SPEED; + GP.player.getMove().y = -GamePhysics.PL_SPEED; } } @@ -59,13 +59,13 @@ public class GameInput { if (GP.controlMode == ControlMode.WALK || !CaveGame.TOUCH) { switch (keycode) { case Input.Keys.A: - GP.player.getMov().x = -GamePhysics.PL_SPEED; - GP.player.setDir(Mob.LEFT); + GP.player.getMove().x = -GamePhysics.PL_SPEED; + GP.player.setDir(Mob.Direction.LEFT); if (CaveGame.TOUCH && checkSwim()) GP.player.swim = true; break; case Input.Keys.D: - GP.player.getMov().x = GamePhysics.PL_SPEED; - GP.player.setDir(Mob.RIGHT); + GP.player.getMove().x = GamePhysics.PL_SPEED; + GP.player.setDir(Mob.Direction.RIGHT); if (CaveGame.TOUCH && checkSwim()) GP.player.swim = true; break; case Input.Keys.W: @@ -74,7 +74,7 @@ public class GameInput { break; case Input.Keys.S: case Input.Keys.CONTROL_LEFT: - GP.player.getMov().y = GamePhysics.PL_SPEED; + GP.player.getMove().y = GamePhysics.PL_SPEED; break; } } else { @@ -109,9 +109,9 @@ public class GameInput { if (GP.controlMode == ControlMode.CURSOR) { if (curX * 16 + 8 < GP.player.getX() + GP.player.getWidth() / 2) { - GP.player.setDir(Mob.LEFT); + GP.player.setDir(Mob.Direction.LEFT); } else { - GP.player.setDir(Mob.RIGHT); + GP.player.setDir(Mob.Direction.RIGHT); } } } @@ -275,7 +275,7 @@ public class GameInput { switch (keycode) { case Input.Keys.A: case Input.Keys.D: - GP.player.getMov().x = 0; + GP.player.getMove().x = 0; if (CaveGame.TOUCH && GP.player.swim) GP.player.swim = false; break; @@ -283,7 +283,7 @@ public class GameInput { case Input.Keys.S: case Input.Keys.SPACE: case Input.Keys.CONTROL_LEFT: - if (GP.player.isFlyMode()) GP.player.getMov().y = 0; + if (GP.player.isFlyMode()) GP.player.getMove().y = 0; if (GP.player.swim) GP.player.swim = false; break; } diff --git a/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java b/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java index 2d2e4a4..ed31da7 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java @@ -4,10 +4,11 @@ import com.badlogic.gdx.math.Intersector; import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; +import org.jetbrains.annotations.NotNull; import ru.deadsoftware.cavedroid.CaveGame; import ru.deadsoftware.cavedroid.game.mobs.Mob; -import ru.deadsoftware.cavedroid.game.objects.Drop; import ru.deadsoftware.cavedroid.game.mobs.Player; +import ru.deadsoftware.cavedroid.game.objects.Drop; import java.util.Iterator; @@ -19,147 +20,217 @@ class GamePhysics { private final Vector2 gravity = new Vector2(0, .9f); - private boolean checkJump(Rectangle rect, int dir) { - int bl; - int blX = (int) (rect.x + rect.width * dir - 8 + 16 * dir); - int blY = (int) (rect.y + rect.height - 8); + /** + * Checks if mob should jump + * + * @return true if mob should jump + */ + private boolean checkJump(@NotNull Mob mob) { + 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 = GP.world.getForeMap(blX / 16, blY / 16); - bl = GP.world.getForeMap(blX / 16, blY / 16); - if (checkColl(new Rectangle(blX, rect.y - 18, rect.width, rect.height))) bl = 0; + if (checkColl(new Rectangle(blX, mob.getY() - 18, mob.getWidth(), mob.getHeight()))) { + block = 0; + } - return (bl > 0 && GameItems.getBlock(bl).toJump() && - (rect.y + rect.height) - GameItems.getBlock(bl).getRect(blX / 16, blY / 16).y > 8); + return (block > 0 && GameItems.getBlock(block).toJump() && + (mob.getY() + mob.getHeight()) - GameItems.getBlock(block).getRect(blX / 16, blY / 16).y > 8); } - private boolean checkColl(Rectangle rect) { - int bl; + private boolean checkColl(@NotNull Rectangle rect) { int minX = (int) ((rect.x + rect.width / 2) / 16) - 4; int minY = (int) ((rect.y + rect.height / 2) / 16) - 4; int maxX = (int) ((rect.x + rect.width / 2) / 16) + 4; int maxY = (int) ((rect.y + rect.height / 2) / 16) + 4; - if (minY < 0) minY = 0; - if (maxY > GP.world.getHeight()) maxY = GP.world.getHeight(); + + if (minY < 0) { + minY = 0; + } + + if (maxY > GP.world.getHeight()) { + maxY = GP.world.getHeight(); + } + + int block; for (int y = minY; y < maxY; y++) { for (int x = minX; x < maxX; x++) { - bl = GP.world.getForeMap(x, y); - if (bl > 0 && GameItems.getBlock(bl).hasCollision()) { - if (Intersector.overlaps(rect, GameItems.getBlock(bl).getRect(x, y))) { + block = GP.world.getForeMap(x, y); + if (block > 0 && GameItems.getBlock(block).hasCollision()) { + if (Intersector.overlaps(rect, GameItems.getBlock(block).getRect(x, y))) { return true; } } } } + return false; } - private int getBlock(Rectangle rect) { - return GP.world.getForeMap((int) (rect.x + rect.width / 2) / 16, (int) (rect.y + rect.height / 8 * 7) / 16); + private int getBlock(@NotNull Rectangle rect) { + return GP.world.getForeMap((int) (rect.x + rect.width / 2) / 16, + (int) (rect.y + rect.height / 8 * 7) / 16); } private void dropPhy(Drop drop) { if (drop.closeToPlayer() > 0) { drop.moveToPlayer(); } else { - if (drop.move.x >= .5f) drop.move.x -= .5f; - else if (drop.move.x <= -.5f) drop.move.x += .5f; - else drop.move.x = 0; - if (drop.move.y < 9) drop.move.y += gravity.y / 4; - } - drop.pos.add(drop.move); - if (drop.pos.x + 8 > GP.world.getWidthPx()) drop.pos.x -= GP.world.getWidthPx(); - else if (drop.pos.x < 0) drop.pos.x += GP.world.getWidthPx(); - drop.pos.y = MathUtils.round(drop.pos.y); - while (checkColl(drop.getRect())) { - drop.pos.y--; - drop.move.y = 0; + 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; + } + } + drop.move(); + + + if (checkColl(drop)) { + drop.getMove().set(0, -1); + do { + drop.move(); + } while (checkColl(drop)); + drop.getMove().setZero(); } } private void mobXColl(Mob mob) { - if (checkColl(mob.getRect())) { + if (checkColl(mob)) { if (mob.canJump() && !mob.isFlyMode()) { - mob.getPos().y -= 8; + mob.y -= 8; } - if (checkColl(mob.getRect())) { - if (mob.canJump() && !mob.isFlyMode()) mob.getPos().y += 8; + + if (checkColl(mob)) { + if (mob.canJump() && !mob.isFlyMode()) { + mob.y += 8; + } + int d = 0; - if (mob.getMov().x < 0) d = 1; - else if (mob.getMov().x > 0) d = -1; - mob.getPos().x = MathUtils.round(mob.getX()); - while (checkColl(mob.getRect())) mob.getPos().x += d; - if (mob.canJump()) mob.changeDir(); + + if (mob.getMove().x < 0) { + d = 1; + } else if (mob.getMove().x > 0) { + d = -1; + } + + mob.x = MathUtils.round(mob.getX()); + + while (checkColl(mob)) { + mob.x += d; + } + + if (mob.canJump()) { + mob.changeDir(); + } } } - if (mob.getX() + mob.getWidth() / 2 < 0) mob.getPos().x += GP.world.getWidthPx(); - if (mob.getX() + mob.getWidth() / 2 > GP.world.getWidthPx()) mob.getPos().x -= GP.world.getWidthPx(); + + mob.checkWorldBounds(); } private void mobYColl(Mob mob) { - if (checkColl(mob.getRect())) { + if (checkColl(mob)) { int d = -1; - if (mob.getMov().y < 0) d = 1; + + if (mob.getMove().y < 0) { + d = 1; + } + if (d == -1) { mob.setCanJump(true); mob.setFlyMode(false); } - mob.getPos().y = MathUtils.round(mob.getY()); - while (checkColl(mob.getRect())) mob.getPos().y += d; - mob.getMov().y = 0; - if (mob.getType() > 0) { - GP.world.setForeMap(mob.getMapX(), mob.getMiddleMapY(), mob.getType()); - mob.kill(); + + mob.y = MathUtils.round(mob.getY()); + + while (checkColl(mob)) { + mob.y += d; } + + mob.getMove().y = 0; + } else { mob.setCanJump(false); } + if (mob.getY() > GP.world.getHeightPx()) { mob.kill(); } } - private void playerPhy(Player pl) { - pl.getPos().y += pl.getMov().y; - mobYColl(pl); - if (pl.isDead()) return; + private void playerPhy(Player player) { + player.y += player.getMove().y; + mobYColl(player); + + if (player.isDead()) { + return; + } - if (GameItems.isFluid(getBlock(pl.getRect()))) { - if (CaveGame.TOUCH && pl.getMov().x != 0 && !pl.swim && !pl.isFlyMode()) pl.swim = true; - if (!pl.swim) { - if (!pl.isFlyMode() && pl.getMov().y < 4.5f) pl.getMov().add(gravity.x / 4, gravity.y / 4); - if (!pl.isFlyMode() && pl.getMov().y > 4.5f) pl.getMov().add(0, -1f); + if (GameItems.isFluid(getBlock(player))) { + if (CaveGame.TOUCH && player.getMove().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.getMove().y > 4.5f) { + player.getMove().add(0, -1f); + } } else { - pl.getMov().add(0, -.5f); - if (pl.getMov().y < -3) pl.getMov().y = -3; + player.getMove().add(0, -.5f); + if (player.getMove().y < -3) { + player.getMove().y = -3; + } } } else { - if (!pl.isFlyMode() && pl.getMov().y < 18) pl.getMov().add(gravity); + if (!player.isFlyMode() && player.getMove().y < 18) { + player.getMove().add(gravity); + } } - pl.getPos().x += pl.getMov().x * (pl.isFlyMode() ? 1.5f : 1) * (GameItems.isFluid(getBlock(pl.getRect())) && !pl.isFlyMode() ? .8f : 1); - mobXColl(pl); + player.x += player.getMove().x * (player.isFlyMode() ? 1.5f : 1) * (GameItems.isFluid(getBlock(player)) && !player.isFlyMode() ? .8f : 1); + mobXColl(player); - if (CaveGame.TOUCH && checkJump(pl.getRect(), pl.getDirection()) && !pl.isFlyMode() && pl.canJump() && pl.getMov().x != 0) { - pl.getMov().add(0, -8); - pl.setCanJump(false); + if (CaveGame.TOUCH && !player.isFlyMode() && player.canJump() && player.getMove().x != 0 && checkJump(player)) { + player.getMove().add(0, -8); + player.setCanJump(false); } } private void mobPhy(Mob mob) { - mob.getPos().y += mob.getMov().y; + if (mob.getType() == Mob.Type.MOB && GameItems.isFluid(getBlock(mob))) { + if (mob.getMove().y > 9) { + mob.getMove().add(0, -.9f); + } + + mob.getMove().add(0, -.5f); + + if (mob.getMove().y < -3) { + mob.getMove().y = -3; + } + } else if (!mob.isFlyMode() && mob.getMove().y < 18) { + mob.getMove().add(gravity); + } + + mob.y += mob.getMove().y; mobYColl(mob); - if (mob.isDead()) return; - if (mob.getType() == 0 && GameItems.isFluid(getBlock(mob.getRect()))) { - if (mob.getMov().y > 9) mob.getMov().add(0, -.9f); - mob.getMov().add(0, -.5f); - if (mob.getMov().y < -3) mob.getMov().y = -3; - } else if (!mob.isFlyMode() && mob.getMov().y < 18) mob.getMov().add(gravity); + if (mob.isDead()) { + return; + } - mob.getPos().x += mob.getMov().x; + mob.x += mob.getMove().x; mobXColl(mob); - if (checkJump(mob.getRect(), mob.getDirection()) && mob.canJump() && mob.getMov().x != 0) { - mob.getMov().add(0, -8); + if (mob.canJump() && mob.getMove().x != 0 && checkJump(mob)) { + mob.getMove().add(0, -8); mob.setCanJump(false); } } @@ -168,23 +239,30 @@ class GamePhysics { for (Iterator it = GP.drops.iterator(); it.hasNext(); ) { Drop drop = it.next(); dropPhy(drop); - if (Intersector.overlaps(drop.getRect(), GP.player.getRect())) drop.pickUpDrop(GP.player); - if (drop.pickedUp) it.remove(); + if (Intersector.overlaps(drop, GP.player)) { + drop.pickUpDrop(GP.player); + } + if (drop.isPickedUp()) { + it.remove(); + } } for (Iterator it = GP.mobs.iterator(); it.hasNext(); ) { Mob mob = it.next(); mob.ai(); mobPhy(mob); - if (mob.isDead()) it.remove(); + if (mob.isDead()) { + it.remove(); + } } playerPhy(GP.player); - if (GP.player.isDead()) GP.player.respawn(); + if (GP.player.isDead()) { + GP.player.respawn(); + } - GP.renderer.setCamPos( - GP.player.getPos().x + GP.player.getWidth() / 2 - GP.renderer.getWidth() / 2, - GP.player.getPos().y + GP.player.getHeight() / 2 - GP.renderer.getHeight() / 2); + GP.renderer.setCamPos(GP.player.getX() + GP.player.getWidth() / 2 - GP.renderer.getWidth() / 2, + GP.player.getY() + GP.player.getHeight() / 2 - GP.renderer.getHeight() / 2); } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameProc.java b/core/src/ru/deadsoftware/cavedroid/game/GameProc.java index 346d9c1..ff6d174 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameProc.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameProc.java @@ -6,12 +6,12 @@ import ru.deadsoftware.cavedroid.GameScreen; import ru.deadsoftware.cavedroid.game.mobs.FallingGravel; import ru.deadsoftware.cavedroid.game.mobs.FallingSand; import ru.deadsoftware.cavedroid.game.mobs.Mob; -import ru.deadsoftware.cavedroid.game.objects.Drop; import ru.deadsoftware.cavedroid.game.mobs.Player; +import ru.deadsoftware.cavedroid.game.objects.Drop; import ru.deadsoftware.cavedroid.misc.ControlMode; import java.io.Serializable; -import java.util.ArrayList; +import java.util.LinkedList; public class GameProc implements Serializable, Disposable { @@ -32,8 +32,8 @@ public class GameProc implements Serializable, Disposable { public ControlMode controlMode; public final Player player; - public final ArrayList mobs; - final ArrayList drops; + public final LinkedList mobs; + final LinkedList drops; public void resetRenderer() { int scale = CaveGame.TOUCH ? 320 : 480; @@ -43,8 +43,8 @@ public class GameProc implements Serializable, Disposable { public GameProc(int gameMode) { world = new GameWorld(WORLD_WIDTH, WORLD_HEIGHT); player = new Player(gameMode); - drops = new ArrayList<>(); - mobs = new ArrayList<>(); + drops = new LinkedList<>(); + mobs = new LinkedList<>(); physics = new GamePhysics(); input = new GameInput(); controlMode = CaveGame.TOUCH ? ControlMode.WALK : ControlMode.CURSOR; diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java index e6ead52..28e93bb 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java @@ -9,14 +9,13 @@ import com.badlogic.gdx.math.Rectangle; import ru.deadsoftware.cavedroid.CaveGame; import ru.deadsoftware.cavedroid.GameScreen; import ru.deadsoftware.cavedroid.game.mobs.Mob; -import ru.deadsoftware.cavedroid.game.mobs.Pig; import ru.deadsoftware.cavedroid.game.objects.Drop; -import ru.deadsoftware.cavedroid.misc.Assets; import ru.deadsoftware.cavedroid.misc.ControlMode; import ru.deadsoftware.cavedroid.misc.Renderer; import static ru.deadsoftware.cavedroid.GameScreen.GP; -import static ru.deadsoftware.cavedroid.misc.Assets.*; +import static ru.deadsoftware.cavedroid.misc.Assets.guiMap; +import static ru.deadsoftware.cavedroid.misc.Assets.textureRegions; public class GameRenderer extends Renderer { @@ -92,6 +91,15 @@ public class GameRenderer extends Renderer { private void drawMob(Mob mob) { float mobDrawX = mob.getX() - getCamX(); float mobDrawY = mob.getY() - getCamY(); + + if (mobDrawX + mob.getWidth() < 0 && mobDrawX + GP.world.getWidthPx() > 0) { + mobDrawX += GP.world.getWidthPx(); + } else if (mobDrawX > getWidth() && mobDrawX + mob.getWidth() - GP.world.getWidthPx() > 0) { + mobDrawX -= GP.world.getWidthPx(); + } else if (mobDrawX + mob.getWidth() < 0 && mobDrawX > getWidth()) { + return; + } + mob.draw(spriter, mobDrawX, mobDrawY); } diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/FallingGravel.java b/core/src/ru/deadsoftware/cavedroid/game/mobs/FallingGravel.java index 850f8dd..fb56704 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/mobs/FallingGravel.java +++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/FallingGravel.java @@ -5,6 +5,8 @@ import com.badlogic.gdx.math.Vector2; import org.jetbrains.annotations.NotNull; import ru.deadsoftware.cavedroid.misc.Assets; +import static ru.deadsoftware.cavedroid.GameScreen.GP; + /** * Falling gravel is actually a mob, that spawns in place of gravel when there is no block under it, * falls down to the next block and becomes a block of gravel again. @@ -17,12 +19,16 @@ public class FallingGravel extends Mob { * @param y Y in pixels */ public FallingGravel(float x, float y) { - super(x, y, 16, 16, 0); - mov = new Vector2(0, 1); + super(x, y, 16, 16, Direction.LEFT, Type.GRAVEL); + move = new Vector2(0, 1); } @Override public void ai() { + if (move.isZero()) { + GP.world.setForeMap(getMapX(), getMiddleMapY(), 11); + kill(); + } } @Override @@ -34,9 +40,4 @@ public class FallingGravel extends Mob { spriteBatch.draw(Assets.gravelSprite, x, y); } - @Override - public int getType() { - return 11; - } - } diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/FallingSand.java b/core/src/ru/deadsoftware/cavedroid/game/mobs/FallingSand.java index d193dcf..0f44f05 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/mobs/FallingSand.java +++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/FallingSand.java @@ -5,6 +5,8 @@ import com.badlogic.gdx.math.Vector2; import org.jetbrains.annotations.NotNull; import ru.deadsoftware.cavedroid.misc.Assets; +import static ru.deadsoftware.cavedroid.GameScreen.GP; + /** * Falling sand is actually a mob, that spawns in place of gravel when there is no block under it, * falls down to the next block and becomes a block of sand again. @@ -17,12 +19,16 @@ public class FallingSand extends Mob { * @param y Y in pixels */ public FallingSand(float x, float y) { - super(x, y, 16, 16, 0); - mov = new Vector2(0, 1); + super(x, y, 16, 16, Direction.LEFT, Type.SAND); + move = new Vector2(0, 1); } @Override public void ai() { + if (move.isZero()) { + GP.world.setForeMap(getMapX(), getMiddleMapY(), 10); + kill(); + } } @Override @@ -34,9 +40,4 @@ public class FallingSand extends Mob { spriteBatch.draw(Assets.sandSprite, x, y); } - @Override - public int getType() { - return 10; - } - } diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/Mob.java b/core/src/ru/deadsoftware/cavedroid/game/mobs/Mob.java index 716c3df..723a929 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/mobs/Mob.java +++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/Mob.java @@ -7,20 +7,32 @@ import com.badlogic.gdx.math.Vector2; import java.io.Serializable; +import static ru.deadsoftware.cavedroid.GameScreen.GP; + /** * Mob class. */ -public abstract class Mob implements Serializable { - - public static final int LEFT = 0; - public static final int RIGHT = 1; +public abstract class Mob extends Rectangle implements Serializable { - private final float width; - private final float height; - private int dir; + protected Vector2 move; + protected Type type; + private Direction dir; - protected final Vector2 pos; - protected Vector2 mov; + /** + * @param x in pixels + * @param y in pixels + * @param width in pixels + * @param height in pixels + * @param dir Direction in which mob is looking + */ + protected Mob(float x, float y, float width, float height, Direction dir, Type type) { + super(x, y, width, height); + move = new Vector2(0, 0); + canJump = false; + dead = false; + this.dir = dir; + this.type = type; + } private boolean dead; @@ -28,145 +40,136 @@ public abstract class Mob implements Serializable { protected int animDelta = 6; protected int anim; - protected static int randomDir() { - return MathUtils.random(1); - } - - /** - * - * @param x in pixels - * @param y in pixels - * @param width in pixels - * @param height in pixels - * @param dir integer representing a direction where 0 is left and 1 is right. - * You should use {@link #LEFT} and {@link #RIGHT} constants - */ - protected Mob(float x, float y, float width, float height, int dir) { - pos = new Vector2(x, y); - mov = new Vector2(0, 0); - this.width = width; - this.height = height; - canJump = false; - dead = false; - this.dir = dir; + protected static Direction randomDir() { + return MathUtils.randomBoolean(.5f) ? Direction.LEFT : Direction.RIGHT; } /** - * * @return The X coordinate of a mob in blocks */ - public int getMapX() { - return (int) (pos.x + (getWidth() / 2)) / 16; + public final int getMapX() { + return (int) (x + (getWidth() / 2)) / 16; } /** - * * @return The Y coordinate of mob's upper edge in blocks */ - public int getUpperMapY() { - return (int) (pos.y / 16); + public final int getUpperMapY() { + return (int) (y / 16); } /** * * @return The Y coordinate if mob's vertical center in blocks */ - public int getMiddleMapY() { - return (int) (pos.y + (getHeight() / 2)) / 16; + public final int getMiddleMapY() { + return (int) (y + (getHeight() / 2)) / 16; } /** * * @return The Y coordinate of mob's legs in blocks */ - public int getLowerMapY() { - return (int) (pos.y + getHeight()) / 16; + public final int getLowerMapY() { + return (int) (y + getHeight()) / 16; } - public float getWidth() { + public final float getWidth() { return width; } - public float getHeight() { + public final float getHeight() { return height; } /** - * * @return Integer representing a direction in which mob is looking, where 0 is left and 1 is right */ - public int getDirection() { + public final Direction getDirection() { return dir; } - public boolean looksLeft() { - return getDirection() == LEFT; + public final boolean looksLeft() { + return dir == Direction.LEFT; } - public boolean looksRight() { - return getDirection() == RIGHT; + public final boolean looksRight() { + return dir == Direction.RIGHT; } /** * Switches direction in which mob is looking */ - protected void switchDir() { - dir = looksLeft() ? RIGHT : LEFT; + protected final void switchDir() { + dir = looksLeft() ? Direction.RIGHT : Direction.LEFT; + } + + protected final int dirMultiplier() { + return looksLeft() ? 0 : 1; } - public boolean isDead() { + public final boolean isDead() { return dead; } - public int getAnim() { + public final int getAnim() { return anim; } /** - * Set's mob's dead variable to true and nothing else. It doesn't delete the mob. + * Set's mob's dead variable to true and nothing else. It doesn't delete the */ - public void kill() { + public final void kill() { dead = true; } - /** - * - * @return A {@link Rectangle} with mob's coordinates and size - */ - public Rectangle getRect() { - return new Rectangle(pos.x, pos.y, getWidth(), getHeight()); + public final void move() { + x += move.x; + y += move.y; } - public Vector2 getPos() { - return pos; + public final Vector2 getMove() { + return move; } - public Vector2 getMov() { - return mov; + public final boolean canJump() { + return canJump; } - public float getX() { - return pos.x; + public final void setCanJump(boolean canJump) { + this.canJump = canJump; } - public float getY() { - return pos.y; + public final boolean isFlyMode() { + return flyMode; } - public boolean canJump() { - return canJump; + public final void setFlyMode(boolean flyMode) { + this.flyMode = flyMode; } - public void setCanJump(boolean canJump) { - this.canJump = canJump; + public final Type getType() { + return type; } - public boolean isFlyMode() { - return flyMode; + public void checkWorldBounds() { + if (x + width / 2 < 0) { + x += GP.world.getWidthPx(); + } + if (x + width / 2 > GP.world.getWidthPx()) { + x -= GP.world.getWidthPx(); + } } - public void setFlyMode(boolean flyMode) { - this.flyMode = flyMode; + public enum Type { + MOB, + SAND, + GRAVEL + } + + public enum Direction { + LEFT, + RIGHT } public abstract void draw(SpriteBatch spriteBatch, float x, float y); @@ -174,11 +177,4 @@ public abstract class Mob implements Serializable { public abstract void ai(); public abstract void changeDir(); - - /** - * - * @return 0 - if regular mob.
- * 10 - if instance of {@link FallingSand}
11 - if instance of {@link FallingGravel} - */ - public abstract int getType(); //0 - mob, 10 - sand, 11 - gravel } diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/Pig.java b/core/src/ru/deadsoftware/cavedroid/game/mobs/Pig.java index ecc9397..e37ab3e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/mobs/Pig.java +++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/Pig.java @@ -5,62 +5,57 @@ import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Vector2; import ru.deadsoftware.cavedroid.misc.Assets; -import static ru.deadsoftware.cavedroid.GameScreen.GP; import static ru.deadsoftware.cavedroid.misc.Assets.pigSprite; public class Pig extends Mob { public Pig(float x, float y) { - super(x, y, 25, 18, Mob.randomDir()); - mov = new Vector2(looksLeft() ? -1 : 1, 0); + super(x, y, 25, 18, randomDir(), Type.MOB); + move = new Vector2(looksLeft() ? -1 : 1, 0); } @Override public void changeDir() { switchDir(); - mov.x = -1 + 2 * getDirection(); + move.x = -1 + 2 * dirMultiplier(); } @Override public void ai() { - if (MathUtils.randomBoolean(.0025f)) changeDir(); - else if (MathUtils.randomBoolean(.0025f)) { - if (mov.x != 0f) mov.x = 0; - else mov.x = -1 + 2 * getDirection(); + if (MathUtils.randomBoolean(.0025f)) { + if (move.x != 0f) { + move.x = 0; + } else { + changeDir(); + } } - if (mov.x != 0f) anim += animDelta; - else anim = 0; + + if (move.x != 0f) { + anim += animDelta; + } else { + anim = 0; + } + if (anim >= 60 || anim <= -60) { animDelta = -animDelta; } } - @Override - public int getType() { - return 0; - } - @Override public void draw(SpriteBatch spriteBatch, float x, float y) { - if (x + getWidth() - GP.world.getWidthPx() >= 0 && x - GP.world.getWidthPx() <= getWidth()) { - x -= GP.world.getWidthPx(); - } else if (x + getWidth() + GP.world.getWidthPx() >= 0 && x + GP.world.getWidthPx() <= getWidth()) { - x += GP.world.getWidthPx(); - } - pigSprite[0][1].setRotation(getAnim()); pigSprite[1][1].setRotation(-getAnim()); //back legs - pigSprite[1][1].setPosition(x - 4 + (9 - getDirection() * 9), y + 6); + pigSprite[1][1].setPosition(x - 4 + (9 - dirMultiplier() * 9), y + 6); pigSprite[1][1].draw(spriteBatch); - pigSprite[1][1].setPosition(x + 17 - (9 * getDirection()), y + 6); + pigSprite[1][1].setPosition(x + 17 - (9 * dirMultiplier()), y + 6); pigSprite[1][1].draw(spriteBatch); //front legs - pigSprite[0][1].setPosition(x - 4 + (9 - getDirection() * 9), y + 6); + pigSprite[0][1].setPosition(x - 4 + (9 - dirMultiplier() * 9), y + 6); pigSprite[0][1].draw(spriteBatch); - pigSprite[0][1].setPosition(x + 17 - (9 * getDirection()), y + 6); + pigSprite[0][1].setPosition(x + 17 - (9 * dirMultiplier()), y + 6); pigSprite[0][1].draw(spriteBatch); //head & body - spriteBatch.draw(Assets.pigSprite[getDirection()][0], x, y); + spriteBatch.draw(Assets.pigSprite[dirMultiplier()][0], x, y); } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java b/core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java index df4e0c9..e687a02 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java +++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java @@ -1,16 +1,12 @@ package ru.deadsoftware.cavedroid.game.mobs; import com.badlogic.gdx.graphics.g2d.SpriteBatch; -import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; -import ru.deadsoftware.cavedroid.game.mobs.Mob; import ru.deadsoftware.cavedroid.misc.Assets; -import java.io.Serializable; - import static ru.deadsoftware.cavedroid.GameScreen.GP; -public class Player extends Mob implements Serializable { +public class Player extends Mob { public final int[] inventory; public int slot; @@ -18,15 +14,17 @@ public class Player extends Mob implements Serializable { public boolean swim; public Player(int gameMode) { - super(0, 0, 4, 30, 1); + super(0, 0, 4, 30, randomDir(), Type.MOB); this.gameMode = gameMode; inventory = new int[9]; swim = false; } public void respawn() { - pos.set(getSpawnPoint()); - mov.setZero(); + Vector2 pos = getSpawnPoint(); + this.x = pos.x; + this.y = pos.y; + move.setZero(); } private Vector2 getSpawnPoint() { @@ -37,13 +35,17 @@ public class Player extends Mob implements Serializable { GP.world.setForeMap(x, y, 1); break; } - if (GP.world.hasForeAt(x, y) && GP.world.getForeMapBlock(x, y).hasCollision()) break; + if (GP.world.hasForeAt(x, y) && GP.world.getForeMapBlock(x, y).hasCollision()) { + break; + } } - return new Vector2(x * 16 + 8 - getWidth() / 2, (float) y * 16 - getHeight()); + return new Vector2(x * 16 + 8 - getWidth() / 2, (float) y * 16 - getHeight()); } - public void setDir(int dir) { - if (dir != getDirection()) switchDir(); + public void setDir(Direction dir) { + if (dir != getDirection()) { + switchDir(); + } } @Override @@ -56,7 +58,7 @@ public class Player extends Mob implements Serializable { @Override public void draw(SpriteBatch spriteBatch, float x, float y) { - if (mov.x != 0 || Assets.playerSprite[0][2].getRotation() != 0) { + if (move.x != 0 || Assets.playerSprite[0][2].getRotation() != 0) { Assets.playerSprite[0][2].rotate(animDelta); Assets.playerSprite[1][2].rotate(-animDelta); Assets.playerSprite[0][3].rotate(-animDelta); @@ -80,22 +82,12 @@ public class Player extends Mob implements Serializable { Assets.playerSprite[0][3].setPosition(x - 6, y + 10); Assets.playerSprite[0][3].draw(spriteBatch); //head - spriteBatch.draw(Assets.playerSprite[getDirection()][0], x - 2, y - 2); + spriteBatch.draw(Assets.playerSprite[dirMultiplier()][0], x - 2, y - 2); //body - spriteBatch.draw(Assets.playerSprite[getDirection()][1], x - 2, y + 8); + spriteBatch.draw(Assets.playerSprite[dirMultiplier()][1], x - 2, y + 8); //front hand Assets.playerSprite[0][2].setPosition(x - 6, y); Assets.playerSprite[0][2].draw(spriteBatch); } - @Override - public int getType() { - return 0; - } - - @Override - public Rectangle getRect() { - return new Rectangle(pos.x, pos.y, getWidth(), getHeight()); - } - } diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/Drop.java b/core/src/ru/deadsoftware/cavedroid/game/objects/Drop.java index 44822b1..e523c4e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/objects/Drop.java +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/Drop.java @@ -1,6 +1,7 @@ package ru.deadsoftware.cavedroid.game.objects; import com.badlogic.gdx.math.Intersector; +import com.badlogic.gdx.math.MathUtils; import com.badlogic.gdx.math.Rectangle; import com.badlogic.gdx.math.Vector2; import ru.deadsoftware.cavedroid.game.mobs.Player; @@ -9,37 +10,38 @@ import java.io.Serializable; import static ru.deadsoftware.cavedroid.GameScreen.GP; -public class Drop implements Serializable { +public class Drop extends Rectangle implements Serializable { private final int id; - public boolean pickedUp = false; - public final Vector2 move; - public final Vector2 pos; + private final Vector2 move; + private boolean pickedUp = false; public Drop(float x, float y, int id) { + super(x, y, 8, 8); this.id = id; - pos = new Vector2(x, y); - move = new Vector2(0, -1); + this.move = new Vector2(0, -1); + } + + public Vector2 getMove() { + return move; } public int closeToPlayer() { boolean[] c = new boolean[3]; c[0] = Intersector.overlaps(new Rectangle(GP.player.getX() - 16, - GP.player.getY() - 16, GP.player.getWidth() + 32, GP.player.getHeight() + 32), - getRect()); + GP.player.getY() - 16, GP.player.getWidth() + 32, GP.player.getHeight() + 32), this); c[1] = Intersector.overlaps(new Rectangle((GP.player.getX() + GP.world.getWidthPx()) - 16, - GP.player.getY() - 16, GP.player.getWidth() + 32, GP.player.getHeight() + 32), - getRect()); + GP.player.getY() - 16, GP.player.getWidth() + 32, GP.player.getHeight() + 32), this); c[2] = Intersector.overlaps(new Rectangle((GP.player.getX() - GP.world.getWidthPx()) - 16, - GP.player.getY() - 16, GP.player.getWidth() + 32, GP.player.getHeight() + 32), - getRect()); + GP.player.getY() - 16, GP.player.getWidth() + 32, GP.player.getHeight() + 32), this); for (int i = 0; i < 3; i++) { if (c[i]) { return i + 1; } } + return 0; } @@ -48,6 +50,7 @@ public class Drop implements Serializable { if (ctp > 0) { float px = GP.player.getX(); float py = GP.player.getY(); + switch (ctp) { case 2: px += GP.world.getWidthPx(); @@ -56,16 +59,18 @@ public class Drop implements Serializable { px -= GP.world.getWidthPx(); break; } + float dx = 0, dy = 0; - if (px + GP.player.getWidth() < pos.x + 4) { + + if (px + GP.player.getWidth() < x + 4) { dx = -.5f; - } else if (px > pos.x + 4) { + } else if (px > x + 4) { dx = .5f; } - if (py + GP.player.getHeight() < pos.y + 4) { + if (py + GP.player.getHeight() < y + 4) { dy = -.5f; - } else if (py > pos.y + 4) { + } else if (py > y + 4) { dy = .5f; } @@ -95,12 +100,30 @@ public class Drop implements Serializable { } } + private void checkWorldBounds() { + if (x + 8 > GP.world.getWidthPx()) { + x -= GP.world.getWidthPx(); + } else if (x < 0) { + x += GP.world.getWidthPx(); + } + } + + public void move() { + x += move.x; + y += move.y; + checkWorldBounds(); + y = MathUtils.round(y); + } + public int getId() { return id; } - public Rectangle getRect() { - return new Rectangle(pos.x, pos.y, 8, 8); + public boolean isPickedUp() { + return pickedUp; } + public void setPickedUp(boolean pickedUp) { + this.pickedUp = pickedUp; + } } -- 2.29.2