diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/Entity.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/Entity.java index 7fc2ec4e..e2de2f2f 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/Entity.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/Entity.java @@ -17,6 +17,8 @@ public interface Entity extends Placeable, Renderable, Updatable { Movement prepareMovement(Direction direction); + Movement getMovement(); + Direction getFaceDirection(); void setFaceDirection(Direction direction); diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/EntityDelegate.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/EntityDelegate.java index 23c88d34..883b33a8 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/EntityDelegate.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/EntityDelegate.java @@ -41,6 +41,11 @@ public abstract class EntityDelegate implements Entity { return entity.prepareMovement(direction); } + @Override + public Movement getMovement() { + return entity.getMovement(); + } + @Override public Direction getFaceDirection() { return entity.getFaceDirection(); diff --git a/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/Movement.java b/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/Movement.java index e6ef9434..ef4abf28 100644 --- a/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/Movement.java +++ b/api/src/main/java/com/bartlomiejpluta/base/api/game/entity/Movement.java @@ -1,11 +1,10 @@ package com.bartlomiejpluta.base.api.game.entity; -import com.bartlomiejpluta.base.api.game.map.layer.object.ObjectLayer; import org.joml.Vector2i; public interface Movement { - boolean perform(ObjectLayer layer); + boolean perform(); Movement another(); diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/entity/model/DefaultEntity.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/entity/model/DefaultEntity.java index 22ae5193..c75886b5 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/entity/model/DefaultEntity.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/entity/model/DefaultEntity.java @@ -2,6 +2,7 @@ package com.bartlomiejpluta.base.engine.world.entity.model; import com.bartlomiejpluta.base.api.game.entity.Direction; import com.bartlomiejpluta.base.api.game.entity.Entity; +import com.bartlomiejpluta.base.api.game.entity.Movement; import com.bartlomiejpluta.base.api.game.map.layer.object.ObjectLayer; import com.bartlomiejpluta.base.engine.core.gl.object.material.Material; import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh; @@ -59,9 +60,9 @@ public class DefaultEntity extends MovableSprite implements Entity { } @Override - protected boolean move(Direction direction) { - if (super.move(direction)) { - faceDirection = direction; + protected boolean move(Movement movement) { + if (super.move(movement)) { + faceDirection = movement.getDirection(); return true; } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/object/DefaultObjectLayer.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/object/DefaultObjectLayer.java index 968a91dc..b66fa8b7 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/object/DefaultObjectLayer.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/map/layer/object/DefaultObjectLayer.java @@ -110,8 +110,18 @@ public class DefaultObjectLayer implements ObjectLayer { }; for (var entity : entities) { - if (entity.isBlocking() && entity.getCoordinates().equals(target)) { - return false; + if (entity.isBlocking()) { + + // The tile is occupied by other entity + if (entity.getCoordinates().equals(target)) { + return false; + } + + // The tile is empty, however another entity is moving on it + var otherMovement = entity.getMovement(); + if (otherMovement != null && otherMovement.getTo().equals(target)) { + return false; + } } } @@ -126,7 +136,12 @@ public class DefaultObjectLayer implements ObjectLayer { @Override public void update(float dt) { for (var iterator = movements.iterator(); iterator.hasNext(); ) { - iterator.next().perform(this); + var movement = iterator.next(); + + if (isMovementPossible(movement)) { + movement.perform(); + } + iterator.remove(); } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/movement/DefaultMovement.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/movement/DefaultMovement.java index 8b90b7fd..74a5495b 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/movement/DefaultMovement.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/movement/DefaultMovement.java @@ -2,26 +2,28 @@ package com.bartlomiejpluta.base.engine.world.movement; import com.bartlomiejpluta.base.api.game.entity.Direction; import com.bartlomiejpluta.base.api.game.entity.Movement; -import com.bartlomiejpluta.base.api.game.map.layer.object.ObjectLayer; -import lombok.AccessLevel; import lombok.Data; -import lombok.RequiredArgsConstructor; import org.joml.Vector2i; @Data -@RequiredArgsConstructor(access = AccessLevel.PACKAGE) public class DefaultMovement implements Movement { private final MovableSprite object; private final Direction direction; + private final Vector2i from; + private final Vector2i to; private boolean performed = false; - @Override - public boolean perform(ObjectLayer layer) { - if (!layer.isMovementPossible(this)) { - return false; - } + DefaultMovement(MovableSprite object, Direction direction) { + this.object = object; + this.direction = direction; - return object.move(direction); + this.from = object.getCoordinates(); + this.to = direction.asVector().add(object.getCoordinates()); + } + + @Override + public boolean perform() { + return object.move(this); } @Override @@ -31,11 +33,11 @@ public class DefaultMovement implements Movement { @Override public Vector2i getFrom() { - return object.getCoordinates(); + return from; } @Override public Vector2i getTo() { - return direction.asVector().add(object.getCoordinates()); + return to; } } \ No newline at end of file diff --git a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/movement/MovableSprite.java b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/movement/MovableSprite.java index 80fd7452..aeb8ef44 100644 --- a/engine/src/main/java/com/bartlomiejpluta/base/engine/world/movement/MovableSprite.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/engine/world/movement/MovableSprite.java @@ -24,15 +24,18 @@ public abstract class MovableSprite extends AnimatedSprite implements Updatable @Getter private final Vector2i coordinates = new Vector2i(0, 0); + @Getter + private Movement movement; + protected int framesToCrossOneTile = 1; public boolean isMoving() { - return movementVector != null; + return movement != null; } @Override public void update(float dt) { - if (movementVector != null) { + if (movement != null) { if (moveTime > 0) { --moveTime; movePosition(movementVector); @@ -40,6 +43,7 @@ public abstract class MovableSprite extends AnimatedSprite implements Updatable adjustCoordinates(); setDefaultAnimationFrame(); movementVector = null; + movement = null; } } } @@ -47,21 +51,25 @@ public abstract class MovableSprite extends AnimatedSprite implements Updatable protected abstract void setDefaultAnimationFrame(); private void adjustCoordinates() { - var position = new Vector2f(getPosition()); - setCoordinates(new Vector2i((int) (position.x / coordinateStepSize.x), (int) (position.y / coordinateStepSize.y))); + setCoordinates(movement.getTo()); } public Movement prepareMovement(Direction direction) { return new DefaultMovement(this, direction); } - protected boolean move(Direction direction) { - if (this.movementVector != null) { + protected boolean move(Movement movement) { + if (this.movement != null) { return false; } + if (!movement.getFrom().equals(coordinates)) { + return false; + } + + this.movement = movement; var speed = new Vector2f(coordinateStepSize).div(framesToCrossOneTile); - movementVector = new Vector2f(direction.x, direction.y).mul(speed); + movementVector = new Vector2f(movement.getDirection().x, movement.getDirection().y).mul(speed); moveTime = framesToCrossOneTile; return true;