Merge :game into :engine module
This commit is contained in:
@@ -7,11 +7,15 @@
|
||||
*/
|
||||
|
||||
plugins {
|
||||
id 'java-library'
|
||||
id 'java'
|
||||
id 'application'
|
||||
id 'org.springframework.boot' version "$springBootVersion"
|
||||
id 'io.spring.dependency-management' version "$springDependencyManagementVersion"
|
||||
}
|
||||
|
||||
group 'com.bartlomiejpluta.base'
|
||||
version 'unspecified'
|
||||
|
||||
import org.gradle.internal.os.OperatingSystem
|
||||
|
||||
switch (OperatingSystem.current()) {
|
||||
@@ -42,18 +46,20 @@ repositories {
|
||||
}
|
||||
|
||||
bootJar {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
jar {
|
||||
enabled = true
|
||||
}
|
||||
|
||||
jar {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
|
||||
implementation project(":proto")
|
||||
implementation project(":api")
|
||||
|
||||
// LWJGL
|
||||
api "org.lwjgl:lwjgl-glfw"
|
||||
implementation platform("org.lwjgl:lwjgl-bom:$lwjglVersion")
|
||||
implementation "org.lwjgl:lwjgl-glfw"
|
||||
implementation "org.lwjgl:lwjgl"
|
||||
implementation "org.lwjgl:lwjgl-assimp"
|
||||
implementation "org.lwjgl:lwjgl-bgfx"
|
||||
@@ -75,10 +81,15 @@ dependencies {
|
||||
runtimeOnly "org.lwjgl:lwjgl-stb::$lwjglNatives"
|
||||
|
||||
// Spring
|
||||
api 'org.springframework.boot:spring-boot-starter'
|
||||
implementation 'org.springframework.boot:spring-boot-starter'
|
||||
compileOnly 'org.projectlombok:lombok'
|
||||
annotationProcessor 'org.projectlombok:lombok'
|
||||
|
||||
// This dependency is used by the application.
|
||||
api "org.joml:joml:${jomlVersion}"
|
||||
implementation "org.joml:joml:${jomlVersion}"
|
||||
}
|
||||
|
||||
application {
|
||||
// Define the main class for the application.
|
||||
mainClass = 'com.bartlomiejpluta.base.engine.App'
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package com.bartlomiejpluta.base.core.engine;
|
||||
|
||||
public interface GameEngine {
|
||||
void start();
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package com.bartlomiejpluta.base.core.gl.render;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.core.ui.Window;
|
||||
import com.bartlomiejpluta.base.core.world.camera.Camera;
|
||||
|
||||
public interface Renderable {
|
||||
void render(Window window, Camera camera, ShaderManager shaderManager);
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package com.bartlomiejpluta.base.core.gl.render;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.core.ui.Window;
|
||||
import com.bartlomiejpluta.base.core.world.camera.Camera;
|
||||
|
||||
public interface Renderer extends Cleanable {
|
||||
void init();
|
||||
void render(Window window, Camera camera, Renderable renderable);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.bartlomiejpluta.base.core.profiling.fps;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.core.logic.Updatable;
|
||||
|
||||
public interface FPSMonitor extends Updatable, Cleanable {
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.bartlomiejpluta.base.core.util.mesh;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.core.gl.object.mesh.Mesh;
|
||||
|
||||
public interface MeshManager extends Cleanable {
|
||||
Mesh createQuad(float width, float height, float originX, float originY);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* This Java source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package com.bartlomiejpluta.base.engine;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.engine.GameEngine;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@Slf4j
|
||||
@SpringBootApplication(scanBasePackages = "com.bartlomiejpluta.base")
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class App implements ApplicationRunner {
|
||||
private final GameEngine gameEngine;
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) {
|
||||
log.info("Starting game engine");
|
||||
gameEngine.start();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(App.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.bartlomiejpluta.base.engine.common.asset;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public abstract class Asset {
|
||||
|
||||
@NonNull
|
||||
protected final String uid;
|
||||
|
||||
@NonNull
|
||||
protected final String source;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.bartlomiejpluta.base.engine.common.manager;
|
||||
|
||||
public interface AssetManager<A, T> {
|
||||
void registerAsset(A asset);
|
||||
|
||||
T loadObject(String uid);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.bartlomiejpluta.base.engine.common.serial;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.error.AppException;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public abstract class Deserializer<T> {
|
||||
protected abstract T parse(InputStream input) throws Exception;
|
||||
|
||||
public T deserialize(InputStream input) {
|
||||
try {
|
||||
return parse(input);
|
||||
} catch (Exception e) {
|
||||
throw new AppException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.bartlomiejpluta.base.core.engine;
|
||||
package com.bartlomiejpluta.base.engine.core.engine;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gc.OffHeapGarbageCollector;
|
||||
import com.bartlomiejpluta.base.core.logic.GameLogic;
|
||||
import com.bartlomiejpluta.base.core.thread.ThreadManager;
|
||||
import com.bartlomiejpluta.base.core.time.ChronoMeter;
|
||||
import com.bartlomiejpluta.base.core.ui.Window;
|
||||
import com.bartlomiejpluta.base.core.ui.WindowManager;
|
||||
import com.bartlomiejpluta.base.engine.gc.OffHeapGarbageCollector;
|
||||
import com.bartlomiejpluta.base.engine.logic.GameLogic;
|
||||
import com.bartlomiejpluta.base.engine.thread.ThreadManager;
|
||||
import com.bartlomiejpluta.base.engine.time.ChronoMeter;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.ui.WindowManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.bartlomiejpluta.base.engine.core.engine;
|
||||
|
||||
public interface GameEngine {
|
||||
void start();
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.bartlomiejpluta.base.core.gl.object.material;
|
||||
package com.bartlomiejpluta.base.engine.core.gl.object.material;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gl.object.texture.Texture;
|
||||
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 com.bartlomiejpluta.base.core.world.camera.Camera;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.texture.Texture;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.render.Renderable;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.constant.UniformName;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
import lombok.Getter;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector4f;
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.bartlomiejpluta.base.core.gl.object.mesh;
|
||||
package com.bartlomiejpluta.base.engine.core.gl.object.mesh;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gc.Disposable;
|
||||
import com.bartlomiejpluta.base.core.gl.render.Renderable;
|
||||
import com.bartlomiejpluta.base.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.core.ui.Window;
|
||||
import com.bartlomiejpluta.base.core.world.camera.Camera;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.render.Renderable;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.gc.Disposable;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.bartlomiejpluta.base.core.gl.object.texture;
|
||||
package com.bartlomiejpluta.base.engine.core.gl.object.texture;
|
||||
|
||||
import com.bartlomiejpluta.base.core.util.res.ResourcesManager;
|
||||
import com.bartlomiejpluta.base.engine.util.res.ResourcesManager;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.bartlomiejpluta.base.core.gl.object.texture;
|
||||
package com.bartlomiejpluta.base.engine.core.gl.object.texture;
|
||||
|
||||
import com.bartlomiejpluta.base.core.error.AppException;
|
||||
import com.bartlomiejpluta.base.core.gc.Disposable;
|
||||
import com.bartlomiejpluta.base.engine.error.AppException;
|
||||
import com.bartlomiejpluta.base.engine.gc.Disposable;
|
||||
import lombok.Getter;
|
||||
import org.joml.Vector2f;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.bartlomiejpluta.base.core.gl.object.texture;
|
||||
package com.bartlomiejpluta.base.engine.core.gl.object.texture;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.engine.gc.Cleanable;
|
||||
|
||||
public interface TextureManager extends Cleanable {
|
||||
Texture loadTexture(String textureFileName);
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.bartlomiejpluta.base.core.gl.render;
|
||||
package com.bartlomiejpluta.base.engine.core.gl.render;
|
||||
|
||||
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.camera.Camera;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.constant.UniformName;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.bartlomiejpluta.base.engine.core.gl.render;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
|
||||
public interface Renderable {
|
||||
void render(Window window, Camera camera, ShaderManager shaderManager);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.bartlomiejpluta.base.engine.core.gl.render;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
|
||||
public interface Renderer extends Cleanable {
|
||||
void init();
|
||||
void render(Window window, Camera camera, Renderable renderable);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.gl.shader.constant;
|
||||
package com.bartlomiejpluta.base.engine.core.gl.shader.constant;
|
||||
|
||||
public interface UniformName {
|
||||
String UNI_VIEW_MODEL_MATRIX = "viewModelMatrix";
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.bartlomiejpluta.base.core.gl.shader.manager;
|
||||
package com.bartlomiejpluta.base.engine.core.gl.shader.manager;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gl.shader.program.ShaderProgram;
|
||||
import com.bartlomiejpluta.base.core.gl.shader.uniform.Uniform;
|
||||
import com.bartlomiejpluta.base.core.util.res.ResourcesManager;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.program.ShaderProgram;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.uniform.Uniform;
|
||||
import com.bartlomiejpluta.base.engine.util.res.ResourcesManager;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.joml.*;
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.bartlomiejpluta.base.core.gl.shader.manager;
|
||||
package com.bartlomiejpluta.base.engine.core.gl.shader.manager;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.core.gl.shader.uniform.Uniform;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.uniform.Uniform;
|
||||
import com.bartlomiejpluta.base.engine.gc.Cleanable;
|
||||
import org.joml.*;
|
||||
|
||||
public interface ShaderManager extends Cleanable {
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.bartlomiejpluta.base.core.gl.shader.program;
|
||||
package com.bartlomiejpluta.base.engine.core.gl.shader.program;
|
||||
|
||||
import com.bartlomiejpluta.base.core.error.AppException;
|
||||
import com.bartlomiejpluta.base.core.gc.Disposable;
|
||||
import com.bartlomiejpluta.base.core.gl.shader.uniform.Uniform;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.uniform.Uniform;
|
||||
import com.bartlomiejpluta.base.engine.error.AppException;
|
||||
import com.bartlomiejpluta.base.engine.gc.Disposable;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.joml.*;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.bartlomiejpluta.base.core.gl.shader.uniform;
|
||||
package com.bartlomiejpluta.base.engine.core.gl.shader.uniform;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gl.shader.program.ShaderProgram;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.program.ShaderProgram;
|
||||
|
||||
public interface Uniform {
|
||||
void createUniform(ShaderProgram shaderProgram, String uniformName);
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.error;
|
||||
package com.bartlomiejpluta.base.engine.error;
|
||||
|
||||
public class AppException extends RuntimeException {
|
||||
public AppException() {
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.gc;
|
||||
package com.bartlomiejpluta.base.engine.gc;
|
||||
|
||||
public interface Cleanable {
|
||||
void cleanUp();
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.gc;
|
||||
package com.bartlomiejpluta.base.engine.gc;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.gc;
|
||||
package com.bartlomiejpluta.base.engine.gc;
|
||||
|
||||
public interface Disposable {
|
||||
void dispose();
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.gc;
|
||||
package com.bartlomiejpluta.base.engine.gc;
|
||||
|
||||
public interface OffHeapGarbageCollector {
|
||||
void cleanUp();
|
||||
@@ -0,0 +1,144 @@
|
||||
package com.bartlomiejpluta.base.engine.input;
|
||||
|
||||
import com.bartlomiejpluta.base.api.input.Key;
|
||||
import com.bartlomiejpluta.base.api.input.Keyboard;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class GLFWKeyboard implements Keyboard {
|
||||
private final Window window;
|
||||
|
||||
@Override
|
||||
public boolean isKeyPressed(Key key) {
|
||||
return window.isKeyPressed(glfwCode(key));
|
||||
}
|
||||
|
||||
private static int glfwCode(Key key) {
|
||||
return switch (key) {
|
||||
case KEY_SPACE -> GLFW_KEY_SPACE;
|
||||
case KEY_APOSTROPHE -> GLFW_KEY_APOSTROPHE;
|
||||
case KEY_COMMA -> GLFW_KEY_COMMA;
|
||||
case KEY_MINUS -> GLFW_KEY_MINUS;
|
||||
case KEY_PERIOD -> GLFW_KEY_PERIOD;
|
||||
case KEY_SLASH -> GLFW_KEY_SLASH;
|
||||
case KEY_0 -> GLFW_KEY_0;
|
||||
case KEY_1 -> GLFW_KEY_1;
|
||||
case KEY_2 -> GLFW_KEY_2;
|
||||
case KEY_3 -> GLFW_KEY_3;
|
||||
case KEY_4 -> GLFW_KEY_4;
|
||||
case KEY_5 -> GLFW_KEY_5;
|
||||
case KEY_6 -> GLFW_KEY_6;
|
||||
case KEY_7 -> GLFW_KEY_7;
|
||||
case KEY_8 -> GLFW_KEY_8;
|
||||
case KEY_9 -> GLFW_KEY_9;
|
||||
case KEY_SEMICOLON -> GLFW_KEY_SEMICOLON;
|
||||
case KEY_EQUAL -> GLFW_KEY_EQUAL;
|
||||
case KEY_A -> GLFW_KEY_A;
|
||||
case KEY_B -> GLFW_KEY_B;
|
||||
case KEY_C -> GLFW_KEY_C;
|
||||
case KEY_D -> GLFW_KEY_D;
|
||||
case KEY_E -> GLFW_KEY_E;
|
||||
case KEY_F -> GLFW_KEY_F;
|
||||
case KEY_G -> GLFW_KEY_G;
|
||||
case KEY_H -> GLFW_KEY_H;
|
||||
case KEY_I -> GLFW_KEY_I;
|
||||
case KEY_J -> GLFW_KEY_J;
|
||||
case KEY_K -> GLFW_KEY_K;
|
||||
case KEY_L -> GLFW_KEY_L;
|
||||
case KEY_M -> GLFW_KEY_M;
|
||||
case KEY_N -> GLFW_KEY_N;
|
||||
case KEY_O -> GLFW_KEY_O;
|
||||
case KEY_P -> GLFW_KEY_P;
|
||||
case KEY_Q -> GLFW_KEY_Q;
|
||||
case KEY_R -> GLFW_KEY_R;
|
||||
case KEY_S -> GLFW_KEY_S;
|
||||
case KEY_T -> GLFW_KEY_T;
|
||||
case KEY_U -> GLFW_KEY_U;
|
||||
case KEY_V -> GLFW_KEY_V;
|
||||
case KEY_W -> GLFW_KEY_W;
|
||||
case KEY_X -> GLFW_KEY_X;
|
||||
case KEY_Y -> GLFW_KEY_Y;
|
||||
case KEY_Z -> GLFW_KEY_Z;
|
||||
case KEY_LEFT_BRACKET -> GLFW_KEY_LEFT_BRACKET;
|
||||
case KEY_BACKSLASH -> GLFW_KEY_BACKSLASH;
|
||||
case KEY_RIGHT_BRACKET -> GLFW_KEY_RIGHT_BRACKET;
|
||||
case KEY_GRAVE_ACCENT -> GLFW_KEY_GRAVE_ACCENT;
|
||||
case KEY_WORLD_1 -> GLFW_KEY_WORLD_1;
|
||||
case KEY_WORLD_2 -> GLFW_KEY_WORLD_2;
|
||||
case KEY_ESCAPE -> GLFW_KEY_ESCAPE;
|
||||
case KEY_ENTER -> GLFW_KEY_ENTER;
|
||||
case KEY_TAB -> GLFW_KEY_TAB;
|
||||
case KEY_BACKSPACE -> GLFW_KEY_BACKSPACE;
|
||||
case KEY_INSERT -> GLFW_KEY_INSERT;
|
||||
case KEY_DELETE -> GLFW_KEY_DELETE;
|
||||
case KEY_RIGHT -> GLFW_KEY_RIGHT;
|
||||
case KEY_LEFT -> GLFW_KEY_LEFT;
|
||||
case KEY_DOWN -> GLFW_KEY_DOWN;
|
||||
case KEY_UP -> GLFW_KEY_UP;
|
||||
case KEY_PAGE_UP -> GLFW_KEY_PAGE_UP;
|
||||
case KEY_PAGE_DOWN -> GLFW_KEY_PAGE_DOWN;
|
||||
case KEY_HOME -> GLFW_KEY_HOME;
|
||||
case KEY_END -> GLFW_KEY_END;
|
||||
case KEY_CAPS_LOCK -> GLFW_KEY_CAPS_LOCK;
|
||||
case KEY_SCROLL_LOCK -> GLFW_KEY_SCROLL_LOCK;
|
||||
case KEY_NUM_LOCK -> GLFW_KEY_NUM_LOCK;
|
||||
case KEY_PRINT_SCREEN -> GLFW_KEY_PRINT_SCREEN;
|
||||
case KEY_PAUSE -> GLFW_KEY_PAUSE;
|
||||
case KEY_F1 -> GLFW_KEY_F1;
|
||||
case KEY_F2 -> GLFW_KEY_F2;
|
||||
case KEY_F3 -> GLFW_KEY_F3;
|
||||
case KEY_F4 -> GLFW_KEY_F4;
|
||||
case KEY_F5 -> GLFW_KEY_F5;
|
||||
case KEY_F6 -> GLFW_KEY_F6;
|
||||
case KEY_F7 -> GLFW_KEY_F7;
|
||||
case KEY_F8 -> GLFW_KEY_F8;
|
||||
case KEY_F9 -> GLFW_KEY_F9;
|
||||
case KEY_F10 -> GLFW_KEY_F10;
|
||||
case KEY_F11 -> GLFW_KEY_F11;
|
||||
case KEY_F12 -> GLFW_KEY_F12;
|
||||
case KEY_F13 -> GLFW_KEY_F13;
|
||||
case KEY_F14 -> GLFW_KEY_F14;
|
||||
case KEY_F15 -> GLFW_KEY_F15;
|
||||
case KEY_F16 -> GLFW_KEY_F16;
|
||||
case KEY_F17 -> GLFW_KEY_F17;
|
||||
case KEY_F18 -> GLFW_KEY_F18;
|
||||
case KEY_F19 -> GLFW_KEY_F19;
|
||||
case KEY_F20 -> GLFW_KEY_F20;
|
||||
case KEY_F21 -> GLFW_KEY_F21;
|
||||
case KEY_F22 -> GLFW_KEY_F22;
|
||||
case KEY_F23 -> GLFW_KEY_F23;
|
||||
case KEY_F24 -> GLFW_KEY_F24;
|
||||
case KEY_F25 -> GLFW_KEY_F25;
|
||||
case KEY_KP_0 -> GLFW_KEY_KP_0;
|
||||
case KEY_KP_1 -> GLFW_KEY_KP_1;
|
||||
case KEY_KP_2 -> GLFW_KEY_KP_2;
|
||||
case KEY_KP_3 -> GLFW_KEY_KP_3;
|
||||
case KEY_KP_4 -> GLFW_KEY_KP_4;
|
||||
case KEY_KP_5 -> GLFW_KEY_KP_5;
|
||||
case KEY_KP_6 -> GLFW_KEY_KP_6;
|
||||
case KEY_KP_7 -> GLFW_KEY_KP_7;
|
||||
case KEY_KP_8 -> GLFW_KEY_KP_8;
|
||||
case KEY_KP_9 -> GLFW_KEY_KP_9;
|
||||
case KEY_KP_DECIMAL -> GLFW_KEY_KP_DECIMAL;
|
||||
case KEY_KP_DIVIDE -> GLFW_KEY_KP_DIVIDE;
|
||||
case KEY_KP_MULTIPLY -> GLFW_KEY_KP_MULTIPLY;
|
||||
case KEY_KP_SUBTRACT -> GLFW_KEY_KP_SUBTRACT;
|
||||
case KEY_KP_ADD -> GLFW_KEY_KP_ADD;
|
||||
case KEY_KP_ENTER -> GLFW_KEY_KP_ENTER;
|
||||
case KEY_KP_EQUAL -> GLFW_KEY_KP_EQUAL;
|
||||
case KEY_LEFT_SHIFT -> GLFW_KEY_LEFT_SHIFT;
|
||||
case KEY_LEFT_CONTROL -> GLFW_KEY_LEFT_CONTROL;
|
||||
case KEY_LEFT_ALT -> GLFW_KEY_LEFT_ALT;
|
||||
case KEY_LEFT_SUPER -> GLFW_KEY_LEFT_SUPER;
|
||||
case KEY_RIGHT_SHIFT -> GLFW_KEY_RIGHT_SHIFT;
|
||||
case KEY_RIGHT_CONTROL -> GLFW_KEY_RIGHT_CONTROL;
|
||||
case KEY_RIGHT_ALT -> GLFW_KEY_RIGHT_ALT;
|
||||
case KEY_RIGHT_SUPER -> GLFW_KEY_RIGHT_SUPER;
|
||||
case KEY_MENU -> GLFW_KEY_MENU;
|
||||
case KEY_LAST -> GLFW_KEY_LAST;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.bartlomiejpluta.base.engine.logic;
|
||||
|
||||
import com.bartlomiejpluta.base.api.runner.GameRunner;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.texture.TextureManager;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.render.Renderer;
|
||||
import com.bartlomiejpluta.base.engine.project.loader.ClassLoader;
|
||||
import com.bartlomiejpluta.base.engine.project.loader.ProjectLoader;
|
||||
import com.bartlomiejpluta.base.engine.project.model.Project;
|
||||
import com.bartlomiejpluta.base.engine.project.model.RenderableContext;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.util.mesh.MeshManager;
|
||||
import com.bartlomiejpluta.base.engine.util.profiling.fps.FPSMonitor;
|
||||
import com.bartlomiejpluta.base.engine.util.profiling.time.TimeProfilerService;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.manager.EntityManager;
|
||||
import com.bartlomiejpluta.base.engine.world.image.manager.ImageManager;
|
||||
import com.bartlomiejpluta.base.engine.world.map.manager.MapManager;
|
||||
import com.bartlomiejpluta.base.engine.world.tileset.manager.TileSetManager;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@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 ImageManager imageManager;
|
||||
private final TimeProfilerService profiler;
|
||||
private final FPSMonitor fpsMonitor;
|
||||
private final MapManager mapManager;
|
||||
private final ProjectLoader projectLoader;
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
private final RenderableContext context;
|
||||
|
||||
private final Camera camera = new Camera();
|
||||
|
||||
private Project project;
|
||||
private GameRunner runner;
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void init(Window window) {
|
||||
log.info("Initializing game logic");
|
||||
renderer.init();
|
||||
context.init(window, camera);
|
||||
|
||||
project = projectLoader.loadProject();
|
||||
var runnerClass = classLoader.<GameRunner>loadClass(project.getRunner());
|
||||
runner = runnerClass.getConstructor().newInstance();
|
||||
|
||||
runner.init(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void input(Window window) {
|
||||
context.input();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
context.update(dt);
|
||||
fpsMonitor.update(dt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Window window) {
|
||||
renderer.render(window, camera, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp() {
|
||||
log.info("There is nothing to clean up here");
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.bartlomiejpluta.base.core.logic;
|
||||
package com.bartlomiejpluta.base.engine.logic;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.core.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
|
||||
public interface GameLogic extends Cleanable {
|
||||
void init(Window window);
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.logic;
|
||||
package com.bartlomiejpluta.base.engine.logic;
|
||||
|
||||
public interface Updatable {
|
||||
void update(float dt);
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.bartlomiejpluta.base.engine.project.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.nio.file.Path;
|
||||
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "app.project")
|
||||
public class ProjectConfiguration {
|
||||
private String mainFile;
|
||||
private String resourcePath;
|
||||
|
||||
|
||||
public String projectFile(String... path) {
|
||||
return Path.of(resourcePath, path).toString().replaceAll("\\\\", "/");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.bartlomiejpluta.base.engine.project.loader;
|
||||
|
||||
public interface ClassLoader {
|
||||
<T> Class<T> loadClass(String className);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.bartlomiejpluta.base.engine.project.loader;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.error.AppException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class DefaultClassLoader implements ClassLoader {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Class<T> loadClass(String className) {
|
||||
try {
|
||||
return (Class<T>) getClass().getClassLoader().loadClass(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new AppException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.bartlomiejpluta.base.engine.project.loader;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.project.config.ProjectConfiguration;
|
||||
import com.bartlomiejpluta.base.engine.project.model.Project;
|
||||
import com.bartlomiejpluta.base.engine.project.serial.ProjectDeserializer;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.manager.EntitySetManager;
|
||||
import com.bartlomiejpluta.base.engine.world.image.manager.ImageManager;
|
||||
import com.bartlomiejpluta.base.engine.world.map.manager.MapManager;
|
||||
import com.bartlomiejpluta.base.engine.world.tileset.manager.TileSetManager;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class DefaultProjectLoader implements ProjectLoader {
|
||||
private final ProjectConfiguration configuration;
|
||||
private final ProjectDeserializer projectDeserializer;
|
||||
private final TileSetManager tileSetManager;
|
||||
private final MapManager mapManager;
|
||||
private final ImageManager imageManager;
|
||||
private final EntitySetManager entitySetManager;
|
||||
|
||||
@Override
|
||||
public Project loadProject() {
|
||||
var resource = DefaultProjectLoader.class.getResourceAsStream(configuration.projectFile(configuration.getMainFile()));
|
||||
var project = projectDeserializer.deserialize(resource);
|
||||
project.getTileSetAssets().forEach(tileSetManager::registerAsset);
|
||||
project.getMapAssets().forEach(mapManager::registerAsset);
|
||||
project.getImageAssets().forEach(imageManager::registerAsset);
|
||||
project.getEntitySetAssets().forEach(entitySetManager::registerAsset);
|
||||
|
||||
return project;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.bartlomiejpluta.base.engine.project.loader;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.project.model.Project;
|
||||
|
||||
public interface ProjectLoader {
|
||||
Project loadProject();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.bartlomiejpluta.base.engine.project.model;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.world.entity.asset.EntitySetAsset;
|
||||
import com.bartlomiejpluta.base.engine.world.image.asset.ImageAsset;
|
||||
import com.bartlomiejpluta.base.engine.world.map.asset.GameMapAsset;
|
||||
import com.bartlomiejpluta.base.engine.world.tileset.asset.TileSetAsset;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class Project {
|
||||
|
||||
@NonNull
|
||||
private final String name;
|
||||
|
||||
@NonNull
|
||||
private final String runner;
|
||||
|
||||
@NonNull
|
||||
private final List<TileSetAsset> tileSetAssets;
|
||||
|
||||
@NonNull
|
||||
private final List<GameMapAsset> mapAssets;
|
||||
|
||||
@NonNull
|
||||
private final List<ImageAsset> imageAssets;
|
||||
|
||||
@NonNull
|
||||
private final List<EntitySetAsset> entitySetAssets;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.bartlomiejpluta.base.engine.project.model;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||
import com.bartlomiejpluta.base.api.input.Keyboard;
|
||||
import com.bartlomiejpluta.base.api.map.MapHandler;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.texture.TextureManager;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.render.Renderable;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.input.GLFWKeyboard;
|
||||
import com.bartlomiejpluta.base.engine.logic.Updatable;
|
||||
import com.bartlomiejpluta.base.engine.project.loader.ClassLoader;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.util.mesh.MeshManager;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.manager.EntityManager;
|
||||
import com.bartlomiejpluta.base.engine.world.image.manager.ImageManager;
|
||||
import com.bartlomiejpluta.base.engine.world.map.manager.MapManager;
|
||||
import com.bartlomiejpluta.base.engine.world.map.model.DefaultGameMap;
|
||||
import com.bartlomiejpluta.base.engine.world.tileset.manager.TileSetManager;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.joml.Vector2f;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class RenderableContext implements Context, Updatable, Renderable {
|
||||
private final TileSetManager tileSetManager;
|
||||
private final MeshManager meshManager;
|
||||
private final TextureManager textureManager;
|
||||
private final EntityManager entityManager;
|
||||
private final ImageManager imageManager;
|
||||
private final MapManager mapManager;
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
private Keyboard keyboard;
|
||||
private DefaultGameMap map;
|
||||
private MapHandler mapHandler;
|
||||
|
||||
private Camera camera;
|
||||
|
||||
public void init(Window window, Camera camera) {
|
||||
this.keyboard = new GLFWKeyboard(window);
|
||||
this.camera = camera;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@Override
|
||||
public void openMap(String mapUid) {
|
||||
map = mapManager.loadObject(mapUid);
|
||||
|
||||
var handlerClass = classLoader.<MapHandler>loadClass(map.getHandler());
|
||||
mapHandler = handlerClass.getConstructor().newInstance();
|
||||
|
||||
mapHandler.init(this, map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Entity createEntity(String entitySetUid) {
|
||||
return entityManager.createEntity(entitySetUid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCameraPosition(Vector2f position) {
|
||||
camera.setPosition(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCameraPosition(float x, float y) {
|
||||
camera.setPosition(x, y);
|
||||
}
|
||||
|
||||
public void input() {
|
||||
mapHandler.input(keyboard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
if (mapHandler != null) {
|
||||
mapHandler.update(this, map, dt);
|
||||
}
|
||||
|
||||
if (map != null) {
|
||||
map.update(dt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Window window, Camera camera, ShaderManager shaderManager) {
|
||||
if (map != null) {
|
||||
map.render(window, camera, shaderManager);
|
||||
}
|
||||
|
||||
if (mapHandler != null) {
|
||||
mapHandler.postRender(window.getWidth(), window.getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.bartlomiejpluta.base.engine.project.serial;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.common.serial.Deserializer;
|
||||
import com.bartlomiejpluta.base.engine.project.model.Project;
|
||||
|
||||
public abstract class ProjectDeserializer extends Deserializer<Project> {
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.bartlomiejpluta.base.engine.project.serial;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.project.model.Project;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.asset.EntitySetAsset;
|
||||
import com.bartlomiejpluta.base.engine.world.image.asset.ImageAsset;
|
||||
import com.bartlomiejpluta.base.engine.world.map.asset.GameMapAsset;
|
||||
import com.bartlomiejpluta.base.engine.world.tileset.asset.TileSetAsset;
|
||||
import com.bartlomiejpluta.base.proto.ProjectProto;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
@Component
|
||||
public class ProtobufProjectDeserializer extends ProjectDeserializer {
|
||||
|
||||
@Override
|
||||
protected Project parse(InputStream input) throws Exception {
|
||||
var proto = ProjectProto.Project.parseFrom(input);
|
||||
var name = proto.getName();
|
||||
var runner = proto.getRunner();
|
||||
var tileSetAssets = proto.getTileSetsList().stream().map(this::parseTileSetAsset).collect(toList());
|
||||
var mapAssets = proto.getMapsList().stream().map(this::parseGameMapAsset).collect(toList());
|
||||
var imageAssets = proto.getImagesList().stream().map(this::parseImageAsset).collect(toList());
|
||||
var entitySetAssets = proto.getEntitySetsList().stream().map(this::parseEntitySetAsset).collect(toList());
|
||||
|
||||
return new Project(name, runner, tileSetAssets, mapAssets, imageAssets, entitySetAssets);
|
||||
}
|
||||
|
||||
private TileSetAsset parseTileSetAsset(ProjectProto.TileSetAsset proto) {
|
||||
return new TileSetAsset(proto.getUid(), proto.getSource(), proto.getRows(), proto.getColumns());
|
||||
}
|
||||
|
||||
private GameMapAsset parseGameMapAsset(ProjectProto.GameMapAsset proto) {
|
||||
return new GameMapAsset(proto.getUid(), proto.getSource());
|
||||
}
|
||||
|
||||
private ImageAsset parseImageAsset(ProjectProto.ImageAsset proto) {
|
||||
return new ImageAsset(proto.getUid(), proto.getSource());
|
||||
}
|
||||
|
||||
private EntitySetAsset parseEntitySetAsset(ProjectProto.EntitySetAsset proto) {
|
||||
return new EntitySetAsset(proto.getUid(), proto.getSource(), proto.getRows(), proto.getColumns());
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.thread;
|
||||
package com.bartlomiejpluta.base.engine.thread;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.time;
|
||||
package com.bartlomiejpluta.base.engine.time;
|
||||
|
||||
public class ChronoMeter {
|
||||
private double latchedTime;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.bartlomiejpluta.base.core.ui;
|
||||
package com.bartlomiejpluta.base.engine.ui;
|
||||
|
||||
import com.bartlomiejpluta.base.core.error.AppException;
|
||||
import com.bartlomiejpluta.base.engine.error.AppException;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.ui;
|
||||
package com.bartlomiejpluta.base.engine.ui;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.util.math;
|
||||
package com.bartlomiejpluta.base.engine.util.math;
|
||||
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.min;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.bartlomiejpluta.base.core.util.mesh;
|
||||
package com.bartlomiejpluta.base.engine.util.mesh;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gl.object.mesh.Mesh;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.joml.Vector2f;
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.bartlomiejpluta.base.engine.util.mesh;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh;
|
||||
import com.bartlomiejpluta.base.engine.gc.Cleanable;
|
||||
|
||||
public interface MeshManager extends Cleanable {
|
||||
Mesh createQuad(float width, float height, float originX, float originY);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.bartlomiejpluta.base.engine.util.profiling.fps;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.engine.logic.Updatable;
|
||||
|
||||
public interface FPSMonitor extends Updatable, Cleanable {
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.profiling.fps;
|
||||
package com.bartlomiejpluta.base.engine.util.profiling.fps;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.bartlomiejpluta.base.core.profiling.time;
|
||||
package com.bartlomiejpluta.base.engine.util.profiling.time;
|
||||
|
||||
import com.bartlomiejpluta.base.core.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.engine.gc.Cleanable;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.profiling.time;
|
||||
package com.bartlomiejpluta.base.engine.util.profiling.time;
|
||||
|
||||
public interface TimeProfilerService {
|
||||
void measure(String key, Runnable task);
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.bartlomiejpluta.base.core.util.res;
|
||||
package com.bartlomiejpluta.base.engine.util.res;
|
||||
|
||||
import com.bartlomiejpluta.base.core.error.AppException;
|
||||
import com.bartlomiejpluta.base.engine.error.AppException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.bartlomiejpluta.base.engine.world.animation;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.material.Material;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
import com.bartlomiejpluta.base.engine.world.object.Sprite;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.joml.Vector2f;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public abstract class AnimatedSprite extends Sprite {
|
||||
|
||||
public AnimatedSprite(Mesh mesh, Material material) {
|
||||
super(mesh, material);
|
||||
}
|
||||
|
||||
// Returns time in ms between frames
|
||||
public abstract int getAnimationSpeed();
|
||||
|
||||
public abstract boolean shouldAnimate();
|
||||
|
||||
public abstract Vector2f[] getSpriteAnimationFramesPositions();
|
||||
|
||||
@Override
|
||||
public void render(Window window, Camera camera, ShaderManager shaderManager) {
|
||||
animate();
|
||||
super.render(window, camera, shaderManager);
|
||||
}
|
||||
|
||||
private void animate() {
|
||||
if (shouldAnimate()) {
|
||||
var positions = getSpriteAnimationFramesPositions();
|
||||
var delay = getAnimationSpeed();
|
||||
var currentPosition = (int) (System.currentTimeMillis() % (positions.length * delay)) / delay;
|
||||
var current = positions[currentPosition];
|
||||
material.setSpritePosition(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.bartlomiejpluta.base.core.world.camera;
|
||||
package com.bartlomiejpluta.base.engine.world.camera;
|
||||
|
||||
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.object.Model;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.constant.UniformName;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.world.object.Model;
|
||||
import org.joml.Matrix4f;
|
||||
|
||||
public class Camera extends Model {
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.bartlomiejpluta.base.engine.world.entity.asset;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.common.asset.Asset;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
@Getter
|
||||
public class EntitySetAsset extends Asset {
|
||||
private final int rows;
|
||||
private final int columns;
|
||||
|
||||
public EntitySetAsset(@NonNull String uid, @NonNull String source, int rows, int columns) {
|
||||
super(uid, source);
|
||||
this.rows = rows;
|
||||
this.columns = columns;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.bartlomiejpluta.base.engine.world.entity.config;
|
||||
|
||||
import com.bartlomiejpluta.base.api.entity.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.bartlomiejpluta.base.engine.world.entity.manager;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.material.Material;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh;
|
||||
import com.bartlomiejpluta.base.engine.util.mesh.MeshManager;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.config.EntitySpriteConfiguration;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.model.DefaultEntity;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class DefaultEntityManager implements EntityManager {
|
||||
private final MeshManager meshManager;
|
||||
private final EntitySetManager entitySetManager;
|
||||
private final EntitySpriteConfiguration configuration;
|
||||
|
||||
@Override
|
||||
public DefaultEntity createEntity(String entitySetUid) {
|
||||
var material = entitySetManager.loadObject(entitySetUid);
|
||||
return new DefaultEntity(buildMesh(material), material, 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*0.9f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp() {
|
||||
log.info("There is nothing to clean up here");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.bartlomiejpluta.base.engine.world.entity.manager;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.material.Material;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.texture.TextureManager;
|
||||
import com.bartlomiejpluta.base.engine.error.AppException;
|
||||
import com.bartlomiejpluta.base.engine.project.config.ProjectConfiguration;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.asset.EntitySetAsset;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class DefaultEntitySetManager implements EntitySetManager {
|
||||
private final TextureManager textureManager;
|
||||
private final Map<String, EntitySetAsset> assets = new HashMap<>();
|
||||
private final ProjectConfiguration configuration;
|
||||
|
||||
@Override
|
||||
public void registerAsset(EntitySetAsset asset) {
|
||||
log.info("Registering [{}] entity set asset under UID: [{}]", asset.getSource(), asset.getUid());
|
||||
assets.put(asset.getUid(), asset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material loadObject(String uid) {
|
||||
var asset = assets.get(uid);
|
||||
|
||||
if (asset == null) {
|
||||
throw new AppException("The entity set asset with UID: [%s] does not exist", uid);
|
||||
}
|
||||
|
||||
var source = configuration.projectFile("entsets", asset.getSource());
|
||||
var texture = textureManager.loadTexture(source, asset.getRows(), asset.getColumns());
|
||||
|
||||
return Material.textured(texture);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.bartlomiejpluta.base.engine.world.entity.manager;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.model.DefaultEntity;
|
||||
|
||||
public interface EntityManager extends Cleanable {
|
||||
DefaultEntity createEntity(String entitySetUid);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.bartlomiejpluta.base.engine.world.entity.manager;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.common.manager.AssetManager;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.material.Material;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.asset.EntitySetAsset;
|
||||
|
||||
public interface EntitySetManager extends AssetManager<EntitySetAsset, Material> {
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.bartlomiejpluta.base.engine.world.entity.model;
|
||||
|
||||
import com.bartlomiejpluta.base.api.entity.Direction;
|
||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.material.Material;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh;
|
||||
import com.bartlomiejpluta.base.engine.util.math.MathUtil;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.config.EntitySpriteConfiguration;
|
||||
import com.bartlomiejpluta.base.engine.world.movement.MovableSprite;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.joml.Vector2f;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DefaultEntity extends MovableSprite implements Entity {
|
||||
private final Map<Direction, Integer> spriteDirectionRows;
|
||||
private final int defaultSpriteColumn;
|
||||
|
||||
private int animationSpeed = 100;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private Direction faceDirection;
|
||||
|
||||
@Override
|
||||
public int getAnimationSpeed() {
|
||||
return animationSpeed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldAnimate() {
|
||||
return isMoving();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2f[] getSpriteAnimationFramesPositions() {
|
||||
var row = spriteDirectionRows.get(faceDirection);
|
||||
var frames = material.getTexture().getRows();
|
||||
var array = new Vector2f[frames];
|
||||
|
||||
for (int column = 0; column < frames; ++column) {
|
||||
array[column] = new Vector2f(column, row);
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setDefaultAnimationFrame() {
|
||||
material.setSpritePosition(new Vector2f(defaultSpriteColumn, spriteDirectionRows.get(faceDirection)));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean move(Direction direction) {
|
||||
if (super.move(direction)) {
|
||||
faceDirection = direction;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpeed(float speed) {
|
||||
framesToCrossOneTile = (int) (1 / MathUtil.clamp(speed, Float.MIN_VALUE, 1.0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAnimationSpeed(float speed) {
|
||||
animationSpeed = (int) (1 / MathUtil.clamp(speed, Float.MIN_VALUE, 1.0));
|
||||
}
|
||||
|
||||
public DefaultEntity(Mesh mesh, Material material, EntitySpriteConfiguration configuration) {
|
||||
super(mesh, material);
|
||||
this.defaultSpriteColumn = configuration.getDefaultSpriteColumn();
|
||||
this.spriteDirectionRows = configuration.getSpriteDirectionRows();
|
||||
this.faceDirection = Direction.DOWN;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.bartlomiejpluta.base.engine.world.image.asset;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.common.asset.Asset;
|
||||
import lombok.NonNull;
|
||||
|
||||
public class ImageAsset extends Asset {
|
||||
public ImageAsset(@NonNull String uid, @NonNull String source) {
|
||||
super(uid, source);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.bartlomiejpluta.base.engine.world.image.manager;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.material.Material;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.texture.TextureManager;
|
||||
import com.bartlomiejpluta.base.engine.error.AppException;
|
||||
import com.bartlomiejpluta.base.engine.project.config.ProjectConfiguration;
|
||||
import com.bartlomiejpluta.base.engine.util.math.MathUtil;
|
||||
import com.bartlomiejpluta.base.engine.util.mesh.MeshManager;
|
||||
import com.bartlomiejpluta.base.engine.world.image.asset.ImageAsset;
|
||||
import com.bartlomiejpluta.base.engine.world.image.model.Image;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class DefaultImageManager implements ImageManager {
|
||||
private final MeshManager meshManager;
|
||||
private final TextureManager textureManager;
|
||||
private final Map<String, ImageAsset> assets = new HashMap<>();
|
||||
private final ProjectConfiguration configuration;
|
||||
|
||||
|
||||
@Override
|
||||
public void registerAsset(ImageAsset asset) {
|
||||
log.info("Registering [{}] image asset under UID: [{}]", asset.getSource(), asset.getUid());
|
||||
assets.put(asset.getUid(), asset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image loadObject(String uid) {
|
||||
var asset = assets.get(uid);
|
||||
|
||||
if (asset == null) {
|
||||
throw new AppException("The image asset with UID: [%s] does not exist", uid);
|
||||
}
|
||||
|
||||
var source = configuration.projectFile("images", asset.getSource());
|
||||
var texture = textureManager.loadTexture(source);
|
||||
var width = texture.getWidth();
|
||||
var height = texture.getHeight();
|
||||
var gcd = MathUtil.gcdEuclidean(width, height);
|
||||
var initialWidth = width / gcd;
|
||||
var initialHeight = height / gcd;
|
||||
var mesh = meshManager.createQuad(initialWidth, initialHeight, 0, 0);
|
||||
var material = Material.textured(texture);
|
||||
log.info("Creating new image on asset with UID: [{}]", uid);
|
||||
|
||||
return new Image(mesh, material, initialWidth, initialHeight, gcd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp() {
|
||||
log.info("There is nothing to clean up here");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.bartlomiejpluta.base.engine.world.image.manager;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.common.manager.AssetManager;
|
||||
import com.bartlomiejpluta.base.engine.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.engine.world.image.asset.ImageAsset;
|
||||
import com.bartlomiejpluta.base.engine.world.image.model.Image;
|
||||
|
||||
public interface ImageManager extends AssetManager<ImageAsset, Image>, Cleanable {
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.bartlomiejpluta.base.engine.world.image.model;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.material.Material;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh;
|
||||
import com.bartlomiejpluta.base.engine.world.object.Sprite;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class Image extends Sprite {
|
||||
private final int initialWidth;
|
||||
private final int initialHeight;
|
||||
private final int gcd;
|
||||
|
||||
public Image(Mesh mesh, Material texture, int initialWidth, int initialHeight, int gcd) {
|
||||
super(mesh, texture);
|
||||
this.initialWidth = initialWidth;
|
||||
this.initialHeight = initialHeight;
|
||||
this.gcd = gcd;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.bartlomiejpluta.base.engine.world.map.asset;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.common.asset.Asset;
|
||||
import lombok.NonNull;
|
||||
|
||||
public class GameMapAsset extends Asset {
|
||||
public GameMapAsset(@NonNull String uid, @NonNull String source) {
|
||||
super(uid, source);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.bartlomiejpluta.base.engine.world.map.layer.base;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.render.Renderable;
|
||||
import com.bartlomiejpluta.base.engine.logic.Updatable;
|
||||
|
||||
public interface Layer extends Renderable, Updatable {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.bartlomiejpluta.base.engine.world.map.layer.color;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.material.Material;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.util.mesh.MeshManager;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
import com.bartlomiejpluta.base.engine.world.map.layer.base.Layer;
|
||||
import com.bartlomiejpluta.base.engine.world.map.model.DefaultGameMap;
|
||||
import com.bartlomiejpluta.base.engine.world.object.Sprite;
|
||||
import lombok.NonNull;
|
||||
|
||||
public class ColorLayer extends Sprite implements Layer {
|
||||
private final float mapWidth;
|
||||
private final float mapHeight;
|
||||
|
||||
public ColorLayer(@NonNull MeshManager meshManager, @NonNull DefaultGameMap map, float r, float g, float b, float alpha) {
|
||||
super(meshManager.createQuad(1, 1, 0, 0), Material.colored(r, g, b, alpha));
|
||||
this.mapWidth = map.getWidth();
|
||||
this.mapHeight = map.getHeight();
|
||||
setScale(mapWidth, mapHeight);
|
||||
}
|
||||
|
||||
public void setColor(float r, float g, float b, float alpha) {
|
||||
material.setColor(r, g, b, alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Window window, Camera camera, ShaderManager shaderManager) {
|
||||
super.render(window, camera, shaderManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.bartlomiejpluta.base.engine.world.map.layer.image;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
import com.bartlomiejpluta.base.engine.world.image.model.Image;
|
||||
import com.bartlomiejpluta.base.engine.world.map.layer.base.Layer;
|
||||
import com.bartlomiejpluta.base.engine.world.map.model.DefaultGameMap;
|
||||
import lombok.NonNull;
|
||||
|
||||
public class ImageLayer implements Layer {
|
||||
private final float mapWidth;
|
||||
private final float mapHeight;
|
||||
|
||||
@NonNull
|
||||
private Image image;
|
||||
private float imageInitialWidth;
|
||||
private float imageInitialHeight;
|
||||
private float gcd;
|
||||
|
||||
private float x;
|
||||
private float y;
|
||||
private float scaleX;
|
||||
private float scaleY;
|
||||
|
||||
@NonNull
|
||||
private ImageLayerMode mode;
|
||||
|
||||
private boolean parallax;
|
||||
|
||||
public ImageLayer(DefaultGameMap map, Image image, float opacity, float x, float y, float scaleX, float scaleY, ImageLayerMode mode, boolean parallax) {
|
||||
this.mapWidth = map.getWidth();
|
||||
this.mapHeight = map.getHeight();
|
||||
|
||||
this.image = image;
|
||||
this.imageInitialWidth = image.getInitialWidth();
|
||||
this.imageInitialHeight = image.getInitialHeight();
|
||||
this.gcd = image.getGcd();
|
||||
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.scaleX = scaleX;
|
||||
this.scaleY = scaleY;
|
||||
this.mode = mode;
|
||||
this.parallax = parallax;
|
||||
|
||||
this.image.getMaterial().setAlpha(opacity);
|
||||
this.image.setPosition(x, y);
|
||||
|
||||
switch (mode) {
|
||||
case NORMAL -> image.setScale(mapWidth / imageInitialWidth, mapHeight / imageInitialHeight);
|
||||
case FIT_MAP -> image.setScale(image.getGcd() * imageInitialWidth * scaleX, image.getGcd() * imageInitialHeight * scaleY);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render(Window window, Camera camera, ShaderManager shaderManager) {
|
||||
if (image != null) {
|
||||
if (parallax) {
|
||||
var cameraPosition = camera.getPosition();
|
||||
image.setPosition(cameraPosition.x + x, cameraPosition.y + y);
|
||||
}
|
||||
|
||||
if (mode == ImageLayerMode.FIT_SCREEN) {
|
||||
image.setScale(window.getWidth() / imageInitialWidth, window.getHeight() / imageInitialHeight);
|
||||
}
|
||||
|
||||
image.render(window, camera, shaderManager);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.bartlomiejpluta.base.engine.world.map.layer.image;
|
||||
|
||||
public enum ImageLayerMode {
|
||||
NORMAL,
|
||||
FIT_MAP,
|
||||
FIT_SCREEN
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.bartlomiejpluta.base.engine.world.map.layer.object;
|
||||
|
||||
import com.bartlomiejpluta.base.api.entity.Direction;
|
||||
import com.bartlomiejpluta.base.api.map.PassageAbility;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
import com.bartlomiejpluta.base.engine.world.map.layer.base.Layer;
|
||||
import com.bartlomiejpluta.base.engine.world.movement.MovableSprite;
|
||||
import org.joml.Vector2i;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ObjectLayer implements Layer {
|
||||
private final List<MovableSprite> objects;
|
||||
|
||||
private final PassageAbility[][] passageMap;
|
||||
|
||||
public ObjectLayer(List<MovableSprite> objects, PassageAbility[][] passageMap) {
|
||||
this.objects = objects;
|
||||
this.passageMap = passageMap;
|
||||
}
|
||||
|
||||
public void addObject(MovableSprite object) {
|
||||
objects.add(object);
|
||||
}
|
||||
|
||||
public void removeObject(MovableSprite 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, Camera camera, ShaderManager shaderManager) {
|
||||
objects.sort(this::compareObjects);
|
||||
|
||||
for (var object : objects) {
|
||||
object.render(window, camera, shaderManager);
|
||||
}
|
||||
}
|
||||
|
||||
private int compareObjects(MovableSprite a, MovableSprite b) {
|
||||
return Float.compare(a.getPosition().y, b.getPosition().y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
for (var object : objects) {
|
||||
object.update(dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.bartlomiejpluta.base.engine.world.map.layer.tile;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
import com.bartlomiejpluta.base.engine.world.map.layer.base.Layer;
|
||||
import com.bartlomiejpluta.base.engine.world.tileset.model.Tile;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class TileLayer implements Layer {
|
||||
private final Tile[][] layer;
|
||||
private final int rows;
|
||||
private final int columns;
|
||||
|
||||
public TileLayer(int rows, int columns) {
|
||||
this.rows = rows;
|
||||
this.columns = columns;
|
||||
layer = new Tile[rows][columns];
|
||||
Arrays.stream(layer).forEach(tiles -> Arrays.fill(tiles, null));
|
||||
}
|
||||
|
||||
public void setTile(int row, int column, Tile tile) {
|
||||
layer[row][column] = tile;
|
||||
|
||||
if(tile != null) {
|
||||
tile.setCoordinates(row, column);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Window window, Camera camera, ShaderManager shaderManager) {
|
||||
for (var row : layer) {
|
||||
for (var tile : row) {
|
||||
if (tile != null) {
|
||||
tile.render(window, camera, shaderManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.bartlomiejpluta.base.engine.world.map.manager;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.error.AppException;
|
||||
import com.bartlomiejpluta.base.engine.project.config.ProjectConfiguration;
|
||||
import com.bartlomiejpluta.base.engine.world.map.asset.GameMapAsset;
|
||||
import com.bartlomiejpluta.base.engine.world.map.model.DefaultGameMap;
|
||||
import com.bartlomiejpluta.base.engine.world.map.serial.MapDeserializer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class DefaultMapManager implements MapManager {
|
||||
private final Map<String, DefaultGameMap> maps = new HashMap<>();
|
||||
private final Map<String, GameMapAsset> assets = new HashMap<>();
|
||||
private final MapDeserializer mapDeserializer;
|
||||
private final ProjectConfiguration configuration;
|
||||
|
||||
@Override
|
||||
public void registerAsset(GameMapAsset asset) {
|
||||
log.info("Registering [{}] map asset under UID: [{}]", asset.getSource(), asset.getUid());
|
||||
assets.put(asset.getUid(), asset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultGameMap loadObject(String uid) {
|
||||
var map = maps.get(uid);
|
||||
|
||||
if (map == null) {
|
||||
var asset = assets.get(uid);
|
||||
|
||||
if (asset == null) {
|
||||
throw new AppException("The map asset with UID: [%s] does not exist", uid);
|
||||
}
|
||||
|
||||
var source = configuration.projectFile("maps", asset.getSource());
|
||||
map = mapDeserializer.deserialize(DefaultMapManager.class.getResourceAsStream(source));
|
||||
log.info("Loading map from assets to cache under the key: [{}]", uid);
|
||||
maps.put(uid, map);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp() {
|
||||
log.info("There is nothing to clean up here");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.bartlomiejpluta.base.engine.world.map.manager;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.common.manager.AssetManager;
|
||||
import com.bartlomiejpluta.base.engine.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.engine.world.map.asset.GameMapAsset;
|
||||
import com.bartlomiejpluta.base.engine.world.map.model.DefaultGameMap;
|
||||
|
||||
public interface MapManager extends AssetManager<GameMapAsset, DefaultGameMap>, Cleanable {
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package com.bartlomiejpluta.base.engine.world.map.model;
|
||||
|
||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||
import com.bartlomiejpluta.base.api.entity.Movement;
|
||||
import com.bartlomiejpluta.base.api.map.GameMap;
|
||||
import com.bartlomiejpluta.base.api.map.PassageAbility;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.render.Renderable;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.logic.Updatable;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.util.mesh.MeshManager;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
import com.bartlomiejpluta.base.engine.world.entity.model.DefaultEntity;
|
||||
import com.bartlomiejpluta.base.engine.world.image.model.Image;
|
||||
import com.bartlomiejpluta.base.engine.world.map.layer.base.Layer;
|
||||
import com.bartlomiejpluta.base.engine.world.map.layer.color.ColorLayer;
|
||||
import com.bartlomiejpluta.base.engine.world.map.layer.image.ImageLayer;
|
||||
import com.bartlomiejpluta.base.engine.world.map.layer.image.ImageLayerMode;
|
||||
import com.bartlomiejpluta.base.engine.world.map.layer.object.ObjectLayer;
|
||||
import com.bartlomiejpluta.base.engine.world.map.layer.tile.TileLayer;
|
||||
import com.bartlomiejpluta.base.engine.world.tileset.model.TileSet;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import org.joml.Vector2f;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultGameMap implements Renderable, Updatable, GameMap {
|
||||
@Getter
|
||||
private final List<Layer> layers = new ArrayList<>();
|
||||
|
||||
@NonNull
|
||||
private final TileSet tileSet;
|
||||
|
||||
@Getter
|
||||
private final int rows;
|
||||
|
||||
@Getter
|
||||
private final int columns;
|
||||
|
||||
@Getter
|
||||
private final float width;
|
||||
|
||||
@Getter
|
||||
private final float height;
|
||||
|
||||
@Getter
|
||||
private final Vector2f stepSize;
|
||||
|
||||
@Getter
|
||||
private final String handler;
|
||||
|
||||
public DefaultGameMap(TileSet tileSet, int rows, int columns, String handler) {
|
||||
this.tileSet = tileSet;
|
||||
this.rows = rows;
|
||||
this.columns = columns;
|
||||
this.stepSize = new Vector2f(tileSet.getTileSet().getSpriteSize());
|
||||
this.width = columns * stepSize.x;
|
||||
this.height = rows * stepSize.y;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Window window, Camera camera, ShaderManager shaderManager) {
|
||||
for (var layer : layers) {
|
||||
layer.render(window, camera, shaderManager);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
for (var layer : layers) {
|
||||
layer.update(dt);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2f getSize() {
|
||||
return new Vector2f(columns * stepSize.x, rows * stepSize.y);
|
||||
}
|
||||
|
||||
public int createObjectLayer() {
|
||||
var passageMap = new PassageAbility[rows][columns];
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
Arrays.fill(passageMap[i], 0, columns, PassageAbility.ALLOW);
|
||||
}
|
||||
|
||||
layers.add(new ObjectLayer(new ArrayList<>(), passageMap));
|
||||
|
||||
return layers.size() - 1;
|
||||
}
|
||||
|
||||
public int createTileLayer() {
|
||||
layers.add(new TileLayer(rows, columns));
|
||||
|
||||
return layers.size() - 1;
|
||||
}
|
||||
|
||||
public int createColorLayer(MeshManager meshManager, float r, float g, float b, float alpha) {
|
||||
layers.add(new ColorLayer(meshManager, this, r, g, b, alpha));
|
||||
|
||||
return layers.size() - 1;
|
||||
}
|
||||
|
||||
public int createImageLayer(Image image, float opacity, float x, float y, float scaleX, float scaleY, ImageLayerMode mode, boolean parallax) {
|
||||
layers.add(new ImageLayer(this, image, opacity, x, y, scaleX, scaleY, mode, parallax));
|
||||
|
||||
return layers.size() - 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addEntity(int objectLayerIndex, Entity entity) {
|
||||
var object = (DefaultEntity) entity;
|
||||
object.setStepSize(stepSize.x, stepSize.y);
|
||||
|
||||
((ObjectLayer) layers.get(objectLayerIndex)).addObject(object);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeEntity(int objectLayerIndex, Entity entity) {
|
||||
((ObjectLayer) layers.get(objectLayerIndex)).removeObject((DefaultEntity) entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTile(int tileLayerIndex, int row, int column, int tileId) {
|
||||
((TileLayer) layers.get(tileLayerIndex)).setTile(row, column, tileSet.tileById(tileId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTile(int tileLayerIndex, int row, int column, int tileSetRow, int tileSetColumn) {
|
||||
((TileLayer) layers.get(tileLayerIndex)).setTile(row, column, tileSet.tileAt(tileSetRow, tileSetColumn));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearTile(int tileLayerIndex, int row, int column) {
|
||||
((TileLayer) layers.get(tileLayerIndex)).setTile(row, column, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPassageAbility(int objectLayerIndex, int row, int column, PassageAbility passageAbility) {
|
||||
((ObjectLayer) layers.get(objectLayerIndex)).setPassageAbility(row, column, passageAbility);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColor(int colorLayerIndex, float r, float g, float b, float alpha) {
|
||||
((ColorLayer) layers.get(colorLayerIndex)).setColor(r, g, b, alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMovementPossible(int objectLayerIndex, Movement movement) {
|
||||
var target = movement.getTo();
|
||||
|
||||
// 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.getFrom();
|
||||
var direction = movement.getDirection();
|
||||
|
||||
return ((ObjectLayer) layers.get(objectLayerIndex)).isMovementPossible(source, target, direction);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.bartlomiejpluta.base.engine.world.map.serial;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.common.serial.Deserializer;
|
||||
import com.bartlomiejpluta.base.engine.world.map.model.DefaultGameMap;
|
||||
|
||||
public abstract class MapDeserializer extends Deserializer<DefaultGameMap> {
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.bartlomiejpluta.base.engine.world.map.serial;
|
||||
|
||||
import com.bartlomiejpluta.base.api.map.PassageAbility;
|
||||
import com.bartlomiejpluta.base.engine.error.AppException;
|
||||
import com.bartlomiejpluta.base.engine.util.mesh.MeshManager;
|
||||
import com.bartlomiejpluta.base.engine.world.image.manager.ImageManager;
|
||||
import com.bartlomiejpluta.base.engine.world.map.layer.image.ImageLayerMode;
|
||||
import com.bartlomiejpluta.base.engine.world.map.model.DefaultGameMap;
|
||||
import com.bartlomiejpluta.base.engine.world.tileset.manager.TileSetManager;
|
||||
import com.bartlomiejpluta.base.proto.GameMapProto;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class ProtobufMapDeserializer extends MapDeserializer {
|
||||
private final MeshManager meshManager;
|
||||
private final TileSetManager tileSetManager;
|
||||
private final ImageManager imageManager;
|
||||
|
||||
@Override
|
||||
protected DefaultGameMap parse(InputStream input) throws Exception {
|
||||
var proto = GameMapProto.GameMap.parseFrom(input);
|
||||
var tileSet = tileSetManager.loadObject(proto.getTileSetUID());
|
||||
var map = new DefaultGameMap(tileSet, proto.getRows(), proto.getColumns(), proto.getHandler());
|
||||
|
||||
proto.getLayersList().forEach(layer -> deserializeLayer(map, layer));
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private void deserializeLayer(DefaultGameMap map, GameMapProto.Layer proto) {
|
||||
if (proto.hasTileLayer()) {
|
||||
deserializeTileLayer(map, proto);
|
||||
} else if (proto.hasObjectLayer()) {
|
||||
deserializeObjectLayer(map, proto);
|
||||
} else if (proto.hasColorLayer()) {
|
||||
deserializeColorLayer(map, proto);
|
||||
} else if (proto.hasImageLayer()) {
|
||||
deserializeImageLayer(map, proto);
|
||||
} else {
|
||||
throw new AppException("Not supported layer type");
|
||||
}
|
||||
}
|
||||
|
||||
private void deserializeTileLayer(DefaultGameMap map, GameMapProto.Layer proto) {
|
||||
var layer = map.createTileLayer();
|
||||
var columns = map.getColumns();
|
||||
var tiles = proto.getTileLayer().getTilesList();
|
||||
|
||||
for (var i = 0; i < tiles.size(); ++i) {
|
||||
var tile = tiles.get(i);
|
||||
|
||||
if (tile == 0) {
|
||||
map.clearTile(layer, i / columns, i % columns);
|
||||
} else {
|
||||
map.setTile(layer, i / columns, i % columns, tile - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void deserializeObjectLayer(DefaultGameMap map, GameMapProto.Layer proto) {
|
||||
var layer = map.createObjectLayer();
|
||||
var columns = map.getColumns();
|
||||
var passageMap = proto.getObjectLayer().getPassageMapList();
|
||||
|
||||
for (var i = 0; i < passageMap.size(); ++i) {
|
||||
map.setPassageAbility(layer, i / columns, i % columns, switch (passageMap.get(i)) {
|
||||
case ALLOW -> PassageAbility.ALLOW;
|
||||
case BLOCK -> PassageAbility.BLOCK;
|
||||
case RIGHT_ONLY -> PassageAbility.RIGHT_ONLY;
|
||||
case LEFT_ONLY -> PassageAbility.LEFT_ONLY;
|
||||
case DOWN_ONLY -> PassageAbility.DOWN_ONLY;
|
||||
case UP_ONLY -> PassageAbility.UP_ONLY;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void deserializeColorLayer(DefaultGameMap map, GameMapProto.Layer proto) {
|
||||
var protoColorLayer = proto.getColorLayer();
|
||||
map.createColorLayer(
|
||||
meshManager,
|
||||
protoColorLayer.getRed() / 100.0f,
|
||||
protoColorLayer.getGreen() / 100.0f,
|
||||
protoColorLayer.getBlue() / 100.0f,
|
||||
protoColorLayer.getAlpha() / 100.0f
|
||||
);
|
||||
}
|
||||
|
||||
private void deserializeImageLayer(DefaultGameMap map, GameMapProto.Layer proto) {
|
||||
var protoImageLayer = proto.getImageLayer();
|
||||
var image = imageManager.loadObject(protoImageLayer.getImageUID());
|
||||
|
||||
var mode = switch (proto.getImageLayer().getMode()) {
|
||||
case NORMAL -> ImageLayerMode.NORMAL;
|
||||
case FIT_MAP -> ImageLayerMode.FIT_MAP;
|
||||
case FIT_SCREEN -> ImageLayerMode.FIT_SCREEN;
|
||||
};
|
||||
|
||||
map.createImageLayer(
|
||||
image,
|
||||
protoImageLayer.getOpacity() / 100.0f,
|
||||
protoImageLayer.getX(),
|
||||
protoImageLayer.getY(),
|
||||
(float) protoImageLayer.getScaleX(),
|
||||
(float) protoImageLayer.getScaleY(),
|
||||
mode,
|
||||
protoImageLayer.getParallax()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.bartlomiejpluta.base.engine.world.movement;
|
||||
|
||||
import com.bartlomiejpluta.base.api.entity.Direction;
|
||||
import com.bartlomiejpluta.base.api.entity.Movement;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.joml.Vector2i;
|
||||
|
||||
@Data
|
||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||
public class DefaultMovement implements Movement {
|
||||
private final MovableSprite object;
|
||||
private final Direction direction;
|
||||
private boolean performed = false;
|
||||
|
||||
@Override
|
||||
public boolean perform() {
|
||||
performed = object.move(direction);
|
||||
return performed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Movement another() {
|
||||
return object.prepareMovement(direction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2i getFrom() {
|
||||
return object.getCoordinates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector2i getTo() {
|
||||
return direction.asVector().add(object.getCoordinates());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.bartlomiejpluta.base.engine.world.movement;
|
||||
|
||||
import com.bartlomiejpluta.base.api.entity.Direction;
|
||||
import com.bartlomiejpluta.base.api.entity.Movement;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.material.Material;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh;
|
||||
import com.bartlomiejpluta.base.engine.logic.Updatable;
|
||||
import com.bartlomiejpluta.base.engine.world.animation.AnimatedSprite;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import org.joml.Vector2f;
|
||||
import org.joml.Vector2i;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public abstract class MovableSprite extends AnimatedSprite implements Updatable {
|
||||
private final Vector2f coordinateStepSize = new Vector2f(0, 0);
|
||||
|
||||
private int moveTime = 0;
|
||||
private Vector2f movementVector;
|
||||
|
||||
@Getter
|
||||
private final Vector2i coordinates = new Vector2i(0, 0);
|
||||
|
||||
protected int framesToCrossOneTile = 1;
|
||||
|
||||
public boolean isMoving() {
|
||||
return movementVector != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
if (movementVector != null) {
|
||||
if (moveTime > 0) {
|
||||
--moveTime;
|
||||
movePosition(movementVector);
|
||||
} else {
|
||||
adjustCoordinates();
|
||||
setDefaultAnimationFrame();
|
||||
movementVector = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void setDefaultAnimationFrame();
|
||||
|
||||
private void adjustCoordinates() {
|
||||
var position = new Vector2f(getPosition());
|
||||
setCoordinates(new Vector2i((int) (position.x / coordinateStepSize.x), (int) (position.y / coordinateStepSize.y)));
|
||||
}
|
||||
|
||||
public Movement prepareMovement(Direction direction) {
|
||||
return new DefaultMovement(this, direction);
|
||||
}
|
||||
|
||||
protected boolean move(Direction direction) {
|
||||
if (this.movementVector != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var speed = new Vector2f(coordinateStepSize).div(framesToCrossOneTile);
|
||||
movementVector = new Vector2f(direction.x, direction.y).mul(speed);
|
||||
moveTime = framesToCrossOneTile;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setCoordinates(int x, int y) {
|
||||
coordinates.x = x;
|
||||
coordinates.y = y;
|
||||
setPosition((x + 0.5f) * coordinateStepSize.x, (y + 0.5f) * coordinateStepSize.y);
|
||||
}
|
||||
|
||||
public void setCoordinates(Vector2i coordinates) {
|
||||
setCoordinates(coordinates.x, coordinates.y);
|
||||
}
|
||||
|
||||
public void setStepSize(float x, float y) {
|
||||
coordinateStepSize.x = x;
|
||||
coordinateStepSize.y = y;
|
||||
setCoordinates(coordinates);
|
||||
}
|
||||
|
||||
public MovableSprite(Mesh mesh, Material material) {
|
||||
super(mesh, material);
|
||||
setCoordinates(0, 0);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.bartlomiejpluta.base.core.world.object;
|
||||
package com.bartlomiejpluta.base.engine.world.object;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.bartlomiejpluta.base.core.world.object;
|
||||
package com.bartlomiejpluta.base.engine.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 com.bartlomiejpluta.base.core.world.camera.Camera;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.material.Material;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.render.Renderable;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.constant.UniformName;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.shader.manager.ShaderManager;
|
||||
import com.bartlomiejpluta.base.engine.ui.Window;
|
||||
import com.bartlomiejpluta.base.engine.world.camera.Camera;
|
||||
import lombok.*;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.bartlomiejpluta.base.engine.world.tileset.asset;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.common.asset.Asset;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
@Getter
|
||||
public class TileSetAsset extends Asset {
|
||||
private final int rows;
|
||||
private final int columns;
|
||||
|
||||
public TileSetAsset(@NonNull String uid, @NonNull String source, int rows, int columns) {
|
||||
super(uid, source);
|
||||
this.rows = rows;
|
||||
this.columns = columns;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.bartlomiejpluta.base.engine.world.tileset.manager;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.texture.TextureManager;
|
||||
import com.bartlomiejpluta.base.engine.error.AppException;
|
||||
import com.bartlomiejpluta.base.engine.project.config.ProjectConfiguration;
|
||||
import com.bartlomiejpluta.base.engine.util.mesh.MeshManager;
|
||||
import com.bartlomiejpluta.base.engine.world.tileset.asset.TileSetAsset;
|
||||
import com.bartlomiejpluta.base.engine.world.tileset.model.TileSet;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
|
||||
public class DefaultTileSetManager implements TileSetManager {
|
||||
private final TextureManager textureManager;
|
||||
private final MeshManager meshManager;
|
||||
private final Map<String, TileSet> tileSets = new HashMap<>();
|
||||
private final Map<String, TileSetAsset> assets = new HashMap<>();
|
||||
private final ProjectConfiguration configuration;
|
||||
|
||||
@Override
|
||||
public void registerAsset(TileSetAsset asset) {
|
||||
log.info("Registering [{}] tile set asset under UID: [{}]", asset.getSource(), asset.getUid());
|
||||
assets.put(asset.getUid(), asset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TileSet loadObject(String uid) {
|
||||
var tileset = tileSets.get(uid);
|
||||
|
||||
if (tileset == null) {
|
||||
var asset = assets.get(uid);
|
||||
|
||||
if (asset == null) {
|
||||
throw new AppException("The tile set asset with UID: [%s] does not exist", uid);
|
||||
}
|
||||
|
||||
var source = configuration.projectFile("tilesets", asset.getSource());
|
||||
var texture = textureManager.loadTexture(source, asset.getRows(), asset.getColumns());
|
||||
var size = texture.getSpriteSize();
|
||||
var mesh = meshManager.createQuad(size.x, size.y, 0, 0);
|
||||
tileset = new TileSet(texture, mesh);
|
||||
log.info("Loading tile set from assets to cache under the key: [{}]", uid);
|
||||
tileSets.put(uid, tileset);
|
||||
}
|
||||
|
||||
return tileset;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanUp() {
|
||||
log.info("There is nothing to clean up here");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.bartlomiejpluta.base.engine.world.tileset.manager;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.common.manager.AssetManager;
|
||||
import com.bartlomiejpluta.base.engine.gc.Cleanable;
|
||||
import com.bartlomiejpluta.base.engine.world.tileset.asset.TileSetAsset;
|
||||
import com.bartlomiejpluta.base.engine.world.tileset.model.TileSet;
|
||||
|
||||
public interface TileSetManager extends AssetManager<TileSetAsset, TileSet>, Cleanable {
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.bartlomiejpluta.base.engine.world.tileset.model;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.material.Material;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.texture.Texture;
|
||||
import com.bartlomiejpluta.base.engine.world.object.Sprite;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class Tile extends Sprite {
|
||||
private final int id;
|
||||
private final int tileSetRow;
|
||||
private final int tileSetColumn;
|
||||
|
||||
public Tile setCoordinates(int row, int column) {
|
||||
var stepSize = material.getTexture().getSpriteSize();
|
||||
setPosition(column * stepSize.x, row * stepSize.y);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Tile(Mesh mesh, Texture tileSet, int id) {
|
||||
super(mesh, Material.textured(tileSet));
|
||||
this.id = id;
|
||||
this.tileSetRow = id / tileSet.getColumns();
|
||||
this.tileSetColumn = id % tileSet.getColumns();
|
||||
material.setSpritePosition(tileSetColumn, tileSetRow);
|
||||
}
|
||||
|
||||
public Tile(Mesh mesh, Texture tileSet, int row, int column) {
|
||||
super(mesh, Material.textured(tileSet));
|
||||
this.tileSetRow = row;
|
||||
this.tileSetColumn = column;
|
||||
this.id = row * tileSet.getColumns() + column;
|
||||
material.setSpritePosition(tileSetColumn, tileSetRow);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.bartlomiejpluta.base.engine.world.tileset.model;
|
||||
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.mesh.Mesh;
|
||||
import com.bartlomiejpluta.base.engine.core.gl.object.texture.Texture;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class TileSet {
|
||||
private final Texture tileSet;
|
||||
private final Mesh mesh;
|
||||
|
||||
public Tile tileById(int id) {
|
||||
return new Tile(mesh, tileSet, id);
|
||||
}
|
||||
|
||||
public Tile tileAt(int row, int column) {
|
||||
return new Tile(mesh, tileSet, row, column);
|
||||
}
|
||||
}
|
||||
31
engine/src/main/resources/application.yml
Normal file
31
engine/src/main/resources/application.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
app:
|
||||
window:
|
||||
title: "Simple Game"
|
||||
width: 640
|
||||
height: 480
|
||||
|
||||
core:
|
||||
targetUps: 50 # Updates per second
|
||||
|
||||
project:
|
||||
main-file: project.bep
|
||||
resource-path: /project
|
||||
|
||||
sprite:
|
||||
entity:
|
||||
dimension:
|
||||
rows: 4
|
||||
cols: 4
|
||||
|
||||
default-sprite-column: 0
|
||||
|
||||
sprite-direction-rows:
|
||||
down: 0
|
||||
left: 1
|
||||
right: 2
|
||||
up: 3
|
||||
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.bartlomiejpluta.base.core.profiling.time.aspect.ExecutionTimeAspect: DEBUG
|
||||
Reference in New Issue
Block a user