diff --git a/res/textures.png b/res/textures.png index 8259941..eb12416 100644 Binary files a/res/textures.png and b/res/textures.png differ diff --git a/src/main/java/xyz/valnet/engine/App.java b/src/main/java/xyz/valnet/engine/App.java index 5f5f6ce..da322c6 100644 --- a/src/main/java/xyz/valnet/engine/App.java +++ b/src/main/java/xyz/valnet/engine/App.java @@ -19,7 +19,7 @@ public class App { // The window handle private long window; - private int width = 800, height = 450; + private int width = 1024, height = 576; private Matrix4f matrix = Matrix4f.orthographic(0, width, height, 0, 1, -1); public static int mouseX, mouseY; public static boolean mouseLeft, mouseMiddle, mouseRight; diff --git a/src/main/java/xyz/valnet/engine/graphics/Drawing.java b/src/main/java/xyz/valnet/engine/graphics/Drawing.java index 752e87b..00eacf7 100644 --- a/src/main/java/xyz/valnet/engine/graphics/Drawing.java +++ b/src/main/java/xyz/valnet/engine/graphics/Drawing.java @@ -6,37 +6,37 @@ import xyz.valnet.engine.shaders.SimpleShader; public class Drawing { - private static Texture bound = null; + private static Texture bound = null; - public static void drawSprite(Sprite sprite, int x, int y) { - drawSprite(sprite, x, y, sprite.width, sprite.height); + public static void drawSprite(Sprite sprite, int x, int y) { + drawSprite(sprite, x, y, sprite.width, sprite.height); + } + + private static float layer = 0f; + + public static void setLayer(float layer) { + Drawing.layer = layer; + } + + public static void drawSprite(Sprite sprite, int x, int y, int width, int height) { + // lazy texture binding + if(bound != sprite.atlas) { + if(bound != null) bound.unbind(); + sprite.atlas.bind(); } - private static float layer = 0f; + glBegin(GL_QUADS); + glVertexAttrib2f(SimpleShader.TEX_COORD, sprite.sourceBoxUV.x, sprite.sourceBoxUV.y); + glVertex3f(x, y, layer); - public static void setLayer(float layer) { - Drawing.layer = layer; - } + glVertexAttrib2f(SimpleShader.TEX_COORD, sprite.sourceBoxUV.x + sprite.sourceBoxUV.z, sprite.sourceBoxUV.y); + glVertex3f(x + width, y, layer); - public static void drawSprite(Sprite sprite, int x, int y, int width, int height) { - // lazy texture binding - if(bound != sprite.atlas) { - if(bound != null) bound.unbind(); - sprite.atlas.bind(); - } + glVertexAttrib2f(SimpleShader.TEX_COORD, sprite.sourceBoxUV.x + sprite.sourceBoxUV.z, sprite.sourceBoxUV.y + sprite.sourceBoxUV.w); + glVertex3f(x + width, y + height, layer); - glBegin(GL_QUADS); - glVertexAttrib2f(SimpleShader.TEX_COORD, sprite.sourceBoxUV.x, sprite.sourceBoxUV.y); - glVertex3f(x, y, layer); - - glVertexAttrib2f(SimpleShader.TEX_COORD, sprite.sourceBoxUV.x + sprite.sourceBoxUV.z, sprite.sourceBoxUV.y); - glVertex3f(x + width, y, layer); - - glVertexAttrib2f(SimpleShader.TEX_COORD, sprite.sourceBoxUV.x + sprite.sourceBoxUV.z, sprite.sourceBoxUV.y + sprite.sourceBoxUV.w); - glVertex3f(x + width, y + height, layer); - - glVertexAttrib2f(SimpleShader.TEX_COORD, sprite.sourceBoxUV.x, sprite.sourceBoxUV.y + sprite.sourceBoxUV.w); - glVertex3f(x, y + height, layer); - glEnd(); - } + glVertexAttrib2f(SimpleShader.TEX_COORD, sprite.sourceBoxUV.x, sprite.sourceBoxUV.y + sprite.sourceBoxUV.w); + glVertex3f(x, y + height, layer); + glEnd(); + } } \ No newline at end of file diff --git a/src/main/java/xyz/valnet/engine/math/Vector2f.java b/src/main/java/xyz/valnet/engine/math/Vector2f.java new file mode 100644 index 0000000..3a62e14 --- /dev/null +++ b/src/main/java/xyz/valnet/engine/math/Vector2f.java @@ -0,0 +1,17 @@ +package xyz.valnet.engine.math; + +public class Vector2f { + + public float x, y; + + public Vector2f() { + x = 0.0f; + y = 0.0f; + } + + public Vector2f(float x, float y) { + this.x = x; + this.y = y; + } + +} diff --git a/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java b/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java index 0c548f0..11671f2 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java @@ -18,4 +18,6 @@ public class GameObject implements IRenderable, ITickable { @Override public void tick(float dTime) {} + + public void start() {} } diff --git a/src/main/java/xyz/valnet/hadean/HadeanGame.java b/src/main/java/xyz/valnet/hadean/HadeanGame.java index 8d8cce3..c775375 100644 --- a/src/main/java/xyz/valnet/hadean/HadeanGame.java +++ b/src/main/java/xyz/valnet/hadean/HadeanGame.java @@ -39,7 +39,7 @@ public class HadeanGame extends Game { Assets.font.drawString("FPS: " + Math.round(averageFPS) + "/" + measuredFPS + " | AVG/MEASURED", 1, 1); Assets.font.drawString("Mouse: <" + App.mouseX + ", " + App.mouseY + ">", 1, 17); Assets.font.drawString("MEMORY: " + (int)((allocated / (double)max) * 100) + "% (" + (allocated / (1024 * 1024)) + "/" + (max / (1024 * 1024)) + "MB)", 1, 33); - Assets.font.drawString("", 1, 49); + Assets.font.drawString("IPATHABLE", 1, 49); Assets.font.drawString("", 1, 65); Assets.font.drawString("", 1, 81); @@ -47,7 +47,7 @@ public class HadeanGame extends Game { Assets.font.drawString("FPS: " + Math.round(averageFPS) + "/" + measuredFPS + " | AVG/MEASURED", 0, 0); Assets.font.drawString("Mouse: <" + App.mouseX + ", " + App.mouseY + ">", 0, 16); Assets.font.drawString("MEMORY: " + (int)((allocated / (double)max) * 100) + "% (" + (allocated / (1024 * 1024)) + "/" + (max / (1024 * 1024)) + "MB)", 0, 32); - Assets.font.drawString("", 0, 48); + Assets.font.drawString("IPATHABLE", 0, 48); Assets.font.drawString("", 0, 64); Assets.font.drawString("", 0, 80); diff --git a/src/main/java/xyz/valnet/hadean/Tile.java b/src/main/java/xyz/valnet/hadean/Tile.java index cd56361..18a126a 100644 --- a/src/main/java/xyz/valnet/hadean/Tile.java +++ b/src/main/java/xyz/valnet/hadean/Tile.java @@ -3,28 +3,35 @@ package xyz.valnet.hadean; import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.engine.graphics.Sprite; import xyz.valnet.engine.math.Vector4f; +import xyz.valnet.hadean.gameobjects.Camera; import xyz.valnet.hadean.gameobjects.Terrain; import xyz.valnet.hadean.util.Assets; +// TODO make these tiles REAL gameobjects... public class Tile { private final int x, y; private final Vector4f color = new Vector4f((float) Math.random() * 0.1f, 0.4f + (float) Math.random() * 0.15f, (float) Math.random() * 0.05f, 1f); private final Sprite sprite = Assets.defaultTerrain[(int)Math.floor(Math.random() * Assets.defaultTerrain.length)]; - private final boolean obstacle; + private boolean obstacle; public Tile(int x, int y) { - float distanceFromOrigin = 0.9f - (float)Math.sqrt(x * x + y * y) / 42; this.x = x; this.y = y; - this.obstacle = Math.random() > 0.8f; + this.obstacle = false; + // this.obstacle = Math.random() > 0.8f; } - public void render() { + public void render(Camera camera) { Assets.flat.pushColor(isWalkable() ? color : new Vector4f(0.1f, 0.1f, 0.1f, 1f)); - Drawing.drawSprite(sprite, Terrain.left + x * Terrain.TILE_SIZE, Terrain.top + y * Terrain.TILE_SIZE); + camera.draw(sprite, x, y); + // Drawing.drawSprite(sprite, Terrain.left + x * Terrain.TILE_SIZE, Terrain.top + y * Terrain.TILE_SIZE); Assets.flat.popColor(); } + public void wall() { + obstacle = true; + } + public boolean isWalkable() { return !obstacle; } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Camera.java b/src/main/java/xyz/valnet/hadean/gameobjects/Camera.java new file mode 100644 index 0000000..91980a8 --- /dev/null +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Camera.java @@ -0,0 +1,35 @@ +package xyz.valnet.hadean.gameobjects; + +import xyz.valnet.engine.graphics.Drawing; +import xyz.valnet.engine.graphics.Sprite; +import xyz.valnet.engine.math.Vector2f; +import xyz.valnet.engine.scenegraph.GameObject; +import xyz.valnet.hadean.scenes.GameScene; + +public class Camera extends GameObject { + + private int tileWidth = 24; + // TODO link these in some way to the real resolution. + private int screenWidth = 1024, screenHeight = 576; + + private Vector2f focus = new Vector2f(0, 0); + + public Camera(GameScene scene) { + super(scene); + } + + public void focus(float x, float y) { + this.focus.x = x; + this.focus.y = y; + } + + public Vector2f world2screen(float x, float y) { + return new Vector2f(x * tileWidth + screenWidth / 2 - focus.x * tileWidth, y * tileWidth + screenHeight / 2 - focus.y * tileWidth); + } + + public void draw(Sprite sprite, float x, float y) { + Vector2f screenPos = world2screen(x, y); + Drawing.drawSprite(sprite, (int)(screenPos.x), (int)(screenPos.y), tileWidth, tileWidth); + } + +} diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Pawn.java b/src/main/java/xyz/valnet/hadean/gameobjects/Pawn.java index 131c223..9422de9 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Pawn.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Pawn.java @@ -1,69 +1,71 @@ package xyz.valnet.hadean.gameobjects; +import static org.lwjgl.opengl.GL11.GL_LINES; +import static org.lwjgl.opengl.GL11.glBegin; +import static org.lwjgl.opengl.GL11.glEnd; +import static org.lwjgl.opengl.GL11.glVertex2f; import static xyz.valnet.engine.util.Math.lerp; import java.util.Stack; import xyz.valnet.engine.graphics.Drawing; -import xyz.valnet.engine.math.Vector4f; +import xyz.valnet.engine.math.Vector2f; import xyz.valnet.engine.scenegraph.GameObject; +import xyz.valnet.hadean.Tile; import xyz.valnet.hadean.pathfinding.Node; import xyz.valnet.hadean.scenes.GameScene; import xyz.valnet.hadean.util.Assets; -import static org.lwjgl.opengl.GL20.*; -// import org.lwjgl.opengl.GL20; - public class Pawn extends GameObject { - private float x, y; + private float x = 0.5f, y = 0.5f; private float dx, dy; private float counter = 0; private Stack path; - private final float speed = 20f; + private final float speed = 50f; + + private Camera camera; + private Terrain terrain; public Pawn(GameScene scene) { super(scene); } + @Override + public void start() { + camera = get(Camera.class); + terrain = get(Terrain.class); + } + @Override public void render() { - Drawing.setLayer(0.15f); + Drawing.setLayer(0.5f); if(path != null && path.size() > 0) { - float cx = (int)(Terrain.left + (x - 0.5f) * Terrain.TILE_SIZE); - float cy = (int)(Terrain.top + (y - 0.5f) * Terrain.TILE_SIZE); - - Node n = path.peek(); - - float nx = Terrain.left + n.x * Terrain.TILE_SIZE; - float ny = Terrain.top + n.y * Terrain.TILE_SIZE; - - System.out.println("" + n.x + " " + n.y); - - Drawing.drawSprite(Assets.pawn, (int)lerp(cx, nx, counter / speed), (int)lerp(cy, ny, counter / speed)); + Node next = path.peek(); + float t = counter / speed; + camera.draw(Assets.pawn, lerp(x - 0.5f, next.x, t), lerp(y - 0.5f, next.y, t)); if(path != null) { for(Node node : path) { glBegin(GL_LINES); - if(node.from == null) { - glVertex2f(Terrain.left + x * Terrain.TILE_SIZE, Terrain.top + y * Terrain.TILE_SIZE); - } else { - glVertex2f(Terrain.left + (node.from.x + 0.5f) * Terrain.TILE_SIZE, Terrain.top + (node.from.y + 0.5f) * Terrain.TILE_SIZE); - } - glVertex2f(Terrain.left + (node.x + 0.5f) * Terrain.TILE_SIZE, Terrain.top + (node.y + 0.5f) * Terrain.TILE_SIZE); + Vector2f u, v; + + if(node.from == null) u = camera.world2screen(x, y); + else u = camera.world2screen(node.from.x + 0.5f, node.from.y + 0.5f); + + v = camera.world2screen(node.x + 0.5f, node.y + 0.5f); + glVertex2f(u.x, u.y); + glVertex2f(v.x, v.y); glEnd(); } } } else { - int nx = (int)(Terrain.left + (x - 0.5f) * Terrain.TILE_SIZE); - int ny = (int)(Terrain.top + (y - 0.5f) * Terrain.TILE_SIZE); - - Drawing.drawSprite(Assets.pawn, nx, ny); + camera.draw(Assets.pawn, x - 0.5f, y - 0.5f); } // Drawing.setLayer(0.1f); @@ -78,34 +80,53 @@ public class Pawn extends GameObject { @Override public void tick(float dTime) { - counter ++; - if(counter >= speed) action(); + if(path != null && !path.empty()) move(); + else newPath(); } + private void newPath() { + // set new destination + dx = 0.5f + (float)Math.floor(Math.random() * Terrain.WORLD_SIZE); + dy = 0.5f + (float)Math.floor(Math.random() * Terrain.WORLD_SIZE); + // and route there. + route(); + } - private void action() { - if(path == null || path.empty()) { - dx = 0.5f + (float)Math.floor(Math.random() * Terrain.WORLD_SIZE); - dy = 0.5f + (float)Math.floor(Math.random() * Terrain.WORLD_SIZE); + private void route() { + // intify all the coordinates + int ix = (int)Math.floor(x); + int iy = (int)Math.floor(y); - int ix = (int)Math.floor(x); - int iy = (int)Math.floor(y); + int idx = (int)Math.floor(dx); + int idy = (int)Math.floor(dy); - int idx = (int)Math.floor(dx); - int idy = (int)Math.floor(dy); + // try to make a new path. + path = get(Terrain.class).getPath(ix, iy, idx, idy); + } - path = get(Terrain.class).getPath(ix, iy, idx, idy); - if(path != null) { - counter = 0; + private void move() { + // check if we CAN move. + Node nextNode = path.peek(); + Tile nextTile = terrain.getTile(nextNode.x, nextNode.y); + if(!nextTile.isWalkable()) { + if(counter > 0) counter --; + if(counter < 0) counter = 0; + if(counter == 0) { + route(); } - } else { - Node n = path.pop(); - x = n.x + 0.5f; - y = n.y + 0.5f; - counter = 0; + return; } + counter ++; + if(counter < speed) return; + + path.pop(); + x = nextNode.x + 0.5f; + y = nextNode.y + 0.5f; + counter = 0; + + nextTile.wall(); } } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Terrain.java b/src/main/java/xyz/valnet/hadean/gameobjects/Terrain.java index 71198c8..5f46511 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Terrain.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Terrain.java @@ -2,34 +2,40 @@ package xyz.valnet.hadean.gameobjects; import java.util.ArrayList; import java.util.Comparator; -import java.util.LinkedList; import java.util.List; import java.util.Stack; import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.engine.scenegraph.GameObject; -import xyz.valnet.engine.scenegraph.IScene; import xyz.valnet.hadean.Tile; import xyz.valnet.hadean.pathfinding.Node; import xyz.valnet.hadean.scenes.GameScene; - -// implements IPathable, the thing that has callbacks for interfacing with a pathfinder. + +// TODO SPLIT PATHABLES. | implements IPathable, the thing that has callbacks for interfacing with a pathfinder. public class Terrain extends GameObject { - public static final int WORLD_SIZE = 40; + public static final int WORLD_SIZE = 24; public static final int TILE_SIZE = 8; - public static int left, top; + // public static int left, top; private Tile[][] tiles = new Tile[WORLD_SIZE][WORLD_SIZE]; + private Camera camera; + public Terrain(GameScene scene) { super(scene); + } + + public void start() { for (int i = 0; i < WORLD_SIZE; i++) { for (int j = 0; j < WORLD_SIZE; j++) { tiles[i][j] = new Tile(i, j); } } + camera = get(Camera.class); + + camera.focus(WORLD_SIZE / 2, WORLD_SIZE / 2); } public Tile getTile(int x, int y) { @@ -44,8 +50,8 @@ public class Terrain extends GameObject { } private Node getPathfindingNode(int x, int y, List open, List closed, Node parent, int dstX, int dstY) { + // TODO this isnt necessarily the BOUNDS so... think about that. if(x < 0 || y < 0 || x >= WORLD_SIZE || y >= WORLD_SIZE) { - // * out of bounds return null; } @@ -126,6 +132,8 @@ public class Terrain extends GameObject { n = n.from; } + path.pop(); + return path; } @@ -164,13 +172,13 @@ public class Terrain extends GameObject { @Override public void render() { - left = 400 - (WORLD_SIZE * TILE_SIZE / 2); - top = 225 - (WORLD_SIZE * TILE_SIZE / 2); + // left = 400 - (WORLD_SIZE * TILE_SIZE / 2); + // top = 225 - (WORLD_SIZE * TILE_SIZE / 2); Drawing.setLayer(0f); for (int i = 0; i < WORLD_SIZE; i++) { for (int j = 0; j < WORLD_SIZE; j++) { - tiles[i][j].render(); + tiles[i][j].render(camera); } } } diff --git a/src/main/java/xyz/valnet/hadean/scenes/GameScene.java b/src/main/java/xyz/valnet/hadean/scenes/GameScene.java index 1331ed9..4d2e964 100644 --- a/src/main/java/xyz/valnet/hadean/scenes/GameScene.java +++ b/src/main/java/xyz/valnet/hadean/scenes/GameScene.java @@ -5,6 +5,7 @@ import java.util.List; import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.IScene; +import xyz.valnet.hadean.gameobjects.Camera; import xyz.valnet.hadean.gameobjects.Pawn; import xyz.valnet.hadean.gameobjects.Terrain; @@ -45,6 +46,12 @@ public class GameScene implements IScene { for(int i = 0; i < 3; i ++) { objects.add(new Pawn(this)); } + Camera camera = new Camera(this); + objects.add(camera); + + for(GameObject obj : objects) { + obj.start(); + } } @Override