diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/world/animation/Animator.java b/engine/src/main/java/com/bartlomiejpluta/base/core/world/animation/Animator.java index 4a273ce5..7b9dcc3d 100755 --- a/engine/src/main/java/com/bartlomiejpluta/base/core/world/animation/Animator.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/world/animation/Animator.java @@ -1,5 +1,5 @@ package com.bartlomiejpluta.base.core.world.animation; public interface Animator { - void animate(Iterable objects); + void animate(AnimationableObject objects); } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/world/animation/DefaultAnimator.java b/engine/src/main/java/com/bartlomiejpluta/base/core/world/animation/DefaultAnimator.java index b4e2f9eb..bde76fb9 100755 --- a/engine/src/main/java/com/bartlomiejpluta/base/core/world/animation/DefaultAnimator.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/world/animation/DefaultAnimator.java @@ -6,13 +6,7 @@ import org.springframework.stereotype.Component; public class DefaultAnimator implements Animator { @Override - public void animate(Iterable objects) { - for (var object : objects) { - animate(object); - } - } - - private void animate(AnimationableObject object) { + public void animate(AnimationableObject object) { if(object.shouldAnimate()) { var positions = object.getSpriteAnimationFramesPositions(); var delay = object.getAnimationSpeed(); diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/GameMap.java b/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/GameMap.java index 470abc81..c15e7122 100755 --- a/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/GameMap.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/GameMap.java @@ -1,106 +1,119 @@ package com.bartlomiejpluta.base.core.world.map; -import com.bartlomiejpluta.base.core.world.movement.Direction; +import com.bartlomiejpluta.base.core.gl.render.Renderable; +import com.bartlomiejpluta.base.core.gl.shader.constant.UniformName; +import com.bartlomiejpluta.base.core.gl.shader.manager.ShaderManager; +import com.bartlomiejpluta.base.core.logic.Updatable; +import com.bartlomiejpluta.base.core.ui.Window; +import com.bartlomiejpluta.base.core.world.animation.Animator; +import com.bartlomiejpluta.base.core.world.camera.Camera; +import com.bartlomiejpluta.base.core.world.movement.MovableObject; 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.TileSet; import lombok.Getter; import org.joml.Vector2f; -import org.joml.Vector2i; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; -public class GameMap { - private static final int LAYERS = 4; +public class GameMap implements Renderable, Updatable { + private final Animator animator; + + private final Camera camera; private final TileSet tileSet; - private final Tile[][] map; + private final List layers = new ArrayList<>(); + private final float scale; - private final PassageAbility[] passageMap; - - @Getter - private final Vector2f stepSize; - @Getter private final int rows; @Getter - private final int cols; + private final int columns; - private GameMap(TileSet tileSet, int rows, int cols, float scale) { + @Getter + private final Vector2f stepSize; + + public GameMap(Animator animator, Camera camera, TileSet tileSet, int rows, int columns, float scale) { + this.animator = animator; + this.camera = camera; this.tileSet = tileSet; - this.rows = rows; - this.cols = cols; this.scale = scale; + this.rows = rows; + this.columns = columns; this.stepSize = new Vector2f(this.scale * this.tileSet.getTileWidth(), this.scale * this.tileSet.getTileHeight()); + } - map = new Tile[LAYERS][rows * cols]; - passageMap = new PassageAbility[rows * cols]; - Arrays.fill(passageMap, 0, rows * cols, PassageAbility.ALLOW); + @Override + public void render(Window window, ShaderManager shaderManager) { + shaderManager.setUniform(UniformName.UNI_PROJECTION_MATRIX, camera.getProjectionMatrix(window)); + shaderManager.setUniform(UniformName.UNI_VIEW_MATRIX, camera.getViewMatrix()); - for(int i=0; i(), passageMap)); + + return this; } - public Tile[] getLayer(int layer) { - return map[layer]; + public GameMap createTileLayer() { + layers.add(new TileLayer(new Tile[rows][columns], stepSize, scale)); + + return this; } - public void setPassageAbility(int row, int col, PassageAbility passageAbility) { - passageMap[row * cols + col] = passageAbility; + public GameMap addObject(int layerIndex, MovableObject object) { + ((ObjectLayer) layers.get(layerIndex)).addObject(object); + + return this; } - private PassageAbility getPassageAbility(Vector2i coordinates) { - return passageMap[coordinates.y * cols + coordinates.x]; + public GameMap removeObject(int layerIndex, MovableObject object) { + ((ObjectLayer) layers.get(layerIndex)).removeObject(object); + + return this; } - private PassageAbility getPassageAbility(int row, int col) { - return passageMap[row * cols + col]; + public GameMap setPassageAbility(int layerIndex, int row, int column, PassageAbility passageAbility) { + ((ObjectLayer) layers.get(layerIndex)).setPassageAbility(row, column, passageAbility); + return this; } - public boolean isMovementPossible(Movement movement) { - var source = movement.getSourceCoordinate(); + public GameMap setTile(int layerIndex, int row, int column, Tile tile) { + ((TileLayer) layers.get(layerIndex)).setTile(row, column, tile); + + return this; + } + + public boolean isMovementPossible(int layerIndex, Movement movement) { var target = movement.getTargetCoordinate(); + + // Is trying to go beyond the map + if(target.x < 0 || target.y < 0 || target.x >= columns || target.y >= rows) { + return false; + } + + var source = movement.getSourceCoordinate(); 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 static GameMap empty(TileSet tileSet, int rows, int cols, float scale) { - return new GameMap(tileSet, rows, cols, scale); + return ((ObjectLayer) layers.get(layerIndex)).isMovementPossible(source, target, direction); } } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/Layer.java b/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/Layer.java new file mode 100755 index 00000000..cf011c5f --- /dev/null +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/Layer.java @@ -0,0 +1,8 @@ +package com.bartlomiejpluta.base.core.world.map; + +import com.bartlomiejpluta.base.core.gl.render.Renderable; +import com.bartlomiejpluta.base.core.logic.Updatable; + +public interface Layer extends Renderable, Updatable { + +} diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/ObjectLayer.java b/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/ObjectLayer.java new file mode 100755 index 00000000..c84770a4 --- /dev/null +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/ObjectLayer.java @@ -0,0 +1,73 @@ +package com.bartlomiejpluta.base.core.world.map; + +import com.bartlomiejpluta.base.core.gl.shader.constant.UniformName; +import com.bartlomiejpluta.base.core.gl.shader.manager.ShaderManager; +import com.bartlomiejpluta.base.core.ui.Window; +import com.bartlomiejpluta.base.core.world.animation.Animator; +import com.bartlomiejpluta.base.core.world.movement.Direction; +import com.bartlomiejpluta.base.core.world.movement.MovableObject; +import org.joml.Vector2i; + +import java.util.List; + +public class ObjectLayer implements Layer { + private final Animator animator; + private final List objects; + + private final PassageAbility[][] passageMap; + + public ObjectLayer(Animator animator, List objects, PassageAbility[][] passageMap) { + this.animator = animator; + this.objects = objects; + this.passageMap = passageMap; + } + + public void addObject(MovableObject object) { + objects.add(object); + } + + public void removeObject(MovableObject object) { + objects.remove(object); + } + + public void setPassageAbility(int row, int column, PassageAbility passageAbility) { + passageMap[row][column] = passageAbility; + } + + public boolean isMovementPossible(Vector2i source, Vector2i target, Direction direction) { + var isTargetReachable = switch (passageMap[target.y][target.x]) { + 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 (passageMap[source.y][source.x]) { + 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; + } + + @Override + public void render(Window window, ShaderManager shaderManager) { + for (var object : objects) { + shaderManager.setUniform(UniformName.UNI_MODEL_MATRIX, object.getModelMatrix()); + animator.animate(object); + object.render(window, shaderManager); + } + } + + @Override + public void update(float dt) { + for (var object : objects) { + object.update(dt); + } + } +} diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/TileLayer.java b/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/TileLayer.java new file mode 100755 index 00000000..1ee051c4 --- /dev/null +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/world/map/TileLayer.java @@ -0,0 +1,44 @@ +package com.bartlomiejpluta.base.core.world.map; + +import com.bartlomiejpluta.base.core.gl.shader.constant.UniformName; +import com.bartlomiejpluta.base.core.gl.shader.manager.ShaderManager; +import com.bartlomiejpluta.base.core.ui.Window; +import com.bartlomiejpluta.base.core.world.tileset.model.Tile; +import org.joml.Vector2f; + +public class TileLayer implements Layer { + private final Tile[][] layer; + private final Vector2f stepSize; + private final float scale; + + public TileLayer(Tile[][] layer, Vector2f stepSize, float scale) { + this.layer = layer; + this.stepSize = stepSize; + this.scale = scale; + } + + public void setTile(int row, int column, Tile tile) { + layer[row][column] = tile; + recalculateTileGeometry(tile, row, column); + } + + private void recalculateTileGeometry(Tile tile, int row, int column) { + tile.setScale(scale); + tile.setPosition(column * stepSize.x, row * stepSize.y); + } + + @Override + public void render(Window window, ShaderManager shaderManager) { + for(var row : layer) { + for(var tile : row) { + shaderManager.setUniform(UniformName.UNI_MODEL_MATRIX, tile.getModelMatrix()); + tile.render(window, shaderManager); + } + } + } + + @Override + public void update(float dt) { + + } +} diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/world/object/RenderableObject.java b/engine/src/main/java/com/bartlomiejpluta/base/core/world/object/RenderableObject.java index 48a86188..2c49cfcc 100755 --- a/engine/src/main/java/com/bartlomiejpluta/base/core/world/object/RenderableObject.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/world/object/RenderableObject.java @@ -3,6 +3,7 @@ package com.bartlomiejpluta.base.core.world.object; import com.bartlomiejpluta.base.core.gl.object.material.Material; import com.bartlomiejpluta.base.core.gl.object.mesh.Mesh; import com.bartlomiejpluta.base.core.gl.render.Renderable; +import com.bartlomiejpluta.base.core.gl.shader.constant.UniformName; import com.bartlomiejpluta.base.core.gl.shader.manager.ShaderManager; import com.bartlomiejpluta.base.core.ui.Window; import lombok.EqualsAndHashCode; @@ -23,7 +24,14 @@ public abstract class RenderableObject extends PositionableObject implements Ren @Override public void render(Window window, ShaderManager shaderManager) { - getMaterial().activateTextureIfExists(); + material.activateTextureIfExists(); + + shaderManager.setUniform(UniformName.UNI_OBJECT_COLOR, material.getColor()); + shaderManager.setUniform(UniformName.UNI_HAS_OBJECT_TEXTURE, material.hasTexture()); + shaderManager.setUniform(UniformName.UNI_TEXTURE_SAMPLER, 0); + shaderManager.setUniform(UniformName.UNI_SPRITE_SIZE, material.getSpriteSize()); + shaderManager.setUniform(UniformName.UNI_SPRITE_POSITION, material.getSpritePosition()); + mesh.render(window, shaderManager); } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/world/scene/Scene.java b/engine/src/main/java/com/bartlomiejpluta/base/core/world/scene/Scene.java deleted file mode 100755 index ab92b7cf..00000000 --- a/engine/src/main/java/com/bartlomiejpluta/base/core/world/scene/Scene.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.bartlomiejpluta.base.core.world.scene; - -import com.bartlomiejpluta.base.core.gl.render.Renderable; -import com.bartlomiejpluta.base.core.gl.shader.constant.UniformName; -import com.bartlomiejpluta.base.core.gl.shader.manager.ShaderManager; -import com.bartlomiejpluta.base.core.logic.Updatable; -import com.bartlomiejpluta.base.core.ui.Window; -import com.bartlomiejpluta.base.core.world.animation.AnimationableObject; -import com.bartlomiejpluta.base.core.world.animation.Animator; -import com.bartlomiejpluta.base.core.world.camera.Camera; -import com.bartlomiejpluta.base.core.world.map.GameMap; -import com.bartlomiejpluta.base.core.world.movement.MovableObject; -import com.bartlomiejpluta.base.core.world.object.RenderableObject; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; - -import java.util.ArrayList; -import java.util.List; - -@AllArgsConstructor -public class Scene implements Renderable, Updatable { - private final Animator animator; - private final Camera camera; - private final List objects = new ArrayList<>(); - - @Setter - @Getter - private GameMap map; - - public Scene addObject(MovableObject object) { - objects.add(object); - return this; - } - - public Scene removeObject(MovableObject object) { - objects.remove(object); - return this; - } - - @Override - public void render(Window window, ShaderManager shaderManager) { - shaderManager.setUniform(UniformName.UNI_PROJECTION_MATRIX, camera.getProjectionMatrix(window)); - shaderManager.setUniform(UniformName.UNI_VIEW_MATRIX, camera.getViewMatrix()); - - renderArray(map.getLayer(0), window, shaderManager); - renderArray(map.getLayer(1), window, shaderManager); - - // Player will be rendered here - renderList(objects, window, shaderManager); - animator.animate(objects); - - renderArray(map.getLayer(2), window, shaderManager); - renderArray(map.getLayer(3), window, shaderManager); - } - - @Override - public void update(float dt) { - for(var object : objects) { - object.update(dt); - } - } - - private void renderList(List objects, Window window, ShaderManager shaderManager) { - for (var object : objects) { - if (object != null) { - renderObject(object, window, shaderManager); - } - } - } - - private void renderArray(T[] objects, Window window, ShaderManager shaderManager) { - for (var object : objects) { - if (object != null) { - renderObject(object, window, shaderManager); - } - } - } - - private void renderObject(T object, Window window, ShaderManager shaderManager) { - shaderManager.setUniform(UniformName.UNI_MODEL_MATRIX, object.getModelMatrix()); - shaderManager.setUniform(UniformName.UNI_OBJECT_COLOR, object.getMaterial().getColor()); - shaderManager.setUniform(UniformName.UNI_HAS_OBJECT_TEXTURE, object.getMaterial().hasTexture()); - shaderManager.setUniform(UniformName.UNI_TEXTURE_SAMPLER, 0); - shaderManager.setUniform(UniformName.UNI_SPRITE_SIZE, object.getMaterial().getSpriteSize()); - shaderManager.setUniform(UniformName.UNI_SPRITE_POSITION, object.getMaterial().getSpritePosition()); - - object.render(window, shaderManager); - } -} diff --git a/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/manager/DefaultEntityManager.java b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/manager/DefaultEntityManager.java index 805c2b90..6cb560e1 100755 --- a/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/manager/DefaultEntityManager.java +++ b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/manager/DefaultEntityManager.java @@ -3,7 +3,7 @@ package com.bartlomiejpluta.base.game.world.entity.manager; import com.bartlomiejpluta.base.core.gl.object.material.Material; import com.bartlomiejpluta.base.core.gl.object.mesh.Mesh; import com.bartlomiejpluta.base.core.util.mesh.MeshManager; -import com.bartlomiejpluta.base.core.world.scene.Scene; +import com.bartlomiejpluta.base.core.world.map.GameMap; import com.bartlomiejpluta.base.game.world.entity.config.EntitySpriteConfiguration; import com.bartlomiejpluta.base.game.world.entity.model.Entity; import lombok.RequiredArgsConstructor; @@ -19,8 +19,8 @@ public class DefaultEntityManager implements EntityManager { private final EntitySpriteConfiguration configuration; @Override - public Entity createEntity(Material material, Scene scene) { - return new Entity(scene, buildMesh(material), material, scene.getMap().getStepSize(), configuration); + public Entity createEntity(Material material, GameMap map) { + return new Entity(buildMesh(material), material, map.getStepSize(), configuration); } private Mesh buildMesh(Material material) { diff --git a/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/manager/EntityManager.java b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/manager/EntityManager.java index 5f5f9d4d..f804867b 100755 --- a/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/manager/EntityManager.java +++ b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/manager/EntityManager.java @@ -2,10 +2,9 @@ package com.bartlomiejpluta.base.game.world.entity.manager; import com.bartlomiejpluta.base.core.gc.Cleanable; import com.bartlomiejpluta.base.core.gl.object.material.Material; -import com.bartlomiejpluta.base.core.world.scene.Scene; +import com.bartlomiejpluta.base.core.world.map.GameMap; import com.bartlomiejpluta.base.game.world.entity.model.Entity; -import org.joml.Vector2f; public interface EntityManager extends Cleanable { - Entity createEntity(Material material, Scene scene); + Entity createEntity(Material material, GameMap map); } diff --git a/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/model/Entity.java b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/model/Entity.java index 6c36df4e..9cdacafd 100755 --- a/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/model/Entity.java +++ b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/model/Entity.java @@ -4,7 +4,6 @@ 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 com.bartlomiejpluta.base.core.world.scene.Scene; import com.bartlomiejpluta.base.game.world.entity.config.EntitySpriteConfiguration; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -13,14 +12,10 @@ import org.joml.Vector2f; import java.util.Map; -@EqualsAndHashCode(exclude = "scene", callSuper = true) +@EqualsAndHashCode(callSuper = true) public class Entity extends MovableObject { private final Map spriteDirectionRows; private final int defaultSpriteColumn; - private final Scene scene; - - @Getter - private boolean onScene; @Setter private int animationSpeed = 100; @@ -75,26 +70,10 @@ public class Entity extends MovableObject { return framesToCrossOneTile; } - public void pushToScene() { - if(!onScene) { - scene.addObject(this); - onScene = true; - } - } - - public void removeFromScene() { - if(onScene) { - scene.removeObject(this); - onScene = false; - } - } - - public Entity(Scene scene, Mesh mesh, Material material, Vector2f coordinateStepSize, EntitySpriteConfiguration configuration) { + public Entity(Mesh mesh, Material material, Vector2f coordinateStepSize, EntitySpriteConfiguration configuration) { super(mesh, material, coordinateStepSize, configuration.getDimension().asVector()); - this.scene = scene; this.defaultSpriteColumn = configuration.getDefaultSpriteColumn(); this.spriteDirectionRows = configuration.getSpriteDirectionRows(); - this.onScene = false; this.faceDirection = Direction.DOWN; } }