diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/util/mesh/DefaultMeshManager.java b/engine/src/main/java/com/bartlomiejpluta/base/core/util/mesh/DefaultMeshManager.java new file mode 100755 index 00000000..b404e5bf --- /dev/null +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/util/mesh/DefaultMeshManager.java @@ -0,0 +1,33 @@ +package com.bartlomiejpluta.base.core.util.mesh; + +import com.bartlomiejpluta.base.core.gl.object.mesh.Mesh; +import lombok.Data; +import org.joml.Vector2f; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +@Component +public class DefaultMeshManager implements MeshManager { + private final Map quads = new HashMap<>(); + + @Override + public Mesh createQuad(float width, float height, float originX, float originY) { + var dim = new QuadDimension(new Vector2f(width, height), new Vector2f(originX, originY)); + var mesh = quads.get(dim); + + if(mesh == null) { + mesh = Mesh.quad(width, height, originX, originY); + quads.put(dim, mesh); + } + + return mesh; + } + + @Data + private static class QuadDimension { + private final Vector2f size; + private final Vector2f origin; + } +} diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/util/mesh/MeshManager.java b/engine/src/main/java/com/bartlomiejpluta/base/core/util/mesh/MeshManager.java new file mode 100755 index 00000000..ee2e5827 --- /dev/null +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/util/mesh/MeshManager.java @@ -0,0 +1,7 @@ +package com.bartlomiejpluta.base.core.util.mesh; + +import com.bartlomiejpluta.base.core.gl.object.mesh.Mesh; + +public interface MeshManager { + Mesh createQuad(float width, float height, float originX, float originY); +} diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/world/animation/AnimationableObject.java b/engine/src/main/java/com/bartlomiejpluta/base/core/world/animation/AnimationableObject.java index cdde8802..ab51ea7e 100755 --- a/engine/src/main/java/com/bartlomiejpluta/base/core/world/animation/AnimationableObject.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/world/animation/AnimationableObject.java @@ -7,18 +7,15 @@ import org.joml.Vector2f; import org.joml.Vector2i; public abstract class AnimationableObject extends RenderableObject { - public AnimationableObject(Mesh mesh, Material material) { + public AnimationableObject(Mesh mesh, Material material, Vector2i spriteSheetDimension) { super(mesh); setMaterial(material); - var dimensions = getSpriteSheetDimensions(); - material.setSpriteSize(1/(float) dimensions.x, 1/(float) dimensions.y); + material.setSpriteSize(1 / (float) spriteSheetDimension.x, 1 / (float) spriteSheetDimension.y); } // Returns time in ms between frames public abstract int getAnimationSpeed(); - public abstract Vector2i getSpriteSheetDimensions(); - public abstract boolean shouldAnimate(); public abstract Vector2f[] getSpriteAnimationFramesPositions(); diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/world/movement/MovableObject.java b/engine/src/main/java/com/bartlomiejpluta/base/core/world/movement/MovableObject.java index 58d10c56..9deb08c7 100755 --- a/engine/src/main/java/com/bartlomiejpluta/base/core/world/movement/MovableObject.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/world/movement/MovableObject.java @@ -68,8 +68,8 @@ public abstract class MovableObject extends AnimationableObject implements Updat return setCoordinates(coordinates.x, coordinates.y); } - public MovableObject(Mesh mesh, Material material, Vector2f coordinateStepSize) { - super(mesh, material); + public MovableObject(Mesh mesh, Material material, Vector2f coordinateStepSize, Vector2i spriteSheetDimensions) { + super(mesh, material, spriteSheetDimensions); this.coordinateStepSize = coordinateStepSize; setCoordinates(0, 0); } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/world/tileset/manager/DefaultTileSetManager.java b/engine/src/main/java/com/bartlomiejpluta/base/core/world/tileset/manager/DefaultTileSetManager.java index 1eab294b..f72686dc 100755 --- a/engine/src/main/java/com/bartlomiejpluta/base/core/world/tileset/manager/DefaultTileSetManager.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/world/tileset/manager/DefaultTileSetManager.java @@ -1,6 +1,7 @@ package com.bartlomiejpluta.base.core.world.tileset.manager; import com.bartlomiejpluta.base.core.gl.object.texture.TextureManager; +import com.bartlomiejpluta.base.core.util.mesh.MeshManager; import com.bartlomiejpluta.base.core.world.tileset.model.TileSet; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; @@ -11,10 +12,14 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class DefaultTileSetManager implements TileSetManager { private final TextureManager textureManager; + private final MeshManager meshManager; @Override public TileSet createTileSet(String tileSetFileName, int rows, int columns) { var texture = textureManager.loadTexture(tileSetFileName); - return new TileSet(texture, rows, columns, texture.getWidth() / columns, texture.getHeight() / rows); + var tileWidth = texture.getWidth() / columns; + var tileHeight = texture.getHeight() / rows; + var mesh = meshManager.createQuad(tileWidth, tileHeight, 0, 0); + return new TileSet(mesh, texture, rows, columns, tileWidth, tileHeight); } } diff --git a/engine/src/main/java/com/bartlomiejpluta/base/core/world/tileset/model/TileSet.java b/engine/src/main/java/com/bartlomiejpluta/base/core/world/tileset/model/TileSet.java index 0805db20..40a5de21 100755 --- a/engine/src/main/java/com/bartlomiejpluta/base/core/world/tileset/model/TileSet.java +++ b/engine/src/main/java/com/bartlomiejpluta/base/core/world/tileset/model/TileSet.java @@ -19,7 +19,7 @@ public class TileSet { @Getter private final int tileHeight; - public TileSet(Texture texture, int rows, int columns, int tileWidth, int tileHeight) { + public TileSet(Mesh mesh, Texture texture, int rows, int columns, int tileWidth, int tileHeight) { this.texture = texture; this.rows = rows; this.columns = columns; @@ -27,7 +27,7 @@ public class TileSet { this.rowStep = 1/(float) rows; this.tileWidth = tileWidth; this.tileHeight = tileHeight; - this.mesh = Mesh.quad(tileWidth, tileHeight, 0, 0); + this.mesh = mesh; } public Tile getTile(int m, int n) { diff --git a/game/src/main/java/com/bartlomiejpluta/base/game/logic/DefaultGameLogic.java b/game/src/main/java/com/bartlomiejpluta/base/game/logic/DefaultGameLogic.java index 5015fecb..c59d10d8 100755 --- a/game/src/main/java/com/bartlomiejpluta/base/game/logic/DefaultGameLogic.java +++ b/game/src/main/java/com/bartlomiejpluta/base/game/logic/DefaultGameLogic.java @@ -1,28 +1,43 @@ package com.bartlomiejpluta.base.game.logic; +import com.bartlomiejpluta.base.core.gl.object.material.Material; +import com.bartlomiejpluta.base.core.gl.object.texture.TextureManager; import com.bartlomiejpluta.base.core.gl.render.Renderer; import com.bartlomiejpluta.base.core.logic.GameLogic; import com.bartlomiejpluta.base.core.ui.Window; +import com.bartlomiejpluta.base.core.util.mesh.MeshManager; +import com.bartlomiejpluta.base.core.world.animation.Animator; import com.bartlomiejpluta.base.core.world.camera.Camera; -import com.bartlomiejpluta.base.core.world.scene.Scene; import com.bartlomiejpluta.base.core.world.map.GameMap; +import com.bartlomiejpluta.base.core.world.movement.Direction; +import com.bartlomiejpluta.base.core.world.scene.Scene; import com.bartlomiejpluta.base.core.world.tileset.manager.TileSetManager; +import com.bartlomiejpluta.base.game.world.entity.Entity; +import com.bartlomiejpluta.base.game.world.entity.EntityManager; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import static org.lwjgl.glfw.GLFW.*; + @Slf4j @Component @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class DefaultGameLogic implements GameLogic { private final Renderer renderer; private final TileSetManager tileSetManager; + private final MeshManager meshManager; + private final TextureManager textureManager; + private final EntityManager entityManager; + private final Animator animator; private Camera camera; private GameMap map; private Scene scene; + private Entity player; + @Override public void init(Window window) { log.info("Initializing game logic"); @@ -36,6 +51,7 @@ public class DefaultGameLogic implements GameLogic { @Override public void update(float dt) { + } @Override diff --git a/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/DefaultEntityManager.java b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/DefaultEntityManager.java new file mode 100755 index 00000000..eaa55319 --- /dev/null +++ b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/DefaultEntityManager.java @@ -0,0 +1,29 @@ +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.util.mesh.MeshManager; +import lombok.RequiredArgsConstructor; +import org.joml.Vector2f; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +public class DefaultEntityManager implements EntityManager { + private final MeshManager meshManager; + private final EntitySpriteConfiguration configuration; + + @Override + public Entity createEntity(Material material, Vector2f coordinateStepSize) { + return new Entity(buildMesh(material), material, coordinateStepSize, configuration); + } + + private Mesh buildMesh(Material material) { + var texture = material.getTexture(); + var dimension = configuration.getDimension().asVector(); + var spriteWidth = texture.getWidth() / (float) dimension.y; + var spriteHeight = texture.getHeight() / (float) dimension.x; + return meshManager.createQuad(spriteWidth, spriteHeight, spriteWidth / 2, spriteHeight); + } +} diff --git a/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/Entity.java b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/Entity.java index 44c44693..0964a4a4 100755 --- a/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/Entity.java +++ b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/Entity.java @@ -6,19 +6,12 @@ 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 SPRITE_ROWS = Map.of( - Direction.DOWN, 0, - Direction.LEFT, 1, - Direction.RIGHT, 2, - Direction.UP, 3 - ); + private final Map spriteDirectionRows; + private final int defaultSpriteColumn; @Setter private int animationSpeed = 100; @@ -31,11 +24,6 @@ public class Entity extends MovableObject { return 100; } - @Override - public Vector2i getSpriteSheetDimensions() { - return SPRITE_DIMENSION; - } - @Override public boolean shouldAnimate() { return isMoving(); @@ -43,13 +31,13 @@ public class Entity extends MovableObject { @Override public Vector2f[] getSpriteAnimationFramesPositions() { - var row = SPRITE_ROWS.get(faceDirection); + var row = spriteDirectionRows.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))); + setAnimationFrame(new Vector2f(defaultSpriteColumn, spriteDirectionRows.get(faceDirection))); } @Override @@ -70,14 +58,9 @@ public class Entity extends MovableObject { 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); + public Entity(Mesh mesh, Material material, Vector2f coordinateStepSize, EntitySpriteConfiguration configuration) { + super(mesh, material, coordinateStepSize, configuration.getDimension().asVector()); + defaultSpriteColumn = configuration.getDefaultSpriteColumn(); + spriteDirectionRows = configuration.getSpriteDirectionRows(); } } diff --git a/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/EntityManager.java b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/EntityManager.java new file mode 100755 index 00000000..3a24cd7a --- /dev/null +++ b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/EntityManager.java @@ -0,0 +1,8 @@ +package com.bartlomiejpluta.base.game.world.entity; + +import com.bartlomiejpluta.base.core.gl.object.material.Material; +import org.joml.Vector2f; + +public interface EntityManager { + Entity createEntity(Material material, Vector2f coordinateStepSize); +} diff --git a/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/EntitySpriteConfiguration.java b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/EntitySpriteConfiguration.java new file mode 100755 index 00000000..ace2c290 --- /dev/null +++ b/game/src/main/java/com/bartlomiejpluta/base/game/world/entity/EntitySpriteConfiguration.java @@ -0,0 +1,28 @@ +package com.bartlomiejpluta.base.game.world.entity; + +import com.bartlomiejpluta.base.core.world.movement.Direction; +import lombok.Data; +import org.joml.Vector2i; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.util.Map; + +@Data +@Configuration +@ConfigurationProperties(prefix = "app.sprite.entity") +public class EntitySpriteConfiguration { + private EntitySpriteDimensionConfiguration dimension; + private int defaultSpriteColumn; + private Map spriteDirectionRows; + + @Data + public static class EntitySpriteDimensionConfiguration { + private int rows; + private int cols; + + public Vector2i asVector() { + return new Vector2i(rows, cols); + } + } +} diff --git a/game/src/main/resources/application.yml b/game/src/main/resources/application.yml index 470c8817..694f71ed 100755 --- a/game/src/main/resources/application.yml +++ b/game/src/main/resources/application.yml @@ -5,4 +5,18 @@ app: height: 480 core: - targetUps: 50 # Updates per second \ No newline at end of file + targetUps: 50 # Updates per second + + sprite: + entity: + dimension: + rows: 4 + cols: 4 + + default-sprite-column: 0 + + sprite-direction-rows: + down: 0 + left: 1 + right: 2 + up: 3