Create basic movement collision detector

This commit is contained in:
2021-02-01 10:55:09 +01:00
parent a141354439
commit 71a1e47d24
6 changed files with 105 additions and 4 deletions

View File

@@ -1,10 +1,13 @@
package com.bartlomiejpluta.base.core.world.map; package com.bartlomiejpluta.base.core.world.map;
import com.bartlomiejpluta.base.core.world.movement.Direction;
import com.bartlomiejpluta.base.core.world.movement.Movement;
import com.bartlomiejpluta.base.core.world.tileset.model.Tile; import com.bartlomiejpluta.base.core.world.tileset.model.Tile;
import com.bartlomiejpluta.base.core.world.tileset.model.TileSet; import com.bartlomiejpluta.base.core.world.tileset.model.TileSet;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.joml.Vector2f; import org.joml.Vector2f;
import org.joml.Vector2i;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
@@ -16,6 +19,8 @@ public class GameMap {
private final Tile[][] map; private final Tile[][] map;
private final float scale; private final float scale;
private final PassageAbility[] passageMap;
@Getter @Getter
private final Vector2f stepSize; private final Vector2f stepSize;
@@ -33,6 +38,8 @@ public class GameMap {
this.stepSize = new Vector2f(this.scale * this.tileSet.getTileWidth(), this.scale * this.tileSet.getTileHeight()); this.stepSize = new Vector2f(this.scale * this.tileSet.getTileWidth(), this.scale * this.tileSet.getTileHeight());
map = new Tile[LAYERS][rows * cols]; map = new Tile[LAYERS][rows * cols];
passageMap = new PassageAbility[rows * cols];
Arrays.fill(passageMap, 0, rows * cols, PassageAbility.ALLOW);
} }
public void setTile(int layer, int row, int col, Tile tile) { public void setTile(int layer, int row, int col, Tile tile) {
@@ -49,6 +56,43 @@ public class GameMap {
return map[layer]; return map[layer];
} }
public void setPassageAbility(int row, int col, PassageAbility passageAbility) {
passageMap[row * cols + col] = passageAbility;
}
private PassageAbility getPassageAbility(Vector2i coordinates) {
return passageMap[coordinates.y * cols + coordinates.x];
}
private PassageAbility getPassageAbility(int row, int col) {
return passageMap[row * cols + col];
}
public boolean isMovementPossible(Movement movement) {
var source = movement.getSourceCoordinate();
var target = movement.getTargetCoordinate();
var direction = movement.getDirection();
var isTargetReachable = switch(getPassageAbility(target)) {
case UP_ONLY -> direction != Direction.DOWN;
case DOWN_ONLY -> direction != Direction.UP;
case LEFT_ONLY -> direction != Direction.RIGHT;
case RIGHT_ONLY -> direction != Direction.LEFT;
case BLOCK -> false;
case ALLOW -> true;
};
var canMoveFromCurrentTile = switch(getPassageAbility(source)) {
case UP_ONLY -> direction == Direction.UP;
case DOWN_ONLY -> direction == Direction.DOWN;
case LEFT_ONLY -> direction == Direction.LEFT;
case RIGHT_ONLY -> direction == Direction.RIGHT;
default -> true;
};
return isTargetReachable && canMoveFromCurrentTile;
}
public void cleanUp() { public void cleanUp() {
Arrays.stream(map).flatMap(Arrays::stream).filter(Objects::nonNull).forEach(Tile::cleanUp); Arrays.stream(map).flatMap(Arrays::stream).filter(Objects::nonNull).forEach(Tile::cleanUp);
} }

View File

@@ -0,0 +1,10 @@
package com.bartlomiejpluta.base.core.world.map;
public enum PassageAbility {
BLOCK,
ALLOW,
UP_ONLY,
DOWN_ONLY,
LEFT_ONLY,
RIGHT_ONLY
}

View File

@@ -45,7 +45,11 @@ public abstract class MovableObject extends AnimationableObject implements Updat
setCoordinates(new Vector2i((int) (position.x / coordinateStepSize.x), (int) (position.y / coordinateStepSize.y))); setCoordinates(new Vector2i((int) (position.x / coordinateStepSize.x), (int) (position.y / coordinateStepSize.y)));
} }
public boolean move(Direction direction) { public Movement prepareMovement(Direction direction) {
return new Movement(this, direction);
}
protected boolean move(Direction direction) {
if (this.movementVector != null) { if (this.movementVector != null) {
return false; return false;
} }

View File

@@ -0,0 +1,43 @@
package com.bartlomiejpluta.base.core.world.movement;
import lombok.AccessLevel;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.joml.Vector2i;
@Data
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
public class Movement {
private final MovableObject object;
private final Direction direction;
public boolean perform() {
return object.move(direction);
}
public Vector2i getSourceCoordinate() {
return new Vector2i(object.getCoordinates());
}
public Vector2i getTargetCoordinate() {
return direction.asIntVector().add(object.getCoordinates());
}
}
//@Data
//public class Movement {
// private final MovableObject object;
// private final Direction direction;
// private final Vector2i source;
// private final Vector2i target;
//
// Movement(MovableObject object, Direction direction) {
// this.object = object;
// this.direction = direction;
// this.source = new Vector2i(object.getCoordinates());
// this.target = direction.asIntVector().add(source);
// }
//
// public boolean perform() {
// return object.move(direction);
// }
//}

View File

@@ -30,10 +30,10 @@ public class TileSet {
this.mesh = mesh; this.mesh = mesh;
} }
public Tile getTile(int m, int n) { public Tile getTile(int row, int column) {
var material = Material.textured(texture); var material = Material.textured(texture);
material.setSpriteSize(columnStep, rowStep); material.setSpriteSize(columnStep, rowStep);
material.setSpritePosition(n * columnStep, m * rowStep); material.setSpritePosition(column * columnStep, row * rowStep);
return new Tile(mesh, material, tileWidth, tileHeight); return new Tile(mesh, material, tileWidth, tileHeight);
} }
} }

View File

@@ -49,7 +49,7 @@ public class Entity extends MovableObject {
} }
@Override @Override
public boolean move(Direction direction) { protected boolean move(Direction direction) {
if(super.move(direction)) { if(super.move(direction)) {
faceDirection = direction; faceDirection = direction;
return true; return true;