Introduce MeshManager and EntityManager
This commit is contained in:
@@ -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<QuadDimension, Mesh> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -7,18 +7,15 @@ import org.joml.Vector2f;
|
|||||||
import org.joml.Vector2i;
|
import org.joml.Vector2i;
|
||||||
|
|
||||||
public abstract class AnimationableObject extends RenderableObject {
|
public abstract class AnimationableObject extends RenderableObject {
|
||||||
public AnimationableObject(Mesh mesh, Material material) {
|
public AnimationableObject(Mesh mesh, Material material, Vector2i spriteSheetDimension) {
|
||||||
super(mesh);
|
super(mesh);
|
||||||
setMaterial(material);
|
setMaterial(material);
|
||||||
var dimensions = getSpriteSheetDimensions();
|
material.setSpriteSize(1 / (float) spriteSheetDimension.x, 1 / (float) spriteSheetDimension.y);
|
||||||
material.setSpriteSize(1/(float) dimensions.x, 1/(float) dimensions.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns time in ms between frames
|
// Returns time in ms between frames
|
||||||
public abstract int getAnimationSpeed();
|
public abstract int getAnimationSpeed();
|
||||||
|
|
||||||
public abstract Vector2i getSpriteSheetDimensions();
|
|
||||||
|
|
||||||
public abstract boolean shouldAnimate();
|
public abstract boolean shouldAnimate();
|
||||||
|
|
||||||
public abstract Vector2f[] getSpriteAnimationFramesPositions();
|
public abstract Vector2f[] getSpriteAnimationFramesPositions();
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ public abstract class MovableObject extends AnimationableObject implements Updat
|
|||||||
return setCoordinates(coordinates.x, coordinates.y);
|
return setCoordinates(coordinates.x, coordinates.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public MovableObject(Mesh mesh, Material material, Vector2f coordinateStepSize) {
|
public MovableObject(Mesh mesh, Material material, Vector2f coordinateStepSize, Vector2i spriteSheetDimensions) {
|
||||||
super(mesh, material);
|
super(mesh, material, spriteSheetDimensions);
|
||||||
this.coordinateStepSize = coordinateStepSize;
|
this.coordinateStepSize = coordinateStepSize;
|
||||||
setCoordinates(0, 0);
|
setCoordinates(0, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.bartlomiejpluta.base.core.world.tileset.manager;
|
package com.bartlomiejpluta.base.core.world.tileset.manager;
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.core.gl.object.texture.TextureManager;
|
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 com.bartlomiejpluta.base.core.world.tileset.model.TileSet;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -11,10 +12,14 @@ import org.springframework.stereotype.Component;
|
|||||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
public class DefaultTileSetManager implements TileSetManager {
|
public class DefaultTileSetManager implements TileSetManager {
|
||||||
private final TextureManager textureManager;
|
private final TextureManager textureManager;
|
||||||
|
private final MeshManager meshManager;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TileSet createTileSet(String tileSetFileName, int rows, int columns) {
|
public TileSet createTileSet(String tileSetFileName, int rows, int columns) {
|
||||||
var texture = textureManager.loadTexture(tileSetFileName);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class TileSet {
|
|||||||
@Getter
|
@Getter
|
||||||
private final int tileHeight;
|
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.texture = texture;
|
||||||
this.rows = rows;
|
this.rows = rows;
|
||||||
this.columns = columns;
|
this.columns = columns;
|
||||||
@@ -27,7 +27,7 @@ public class TileSet {
|
|||||||
this.rowStep = 1/(float) rows;
|
this.rowStep = 1/(float) rows;
|
||||||
this.tileWidth = tileWidth;
|
this.tileWidth = tileWidth;
|
||||||
this.tileHeight = tileHeight;
|
this.tileHeight = tileHeight;
|
||||||
this.mesh = Mesh.quad(tileWidth, tileHeight, 0, 0);
|
this.mesh = mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile getTile(int m, int n) {
|
public Tile getTile(int m, int n) {
|
||||||
|
|||||||
@@ -1,28 +1,43 @@
|
|||||||
package com.bartlomiejpluta.base.game.logic;
|
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.gl.render.Renderer;
|
||||||
import com.bartlomiejpluta.base.core.logic.GameLogic;
|
import com.bartlomiejpluta.base.core.logic.GameLogic;
|
||||||
import com.bartlomiejpluta.base.core.ui.Window;
|
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.camera.Camera;
|
||||||
import com.bartlomiejpluta.base.core.world.scene.Scene;
|
|
||||||
import com.bartlomiejpluta.base.core.world.map.GameMap;
|
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.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.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import static org.lwjgl.glfw.GLFW.*;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Component
|
@Component
|
||||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
public class DefaultGameLogic implements GameLogic {
|
public class DefaultGameLogic implements GameLogic {
|
||||||
private final Renderer renderer;
|
private final Renderer renderer;
|
||||||
private final TileSetManager tileSetManager;
|
private final TileSetManager tileSetManager;
|
||||||
|
private final MeshManager meshManager;
|
||||||
|
private final TextureManager textureManager;
|
||||||
|
private final EntityManager entityManager;
|
||||||
|
private final Animator animator;
|
||||||
|
|
||||||
private Camera camera;
|
private Camera camera;
|
||||||
private GameMap map;
|
private GameMap map;
|
||||||
private Scene scene;
|
private Scene scene;
|
||||||
|
|
||||||
|
private Entity player;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Window window) {
|
public void init(Window window) {
|
||||||
log.info("Initializing game logic");
|
log.info("Initializing game logic");
|
||||||
@@ -36,6 +51,7 @@ public class DefaultGameLogic implements GameLogic {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(float dt) {
|
public void update(float dt) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,19 +6,12 @@ import com.bartlomiejpluta.base.core.world.movement.Direction;
|
|||||||
import com.bartlomiejpluta.base.core.world.movement.MovableObject;
|
import com.bartlomiejpluta.base.core.world.movement.MovableObject;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import org.joml.Vector2f;
|
import org.joml.Vector2f;
|
||||||
import org.joml.Vector2i;
|
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class Entity extends MovableObject {
|
public class Entity extends MovableObject {
|
||||||
private static final Vector2i SPRITE_DIMENSION = new Vector2i(4, 4);
|
private final Map<Direction, Integer> spriteDirectionRows;
|
||||||
private static final int DEFAULT_SPRITE = 0;
|
private final int defaultSpriteColumn;
|
||||||
private static final Map<Direction, Integer> SPRITE_ROWS = Map.of(
|
|
||||||
Direction.DOWN, 0,
|
|
||||||
Direction.LEFT, 1,
|
|
||||||
Direction.RIGHT, 2,
|
|
||||||
Direction.UP, 3
|
|
||||||
);
|
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private int animationSpeed = 100;
|
private int animationSpeed = 100;
|
||||||
@@ -31,11 +24,6 @@ public class Entity extends MovableObject {
|
|||||||
return 100;
|
return 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector2i getSpriteSheetDimensions() {
|
|
||||||
return SPRITE_DIMENSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldAnimate() {
|
public boolean shouldAnimate() {
|
||||||
return isMoving();
|
return isMoving();
|
||||||
@@ -43,13 +31,13 @@ public class Entity extends MovableObject {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector2f[] getSpriteAnimationFramesPositions() {
|
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)};
|
return new Vector2f[]{new Vector2f(0, row), new Vector2f(1, row), new Vector2f(2, row), new Vector2f(3, row)};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setDefaultAnimationFrame() {
|
protected void setDefaultAnimationFrame() {
|
||||||
setAnimationFrame(new Vector2f(DEFAULT_SPRITE, SPRITE_ROWS.get(faceDirection)));
|
setAnimationFrame(new Vector2f(defaultSpriteColumn, spriteDirectionRows.get(faceDirection)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -70,14 +58,9 @@ public class Entity extends MovableObject {
|
|||||||
return framesToCrossOneTile;
|
return framesToCrossOneTile;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entity(Material material, Vector2f coordinateStepSize) {
|
public Entity(Mesh mesh, Material material, Vector2f coordinateStepSize, EntitySpriteConfiguration configuration) {
|
||||||
super(buildMesh(material), material, coordinateStepSize);
|
super(mesh, material, coordinateStepSize, configuration.getDimension().asVector());
|
||||||
}
|
defaultSpriteColumn = configuration.getDefaultSpriteColumn();
|
||||||
|
spriteDirectionRows = configuration.getSpriteDirectionRows();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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<Direction, Integer> spriteDirectionRows;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class EntitySpriteDimensionConfiguration {
|
||||||
|
private int rows;
|
||||||
|
private int cols;
|
||||||
|
|
||||||
|
public Vector2i asVector() {
|
||||||
|
return new Vector2i(rows, cols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,3 +6,17 @@ app:
|
|||||||
|
|
||||||
core:
|
core:
|
||||||
targetUps: 50 # Updates per second
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user