epix camera & routing
parent
8e1f91d947
commit
557d0eb569
BIN
res/textures.png
BIN
res/textures.png
Binary file not shown.
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.6 KiB |
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -18,4 +18,6 @@ public class GameObject implements IRenderable, ITickable {
|
|||
|
||||
@Override
|
||||
public void tick(float dTime) {}
|
||||
|
||||
public void start() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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<Node> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Node> open, List<Node> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue