Extract some responsibility from MovableObject to Entity

This commit is contained in:
2021-01-31 20:02:27 +01:00
parent 3c7143ad20
commit a04538874b
5 changed files with 161 additions and 122 deletions

View File

@@ -1,4 +1,4 @@
package com.bartlomiejpluta.base.game.logic;
package com.bartlomiejpluta.base.core.logic;
public interface Updatable {
void update(float dt);

View File

@@ -1,4 +1,4 @@
package com.bartlomiejpluta.base.game.world.movement;
package com.bartlomiejpluta.base.core.world.movement;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;

View File

@@ -0,0 +1,76 @@
package com.bartlomiejpluta.base.core.world.movement;
import com.bartlomiejpluta.base.core.gl.object.material.Material;
import com.bartlomiejpluta.base.core.gl.object.mesh.Mesh;
import com.bartlomiejpluta.base.core.logic.Updatable;
import com.bartlomiejpluta.base.core.world.animation.AnimationableObject;
import lombok.Getter;
import org.joml.Vector2f;
import org.joml.Vector2i;
public abstract class MovableObject extends AnimationableObject implements Updatable {
private final Vector2f coordinateStepSize;
private int moveTime = 0;
private Vector2f movementVector;
@Getter
private final Vector2i coordinates = new Vector2i(0, 0);
protected int framesToCrossOneTile = 1;
public boolean isMoving() {
return movementVector != null;
}
@Override
public void update(float dt) {
if(movementVector != null) {
if(moveTime > 0) {
--moveTime;
movePosition(movementVector);
} else {
adjustCoordinates();
setDefaultAnimationFrame();
movementVector = null;
}
}
}
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)));
}
public boolean move(Direction direction) {
if (this.movementVector != null) {
return false;
}
var speed = new Vector2f(coordinateStepSize).div(framesToCrossOneTile);
movementVector = direction.asFloatVector().mul(speed);
moveTime = framesToCrossOneTile;
return true;
}
public MovableObject setCoordinates(int x, int y) {
coordinates.x = x;
coordinates.y = y;
setPosition((x + 0.5f) * coordinateStepSize.x, (y + 0.5f) * coordinateStepSize.y);
return this;
}
public MovableObject setCoordinates(Vector2i coordinates) {
return setCoordinates(coordinates.x, coordinates.y);
}
public MovableObject(Mesh mesh, Material material, Vector2f coordinateStepSize) {
super(mesh, material);
this.coordinateStepSize = coordinateStepSize;
setCoordinates(0, 0);
}
}

View File

@@ -0,0 +1,83 @@
package com.bartlomiejpluta.base.game.world.entity;
import com.bartlomiejpluta.base.core.gl.object.material.Material;
import com.bartlomiejpluta.base.core.gl.object.mesh.Mesh;
import com.bartlomiejpluta.base.core.world.movement.Direction;
import com.bartlomiejpluta.base.core.world.movement.MovableObject;
import lombok.Setter;
import org.joml.Vector2f;
import org.joml.Vector2i;
import java.util.Map;
public class Entity extends MovableObject {
private static final Vector2i SPRITE_DIMENSION = new Vector2i(4, 4);
private static final int DEFAULT_SPRITE = 0;
private static final Map<Direction, Integer> SPRITE_ROWS = Map.of(
Direction.DOWN, 0,
Direction.LEFT, 1,
Direction.RIGHT, 2,
Direction.UP, 3
);
@Setter
private int animationSpeed = 100;
@Setter
private Direction faceDirection;
@Override
public int getAnimationSpeed() {
return 100;
}
@Override
public Vector2i getSpriteSheetDimensions() {
return SPRITE_DIMENSION;
}
@Override
public boolean shouldAnimate() {
return isMoving();
}
@Override
public Vector2f[] getSpriteAnimationFramesPositions() {
var row = SPRITE_ROWS.get(faceDirection);
return new Vector2f[]{new Vector2f(0, row), new Vector2f(1, row), new Vector2f(2, row), new Vector2f(3, row)};
}
@Override
protected void setDefaultAnimationFrame() {
setAnimationFrame(new Vector2f(DEFAULT_SPRITE, SPRITE_ROWS.get(faceDirection)));
}
@Override
public boolean move(Direction direction) {
if(super.move(direction)) {
faceDirection = direction;
return true;
}
return false;
}
public void setMovementSlowness(int slowness) {
framesToCrossOneTile = slowness;
}
public int getMovementSlowness() {
return framesToCrossOneTile;
}
public Entity(Material material, Vector2f coordinateStepSize) {
super(buildMesh(material), material, coordinateStepSize);
}
private static Mesh buildMesh(Material material) {
var texture = material.getTexture();
var spriteWidth = texture.getWidth() / (float) SPRITE_DIMENSION.x;
var spriteHeight = texture.getHeight() / (float) SPRITE_DIMENSION.y;
return Mesh.quad(spriteWidth, spriteHeight, spriteWidth / 2, spriteHeight);
}
}

View File

@@ -1,120 +0,0 @@
package com.bartlomiejpluta.base.game.world.movement;
import com.bartlomiejpluta.base.core.gl.object.material.Material;
import com.bartlomiejpluta.base.core.gl.object.mesh.Mesh;
import com.bartlomiejpluta.base.core.world.animation.AnimationableObject;
import com.bartlomiejpluta.base.game.logic.Updatable;
import lombok.Getter;
import lombok.Setter;
import org.joml.Vector2f;
import org.joml.Vector2i;
import java.util.Map;
public abstract class MovableObject extends AnimationableObject implements Updatable {
private static final Vector2i SPRITE_DIMENSION = new Vector2i(4, 4);
private static final int DEFAULT_SPRITE = 0;
private static final Map<Direction, Integer> SPRITE_ROWS = Map.of(
Direction.DOWN, 0,
Direction.LEFT, 1,
Direction.RIGHT, 2,
Direction.UP, 3
);
private final Vector2f coordinateStepSize;
private int moveTime = 0;
private Vector2f movementVector;
@Getter
private final Vector2i coordinates = new Vector2i(0, 0);
@Getter
@Setter
private Direction faceDirection = Direction.DOWN;
@Getter
@Setter
private int framesToCrossOneTile = 1;
@Setter
private int animationSpeed = 100;
@Override
public int getAnimationSpeed() {
return animationSpeed;
}
@Override
public boolean shouldAnimate() {
return movementVector != null;
}
@Override
public void update(float dt) {
if(movementVector != null) {
if(moveTime > 0) {
--moveTime;
movePosition(movementVector);
} else {
adjustCoordinates();
movementVector = null;
setAnimationFrame(new Vector2f(DEFAULT_SPRITE, SPRITE_ROWS.get(faceDirection)));
}
}
}
private void adjustCoordinates() {
var position = new Vector2f(getPosition());
setCoordinates(new Vector2i((int) (position.x / coordinateStepSize.x), (int) (position.y / coordinateStepSize.y)));
}
public void move(Direction direction) {
if (this.movementVector != null) {
return;
}
setFaceDirection(direction);
var speed = new Vector2f(coordinateStepSize).div(framesToCrossOneTile);
movementVector = direction.asFloatVector().mul(speed);
moveTime = framesToCrossOneTile;
}
public MovableObject setCoordinates(int x, int y) {
coordinates.x = x;
coordinates.y = y;
setPosition((x + 0.5f) * coordinateStepSize.x, (y + 0.5f) * coordinateStepSize.y);
return this;
}
public MovableObject setCoordinates(Vector2i coordinates) {
return setCoordinates(coordinates.x, coordinates.y);
}
@Override
public Vector2i getSpriteSheetDimensions() {
return SPRITE_DIMENSION;
}
@Override
public Vector2f[] getSpriteAnimationFramesPositions() {
var row = SPRITE_ROWS.get(faceDirection);
return new Vector2f[]{new Vector2f(0, row), new Vector2f(1, row), new Vector2f(2, row), new Vector2f(3, row)};
}
public MovableObject(Material material, Vector2f coordinateStepSize, float scale) {
super(buildMesh(material), material);
this.coordinateStepSize = coordinateStepSize;
this.setScale(scale);
setCoordinates(0, 0);
}
private static Mesh buildMesh(Material material) {
var texture = material.getTexture();
var spriteWidth = texture.getWidth() / (float) SPRITE_DIMENSION.x;
var spriteHeight = texture.getHeight() / (float) SPRITE_DIMENSION.y;
return Mesh.quad(spriteWidth, spriteHeight, spriteWidth / 2, spriteHeight);
}
}