Create Moveable Object
This commit is contained in:
@@ -76,15 +76,12 @@ public class Mesh implements Renderable {
|
|||||||
glDeleteVertexArrays(vaoId);
|
glDeleteVertexArrays(vaoId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Mesh quad(float width, float height) {
|
public static Mesh quad(float width, float height, float originX, float originY) {
|
||||||
var halfWidth = width/2;
|
|
||||||
var halfHeight = height/2;
|
|
||||||
|
|
||||||
var vertices = new float[] {
|
var vertices = new float[] {
|
||||||
-halfWidth, -halfHeight,
|
-originX, -originY,
|
||||||
-halfWidth, halfHeight,
|
-originX, height - originY,
|
||||||
halfWidth, halfHeight,
|
width - originX, height - originY,
|
||||||
halfWidth, -halfHeight
|
width - originX, - originY
|
||||||
};
|
};
|
||||||
|
|
||||||
var texCoords = new float[] { 0, 0, 0, 1, 1, 1, 1, 0 };
|
var texCoords = new float[] { 0, 0, 0, 1, 1, 1, 1, 0 };
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
package com.bartlomiejpluta.base.core.world.animation;
|
package com.bartlomiejpluta.base.core.world.animation;
|
||||||
|
|
||||||
public interface Animator {
|
public interface Animator {
|
||||||
void animate(AnimationableObject[] objects);
|
void animate(Iterable<AnimationableObject> objects);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import org.springframework.stereotype.Component;
|
|||||||
public class DefaultAnimator implements Animator {
|
public class DefaultAnimator implements Animator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void animate(AnimationableObject[] objects) {
|
public void animate(Iterable<AnimationableObject> objects) {
|
||||||
for (var object : objects) {
|
for (var object : objects) {
|
||||||
animate(object);
|
animate(object);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,37 @@
|
|||||||
package com.bartlomiejpluta.base.core.world.map;
|
package com.bartlomiejpluta.base.core.world.map;
|
||||||
|
|
||||||
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 lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.joml.Vector2f;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class GameMap {
|
public class GameMap {
|
||||||
private static final int LAYERS = 4;
|
private static final int LAYERS = 4;
|
||||||
|
private final TileSet tileSet;
|
||||||
private final Tile[][] map;
|
private final Tile[][] map;
|
||||||
private final float scale;
|
private final float scale;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final Vector2f stepSize;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final int rows;
|
private final int rows;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final int cols;
|
private final int cols;
|
||||||
|
|
||||||
|
public GameMap(TileSet tileSet, int rows, int cols, float scale) {
|
||||||
public GameMap(int rows, int cols, float scale) {
|
this.tileSet = tileSet;
|
||||||
this.rows = rows;
|
this.rows = rows;
|
||||||
this.cols = cols;
|
this.cols = cols;
|
||||||
this.scale = scale;
|
this.scale = scale;
|
||||||
|
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];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -32,9 +42,7 @@ public class GameMap {
|
|||||||
|
|
||||||
private void recalculateTileGeometry(Tile tile, int i, int j) {
|
private void recalculateTileGeometry(Tile tile, int i, int j) {
|
||||||
tile.setScale(scale);
|
tile.setScale(scale);
|
||||||
var size = tile.getWidth();
|
tile.setPosition(i * stepSize.x, j * stepSize.y);
|
||||||
var offset = size * scale;
|
|
||||||
tile.setPosition(i * offset, j * offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile[] getLayer(int layer) {
|
public Tile[] getLayer(int layer) {
|
||||||
|
|||||||
@@ -4,19 +4,31 @@ import com.bartlomiejpluta.base.core.gl.render.Renderable;
|
|||||||
import com.bartlomiejpluta.base.core.gl.shader.constant.UniformName;
|
import com.bartlomiejpluta.base.core.gl.shader.constant.UniformName;
|
||||||
import com.bartlomiejpluta.base.core.gl.shader.manager.ShaderManager;
|
import com.bartlomiejpluta.base.core.gl.shader.manager.ShaderManager;
|
||||||
import com.bartlomiejpluta.base.core.ui.Window;
|
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.camera.Camera;
|
||||||
import com.bartlomiejpluta.base.core.world.object.RenderableObject;
|
import com.bartlomiejpluta.base.core.world.object.RenderableObject;
|
||||||
import com.bartlomiejpluta.base.core.world.map.GameMap;
|
import com.bartlomiejpluta.base.core.world.map.GameMap;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class Scene implements Renderable {
|
public class Scene implements Renderable {
|
||||||
|
private final Animator animator;
|
||||||
private final Camera camera;
|
private final Camera camera;
|
||||||
|
private final List<AnimationableObject> objects = new ArrayList<>();
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private GameMap map;
|
private GameMap map;
|
||||||
|
|
||||||
|
public Scene addObject(AnimationableObject object) {
|
||||||
|
objects.add(object);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(Window window, ShaderManager shaderManager) {
|
public void render(Window window, ShaderManager shaderManager) {
|
||||||
shaderManager.setUniform(UniformName.UNI_PROJECTION_MATRIX, camera.getProjectionMatrix(window));
|
shaderManager.setUniform(UniformName.UNI_PROJECTION_MATRIX, camera.getProjectionMatrix(window));
|
||||||
@@ -26,11 +38,21 @@ public class Scene implements Renderable {
|
|||||||
renderArray(map.getLayer(1), window, shaderManager);
|
renderArray(map.getLayer(1), window, shaderManager);
|
||||||
|
|
||||||
// Player will be rendered here
|
// Player will be rendered here
|
||||||
|
renderList(objects, window, shaderManager);
|
||||||
|
animator.animate(objects);
|
||||||
|
|
||||||
renderArray(map.getLayer(2), window, shaderManager);
|
renderArray(map.getLayer(2), window, shaderManager);
|
||||||
renderArray(map.getLayer(3), window, shaderManager);
|
renderArray(map.getLayer(3), window, shaderManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private <T extends RenderableObject> void renderList(List<T> objects, Window window, ShaderManager shaderManager) {
|
||||||
|
for (var object : objects) {
|
||||||
|
if (object != null) {
|
||||||
|
renderObject(object, window, shaderManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private <T extends RenderableObject> void renderArray(T[] objects, Window window, ShaderManager shaderManager) {
|
private <T extends RenderableObject> void renderArray(T[] objects, Window window, ShaderManager shaderManager) {
|
||||||
for (var object : objects) {
|
for (var object : objects) {
|
||||||
if (object != null) {
|
if (object != null) {
|
||||||
|
|||||||
@@ -2,28 +2,19 @@ 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.world.tileset.model.TileSet;
|
import com.bartlomiejpluta.base.core.world.tileset.model.TileSet;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||||
public class DefaultTileSetManager implements TileSetManager {
|
public class DefaultTileSetManager implements TileSetManager {
|
||||||
private final TextureManager textureManager;
|
private final TextureManager textureManager;
|
||||||
private final int tileWidth;
|
|
||||||
private final int tileHeight;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
public DefaultTileSetManager(
|
|
||||||
TextureManager textureManager,
|
|
||||||
@Value("${app.map.tile.width}") int tileWidth,
|
|
||||||
@Value("${app.map.tile.width}") int tileHeight) {
|
|
||||||
this.textureManager = textureManager;
|
|
||||||
this.tileWidth = tileWidth;
|
|
||||||
this.tileHeight = tileHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TileSet createTileSet(String tileSetFileName, int rows, int columns) {
|
public TileSet createTileSet(String tileSetFileName, int rows, int columns) {
|
||||||
return new TileSet(textureManager.loadTexture(tileSetFileName), rows, columns, tileWidth, tileHeight);
|
var texture = textureManager.loadTexture(tileSetFileName);
|
||||||
|
return new TileSet(texture, rows, columns, texture.getWidth() / columns, texture.getHeight() / rows);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.bartlomiejpluta.base.core.world.tileset.model;
|
|||||||
import com.bartlomiejpluta.base.core.gl.object.material.Material;
|
import com.bartlomiejpluta.base.core.gl.object.material.Material;
|
||||||
import com.bartlomiejpluta.base.core.gl.object.mesh.Mesh;
|
import com.bartlomiejpluta.base.core.gl.object.mesh.Mesh;
|
||||||
import com.bartlomiejpluta.base.core.gl.object.texture.Texture;
|
import com.bartlomiejpluta.base.core.gl.object.texture.Texture;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
public class TileSet {
|
public class TileSet {
|
||||||
private final Texture texture;
|
private final Texture texture;
|
||||||
@@ -10,10 +11,14 @@ public class TileSet {
|
|||||||
private final int columns;
|
private final int columns;
|
||||||
private final float columnStep;
|
private final float columnStep;
|
||||||
private final float rowStep;
|
private final float rowStep;
|
||||||
private final int tileWidth;
|
|
||||||
private final int tileHeight;
|
|
||||||
private final Mesh mesh;
|
private final Mesh mesh;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final int tileWidth;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final int tileHeight;
|
||||||
|
|
||||||
public TileSet(Texture texture, int rows, int columns, int tileWidth, int tileHeight) {
|
public TileSet(Texture texture, int rows, int columns, int tileWidth, int tileHeight) {
|
||||||
this.texture = texture;
|
this.texture = texture;
|
||||||
this.rows = rows;
|
this.rows = rows;
|
||||||
@@ -22,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);
|
this.mesh = Mesh.quad(tileWidth, tileHeight, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tile getTile(int m, int n) {
|
public Tile getTile(int m, int n) {
|
||||||
|
|||||||
@@ -8,6 +8,23 @@ plugins {
|
|||||||
group 'com.bartlomiejpluta.base'
|
group 'com.bartlomiejpluta.base'
|
||||||
version 'unspecified'
|
version 'unspecified'
|
||||||
|
|
||||||
|
import org.gradle.internal.os.OperatingSystem
|
||||||
|
|
||||||
|
switch (OperatingSystem.current()) {
|
||||||
|
case OperatingSystem.LINUX:
|
||||||
|
def osArch = System.getProperty("os.arch")
|
||||||
|
project.ext.lwjglNatives = osArch.startsWith("arm") || osArch.startsWith("aarch64")
|
||||||
|
? "natives-linux-${osArch.contains("64") || osArch.startsWith("armv8") ? "arm64" : "arm32"}"
|
||||||
|
: "natives-linux"
|
||||||
|
break
|
||||||
|
case OperatingSystem.MAC_OS:
|
||||||
|
project.ext.lwjglNatives = "natives-macos"
|
||||||
|
break
|
||||||
|
case OperatingSystem.WINDOWS:
|
||||||
|
project.ext.lwjglNatives = System.getProperty("os.arch").contains("64") ? "natives-windows" : "natives-windows-x86"
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
compileOnly {
|
compileOnly {
|
||||||
extendsFrom annotationProcessor
|
extendsFrom annotationProcessor
|
||||||
@@ -22,6 +39,11 @@ repositories {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation project(":engine")
|
implementation project(":engine")
|
||||||
|
|
||||||
|
implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
|
||||||
|
|
||||||
|
// LWJGL
|
||||||
|
implementation "org.lwjgl:lwjgl-glfw"
|
||||||
|
|
||||||
// Spring
|
// Spring
|
||||||
implementation 'org.springframework.boot:spring-boot-starter'
|
implementation 'org.springframework.boot:spring-boot-starter'
|
||||||
compileOnly 'org.projectlombok:lombok'
|
compileOnly 'org.projectlombok:lombok'
|
||||||
|
|||||||
5
game/src/main/java/com/bartlomiejpluta/base/game/world/Direction.java
Executable file
5
game/src/main/java/com/bartlomiejpluta/base/game/world/Direction.java
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
package com.bartlomiejpluta.base.game.world;
|
||||||
|
|
||||||
|
public enum Direction {
|
||||||
|
UP, DOWN, LEFT, RIGHT
|
||||||
|
}
|
||||||
77
game/src/main/java/com/bartlomiejpluta/base/game/world/MoveableObject.java
Executable file
77
game/src/main/java/com/bartlomiejpluta/base/game/world/MoveableObject.java
Executable file
@@ -0,0 +1,77 @@
|
|||||||
|
package com.bartlomiejpluta.base.game.world;
|
||||||
|
|
||||||
|
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 lombok.Getter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.joml.Vector2f;
|
||||||
|
import org.joml.Vector2i;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Getter
|
||||||
|
public abstract class MoveableObject extends AnimationableObject {
|
||||||
|
private static final Vector2i SPRITE_DIMENSION = new Vector2i(4, 4);
|
||||||
|
|
||||||
|
private final Vector2i coordinates = new Vector2i(0, 0);
|
||||||
|
private Direction direction = Direction.DOWN;
|
||||||
|
private final Vector2f coordinateStepSize;
|
||||||
|
|
||||||
|
public MoveableObject 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 MoveableObject setCoordinates(Vector2i coordinates) {
|
||||||
|
return setCoordinates(coordinates.x, coordinates.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoveableObject moveCoordinates(int x, int y) {
|
||||||
|
coordinates.x += x;
|
||||||
|
coordinates.y += y;
|
||||||
|
movePosition(x * coordinateStepSize.x, y * coordinateStepSize.y);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoveableObject moveCoordinates(Vector2i coordinates) {
|
||||||
|
return moveCoordinates(coordinates.x, coordinates.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoveableObject setDirection(Direction direction) {
|
||||||
|
this.direction = direction;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector2i getSpriteSheetDimensions() {
|
||||||
|
return SPRITE_DIMENSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Vector2f[] getSpriteAnimationFramesPositions() {
|
||||||
|
var row = switch (direction) {
|
||||||
|
case DOWN -> 0;
|
||||||
|
case LEFT -> 1;
|
||||||
|
case RIGHT -> 2;
|
||||||
|
case UP -> 3;
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Vector2f[]{new Vector2f(0, row), new Vector2f(1, row), new Vector2f(2, row), new Vector2f(3, row)};
|
||||||
|
}
|
||||||
|
|
||||||
|
public MoveableObject(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,9 +5,4 @@ app:
|
|||||||
height: 480
|
height: 480
|
||||||
|
|
||||||
core:
|
core:
|
||||||
targetUps: 50 # Updates per second
|
targetUps: 50 # Updates per second
|
||||||
|
|
||||||
map:
|
|
||||||
tile:
|
|
||||||
width: 50
|
|
||||||
height: 50
|
|
||||||
Reference in New Issue
Block a user