diff --git a/idea.md b/idea.md index b8f5f0b..bbcd86a 100644 --- a/idea.md +++ b/idea.md @@ -19,4 +19,8 @@ null instead of the IWorker's current job. to is when the worker knows it can move on to another action. A Worker may also tell a job board, that it no longer -wishes to do work, and the job will be released. \ No newline at end of file +wishes to do work, and the job will be released. + +# IMouseCaptureArea + +its just a name, but reframe current mouse shit to it. \ No newline at end of file diff --git a/res/textures.png b/res/textures.png index 7e4aff3..3d743c5 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 4a27681..2dae3ff 100644 --- a/src/main/java/xyz/valnet/engine/App.java +++ b/src/main/java/xyz/valnet/engine/App.java @@ -22,6 +22,8 @@ public class App { private int width = 1024, height = 576; private Matrix4f matrix = Matrix4f.orthographic(0, width, height, 0, 0, 100); public static int mouseX, mouseY; + + @Deprecated public static boolean mouseLeft, mouseMiddle, mouseRight; private Game game; @@ -78,7 +80,13 @@ public class App { glfwSetMouseButtonCallback(window, new GLFWMouseButtonCallback() { @Override public void invoke(long window, int button, int action, int mods) { - + if(action == 1) { + game.mouseDown(button); + } else if(action == 0) { + game.mouseUp(button); + } + + // TODO deprecate these. if(button >= 3) return; if(button == GLFW_MOUSE_BUTTON_LEFT) { mouseLeft = action == 1; return; } if(button == GLFW_MOUSE_BUTTON_RIGHT) { mouseRight = action == 1; return; } diff --git a/src/main/java/xyz/valnet/engine/Game.java b/src/main/java/xyz/valnet/engine/Game.java index 21d5163..4ba06a1 100644 --- a/src/main/java/xyz/valnet/engine/Game.java +++ b/src/main/java/xyz/valnet/engine/Game.java @@ -47,4 +47,12 @@ public abstract class Game { } public abstract void updateViewMatrix(Matrix4f matrix); + + public final void mouseDown(int button) { + scene.mouseDown(button); + } + + public final void mouseUp(int button) { + scene.mouseUp(button); + } } diff --git a/src/main/java/xyz/valnet/engine/math/Vector4f.java b/src/main/java/xyz/valnet/engine/math/Vector4f.java index 6e7d28f..b4b2e4a 100644 --- a/src/main/java/xyz/valnet/engine/math/Vector4f.java +++ b/src/main/java/xyz/valnet/engine/math/Vector4f.java @@ -26,4 +26,8 @@ public class Vector4f { return "(" + this.x + ", " + this.y + ", " + this.z + ", " + this.w + ")"; } + public boolean contains(float x, float y) { + return x >= this.x && x < this.x + this.z && y >= this.y && y < this.y + this.w; + } + } diff --git a/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java b/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java index 682685c..809ea78 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/GameObject.java @@ -31,7 +31,7 @@ public class GameObject implements IRenderable, ITickable { public void render() {} @Override - public void tick(float dTime) {} + public void update(float dTime) {} public void start() {} diff --git a/src/main/java/xyz/valnet/engine/scenegraph/IScene.java b/src/main/java/xyz/valnet/engine/scenegraph/IScene.java index cd61300..7dddf66 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/IScene.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/IScene.java @@ -4,6 +4,9 @@ public interface IScene { public void render(); public void update(float dTime); + public void mouseDown(int button); + public void mouseUp(int button); + public void enable(); public void disable(); } diff --git a/src/main/java/xyz/valnet/engine/scenegraph/ITickable.java b/src/main/java/xyz/valnet/engine/scenegraph/ITickable.java index 9af77f9..fbbc58d 100644 --- a/src/main/java/xyz/valnet/engine/scenegraph/ITickable.java +++ b/src/main/java/xyz/valnet/engine/scenegraph/ITickable.java @@ -1,5 +1,5 @@ package xyz.valnet.engine.scenegraph; public interface ITickable { - public void tick(float dTime); + public void update(float dTime); } diff --git a/src/main/java/xyz/valnet/hadean/HadeanGame.java b/src/main/java/xyz/valnet/hadean/HadeanGame.java index 5ec4452..585d4d8 100644 --- a/src/main/java/xyz/valnet/hadean/HadeanGame.java +++ b/src/main/java/xyz/valnet/hadean/HadeanGame.java @@ -31,31 +31,31 @@ public class HadeanGame extends Game { renderDebugInfo(); } - private Runtime runtime = Runtime.getRuntime(); - private static Vector4f fontColor = new Vector4f(0, 1, 1, 1); + // private Runtime runtime = Runtime.getRuntime(); + // private static Vector4f fontColor = new Vector4f(0, 1, 1, 1); private void renderDebugInfo() { - long allocated = runtime.totalMemory(); - long max = runtime.maxMemory(); + // long allocated = runtime.totalMemory(); + // long max = runtime.maxMemory(); - Assets.flat.pushColor(Vector4f.black); - 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("IPATHABLE", 1, 49); - Assets.font.drawString("", 1, 65); - Assets.font.drawString("", 1, 81); + // Assets.flat.pushColor(Vector4f.black); + // 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("IPATHABLE", 1, 49); + // Assets.font.drawString("", 1, 65); + // Assets.font.drawString("", 1, 81); - Assets.flat.swapColor(fontColor); - 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("IPATHABLE", 0, 48); - Assets.font.drawString("", 0, 64); - Assets.font.drawString("", 0, 80); + // Assets.flat.swapColor(fontColor); + // 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("IPATHABLE", 0, 48); + // Assets.font.drawString("", 0, 64); + // Assets.font.drawString("", 0, 80); - Assets.flat.popColor(); + // Assets.flat.popColor(); } // receive the updated matrix every frame for the actual window. @@ -63,5 +63,4 @@ public class HadeanGame extends Game { public void updateViewMatrix(Matrix4f matrix) { Assets.flat.setMatrices(matrix); } - } diff --git a/src/main/java/xyz/valnet/hadean/Layers.java b/src/main/java/xyz/valnet/hadean/Layers.java new file mode 100644 index 0000000..e1953c2 --- /dev/null +++ b/src/main/java/xyz/valnet/hadean/Layers.java @@ -0,0 +1,20 @@ +package xyz.valnet.hadean; + +public class Layers { + private static int current = 0; + public static int getMax() { + return current; + } + + public static final int BACKGROUND = current ++; + public static final int TILES = current ++; + public static final int GROUND = current ++; + public static final int AIR = current ++; + public static final int MARKERS = current ++; + public static final int SELECTION_IDENTIFIERS = current ++; + public static final int AREA_SELECT_BOX = current ++; + public static final int GENERAL_UI = current ++; + public static final int GENERAL_UI_INTERACTABLE = current ++; + public static final int BOTTOM_BAR = current ++; + +} diff --git a/src/main/java/xyz/valnet/hadean/Tile.java b/src/main/java/xyz/valnet/hadean/Tile.java index b108340..4fa685e 100644 --- a/src/main/java/xyz/valnet/hadean/Tile.java +++ b/src/main/java/xyz/valnet/hadean/Tile.java @@ -40,7 +40,7 @@ public class Tile extends GameObject { } @Override - public void tick(float dTime) { + public void update(float dTime) { for(ITileThing thing : stuff) { if(thing.shouldRemove()) { toRemove.add(thing); diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/BottomBar.java b/src/main/java/xyz/valnet/hadean/gameobjects/BottomBar.java index d049aea..2223e8c 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/BottomBar.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/BottomBar.java @@ -6,6 +6,7 @@ import java.util.List; import java.util.Map; import xyz.valnet.engine.scenegraph.GameObject; +import xyz.valnet.hadean.Layers; import xyz.valnet.hadean.input.Button; import xyz.valnet.hadean.input.IButtonListener; import xyz.valnet.hadean.input.SimpleButton; @@ -21,11 +22,11 @@ public class BottomBar extends GameObject implements IButtonListener { @Override public void start() { items.clear(); - btnItemTable.clear(); + clearButtons(); } public void registerButton(IBottomBarItem newItem) { - btnItemTable.clear(); + clearButtons(); items.add(newItem); int n = items.size(); @@ -35,9 +36,9 @@ public class BottomBar extends GameObject implements IButtonListener { int r = (int)(((i + 1) / (float) n) * screenWidth); int w = r - l; - Button btn = new SimpleButton(item.getTabName(), l, 576 - bottomBarHeight, w, bottomBarHeight); - + Button btn = new SimpleButton(item.getTabName(), l, 576 - bottomBarHeight, w, bottomBarHeight, Layers.BOTTOM_BAR); btn.registerClickListener(this); + add(btn); btnItemTable.put(btn, item); @@ -45,17 +46,11 @@ public class BottomBar extends GameObject implements IButtonListener { } } - @Override - public void render() { + private void clearButtons() { for(Button btn : btnItemTable.keySet()) { - btn.draw(); - } - } - @Override - public void tick(float dTime) { - for(Button btn : btnItemTable.keySet()) { - btn.update(); + remove(btn); } + btnItemTable.clear(); } @Override diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Log.java b/src/main/java/xyz/valnet/hadean/gameobjects/Log.java index d4f94d0..657d1de 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Log.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Log.java @@ -1,7 +1,9 @@ package xyz.valnet.hadean.gameobjects; +import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.scenegraph.GameObject; +import xyz.valnet.hadean.Layers; import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Assets; @@ -23,6 +25,7 @@ public class Log extends GameObject implements ITileThing, ISelectable { @Override public void render() { + Drawing.setLayer(Layers.GROUND); camera.draw(Assets.log, x, y); } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Pawn.java b/src/main/java/xyz/valnet/hadean/gameobjects/Pawn.java index 650db6e..ca215d4 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Pawn.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Pawn.java @@ -26,13 +26,13 @@ import xyz.valnet.hadean.util.Assets; public class Pawn extends GameObject implements ISelectable { - private float x = 0.5f, y = 0.5f; + private float x = 0.5f + (int)(Math.random() * Terrain.WORLD_SIZE), y = 0.5f + (int)(Math.random() * Terrain.WORLD_SIZE); private float counter = 0; private Path path; - private final float invocationThreshold = 50 + (float)(Math.random() * 20); + private final float invocationThreshold = 100 + (float)(Math.random() * 50); private Camera camera; private Terrain terrain; @@ -108,7 +108,7 @@ public class Pawn extends GameObject implements ISelectable { } @Override - public void tick(float dTime) { + public void update(float dTime) { // then, try to do work! if(currentJob != null && currentJob.hasWork()) { diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Selection.java b/src/main/java/xyz/valnet/hadean/gameobjects/Selection.java index 2d96b7b..018770f 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Selection.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Selection.java @@ -4,14 +4,17 @@ import java.util.ArrayList; import java.util.List; import xyz.valnet.engine.App; +import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.engine.math.Vector2f; import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.scenegraph.GameObject; +import xyz.valnet.hadean.Layers; +import xyz.valnet.hadean.input.IMouseListener; import xyz.valnet.hadean.util.Assets; import static xyz.valnet.engine.util.Math.lerp; -public class Selection extends GameObject { +public class Selection extends GameObject implements IMouseListener { public Vector2f initialCoords; private Camera camera; @@ -37,30 +40,14 @@ public class Selection extends GameObject { private List toRemove = new ArrayList(); @Override - public void tick(float dTime) { + public void update(float dTime) { if(animation < animationMax) animation ++; if(animation > animationMax) animation = animationMax; - // TODO at some point, this will need to be blocked by other things on top. like a ui over the scene should make selections like, not happen?! - if(App.mouseRight) { - Vector2f currentMouseCoords = new Vector2f(App.mouseX, App.mouseY); - if(initialCoords == null) { - initialCoords = currentMouseCoords; - } - } else { - if(initialCoords != null) { - - makeSelection(new Vector4f( - initialCoords.x, - initialCoords.y, - App.mouseX, - App.mouseY - )); - - initialCoords = null; - } - } + // if(!active) return; + // if any of our selection just RANDOMLY isnt in the scene anymore, well + // stop selecting it dumbass for(ISelectable selectable : selected) { if(selectable instanceof GameObject) { if(!((GameObject)selectable).inScene()) { @@ -84,6 +71,7 @@ public class Selection extends GameObject { Vector4f box = thing.getWorldBox(); Vector2f min = camera.world2screen(box.x - p, box.y - p); Vector2f max = camera.world2screen(box.z + p, box.w + p); + Drawing.setLayer(Layers.SELECTION_IDENTIFIERS); Assets.selectedFrame.draw((int)min.x, (int)min.y, (int)(max.x - min.x), (int)(max.y - min.y)); thing.selectedRender(); } @@ -151,4 +139,52 @@ public class Selection extends GameObject { return !( aLeftOfB || aRightOfB || aAboveB || aBelowB ); } + + private boolean active = false; + + @Override + public void mouseEnter() { + active = true; + } + + @Override + public void mouseLeave() { + active = false; + } + + @Override + public Vector4f getBox() { + return new Vector4f(0, 0, 1000, 1000); + } + + @Override + public int getLayer() { + return 0; + } + + @Override + public boolean mouseDown(int button) { + if(!active) return false; + if(button == 0) { + if(initialCoords == null) { + initialCoords = new Vector2f(App.mouseX, App.mouseY); + } + } + return false; + } + + @Override + public void mouseUp(int button) { + if(initialCoords != null && button == 0) { + + makeSelection(new Vector4f( + initialCoords.x, + initialCoords.y, + App.mouseX, + App.mouseY + )); + + initialCoords = null; + } + } } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java b/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java index efbb684..5fda511 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/SelectionUI.java @@ -4,14 +4,17 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.scenegraph.GameObject; +import xyz.valnet.hadean.Layers; import xyz.valnet.hadean.input.Button; import xyz.valnet.hadean.input.IButtonListener; +import xyz.valnet.hadean.input.IMouseListener; import xyz.valnet.hadean.input.SimpleButton; import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Assets; -public class SelectionUI extends GameObject implements ISelectionChangeListener, IButtonListener { +public class SelectionUI extends GameObject implements ISelectionChangeListener, IButtonListener, IMouseListener { private String name = ""; private int count = 0; @@ -21,10 +24,13 @@ public class SelectionUI extends GameObject implements ISelectionChangeListener, private HashMap> narrowBuckets = new HashMap>(); private static final Button[] ACTIONS_BUTTONS_NULL = new Button[] {}; - + private Button[] actionButtons = ACTIONS_BUTTONS_NULL; private Selection selectionManager; + private final int width = 300, height = 200; + private final int padding = 10; + private final int actionButtonSize = 100; // this will be null normally, but set if // a button has been pressed to update the selection. @@ -42,7 +48,7 @@ public class SelectionUI extends GameObject implements ISelectionChangeListener, public void render() { if(selected.isEmpty()) return; - Assets.uiFrame.draw(10, 366, 300, 200); + Assets.uiFrame.draw(10, 576 - BottomBar.bottomBarHeight - height - padding, width, height); // int i = 0; // for(String name : selectedTypes.keySet()) { @@ -53,54 +59,53 @@ public class SelectionUI extends GameObject implements ISelectionChangeListener, if(selectedTypes.size() == 1) { - Assets.font.drawString("" + count + "x " + name, 26, 376); + Assets.font.drawString("" + count + "x " + name, 26, 576 - BottomBar.bottomBarHeight - height); if(count == 1) { String details = selected.get(0).details(); - Assets.font.drawString(details, 26, 376 + 32); - } - - for(Button btn : actionButtons) { - btn.draw(); + Assets.font.drawString(details, 26, 576 - BottomBar.bottomBarHeight - height + 32); } } else { - for(Button btn : narrowButtons.values()) { - btn.draw(); - } } } @Override - public void tick(float dTime) { + public void update(float dTime) { if(newSelection != null) { selectionManager.updateSelection(newSelection); newSelection = null; } if(selectedTypes.size() == 1) { - for(Button btn : actionButtons) { - btn.update(); - } } else { - for(Button btn : narrowButtons.values()) { - btn.update(); - } } } private HashMap buttonActionMap = new HashMap(); + private void addNarrowButton(String str, Button btn) { + narrowButtons.put(str, btn); + add(btn); + } + + private void clearNarrowButtons() { + for(GameObject obj : narrowButtons.values()) { + remove(obj); + } + narrowButtons.clear(); + } + @Override public void selectionChanged(List selected) { this.selected = selected; selectedTypes.clear(); - narrowButtons.clear(); + clearNarrowButtons(); narrowBuckets.clear(); buttonActionMap.clear(); - actionButtons = ACTIONS_BUTTONS_NULL; + setActionButtons(ACTIONS_BUTTONS_NULL); for(ISelectable selectable : selected) { String name = selectable.getClass().getName(); String[] splitName = name.split("\\."); @@ -114,27 +119,41 @@ public class SelectionUI extends GameObject implements ISelectionChangeListener, btn.setText("" + items.size() + "x " + shortName); count ++; } else { - Button btn = new SimpleButton("1x " + shortName, 20, 376 + 30 * selectedTypes.size(), 280, 24); + Button btn = new SimpleButton("1x " + shortName, 20, 576 - BottomBar.bottomBarHeight - height + 30 * selectedTypes.size(), width - padding * 2, 24, Layers.GENERAL_UI_INTERACTABLE); btn.registerClickListener(this); selectedTypes.put(name, 1); - narrowButtons.put(name, btn); + addNarrowButton(name, btn); List list = new ArrayList(); list.add(selectable); narrowBuckets.put(btn, list); count = 1; this.name = shortName; - if(actionButtons == ACTIONS_BUTTONS_NULL) { - Action[] actions = selectable.getActions(); - Button[] actionButtons = new Button[actions.length]; - for(int i = 0; i < actions.length; i ++) { - actionButtons[i] = new SimpleButton(actions[i].name, 320 + i * 110, 466, 100, 100); - actionButtons[i].registerClickListener(this); - buttonActionMap.put(actionButtons[i], actions[i]); - } - this.actionButtons = actionButtons; - } } } + if(selectedTypes.size() == 1) { + // TODO this should only pull common actions to all elements, but rn just pulls the first things actions + Action[] actions = selected.get(0).getActions(); + Button[] actionButtons = new Button[actions.length]; + for(int i = 0; i < actions.length; i ++) { + actionButtons[i] = new SimpleButton(actions[i].name, width + padding * 2 + i * (actionButtonSize + padding), 576 - padding - actionButtonSize - BottomBar.bottomBarHeight, actionButtonSize, actionButtonSize, Layers.GENERAL_UI_INTERACTABLE); + actionButtons[i].registerClickListener(this); + buttonActionMap.put(actionButtons[i], actions[i]); + } + setActionButtons(actionButtons); + } + if(selectedTypes.size() <= 1) { + clearNarrowButtons(); + } + } + + private void setActionButtons(Button[] buttons) { + for(Button btn : this.actionButtons) { + remove(btn); + } + this.actionButtons = buttons; + for(Button btn : this.actionButtons) { + add(btn); + } } @Override @@ -148,4 +167,35 @@ public class SelectionUI extends GameObject implements ISelectionChangeListener, } } } + + @Override + public void mouseEnter() { + + } + + @Override + public void mouseLeave() { + + } + + @Override + public boolean mouseDown(int button) { + return false; + } + + @Override + public void mouseUp(int button) { + + } + + @Override + public Vector4f getBox() { + if(selected.isEmpty()) return Vector4f.zero; + return new Vector4f(10, 576 - BottomBar.bottomBarHeight - height - padding, width, height); + } + + @Override + public int getLayer() { + return Layers.GENERAL_UI; + } } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Terrain.java b/src/main/java/xyz/valnet/hadean/gameobjects/Terrain.java index e7adc50..ad279c5 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Terrain.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Terrain.java @@ -4,7 +4,6 @@ import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.hadean.Tile; import xyz.valnet.hadean.pathfinding.IPathable; -// TODO SPLIT PATHABLES. | implements IPathable, the thing that has callbacks for interfacing with a pathfinder. public class Terrain extends GameObject implements IPathable { public static final int WORLD_SIZE = 24; @@ -32,6 +31,7 @@ public class Terrain extends GameObject implements IPathable { return tiles[x][y]; } + // TODO implement directionality. even the pathfinder doesnt give this info... @Override public boolean isWalkable(int x, int y, int fromX, int fromY) { if(!isOutOfBounds(x, y)) { diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/Tree.java b/src/main/java/xyz/valnet/hadean/gameobjects/Tree.java index 21efdd9..94fee9d 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/Tree.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/Tree.java @@ -1,14 +1,15 @@ package xyz.valnet.hadean.gameobjects; +import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.engine.math.Vector2i; import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.scenegraph.GameObject; +import xyz.valnet.hadean.Layers; import xyz.valnet.hadean.util.Action; import xyz.valnet.hadean.util.Assets; public class Tree extends GameObject implements ITileThing, ISelectable, IWorkable { private Camera camera; - private Terrain terrain; private boolean chopFlag = false; @@ -21,15 +22,16 @@ public class Tree extends GameObject implements ITileThing, ISelectable, IWorkab public void start() { camera = get(Camera.class); - terrain = get(Terrain.class); } @Override public void render() { Assets.flat.pushColor(new Vector4f(1 - getProgress(), 1 - getProgress(), 1 - getProgress(), 1.0f)); + Drawing.setLayer(Layers.AIR); camera.draw(Assets.tree, x - 1, y - 2, 3, 3); Assets.flat.popColor(); if(hasWork()) { + Drawing.setLayer(Layers.MARKERS); camera.draw(Assets.lilAxe, x, y); } } @@ -76,7 +78,7 @@ public class Tree extends GameObject implements ITileThing, ISelectable, IWorkab } protected float choppage = 0; - protected int strength = 500; + protected int strength = 5000; private float getProgress() { return (choppage / (float) strength); @@ -94,7 +96,7 @@ public class Tree extends GameObject implements ITileThing, ISelectable, IWorkab } @Override - public void tick(float dTime) { + public void update(float dTime) { if(choppage >= strength) { return; } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/tabs/ArchitectTab.java b/src/main/java/xyz/valnet/hadean/gameobjects/tabs/ArchitectTab.java index ac061ff..0698d3f 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/tabs/ArchitectTab.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/tabs/ArchitectTab.java @@ -37,11 +37,13 @@ public class ArchitectTab extends Tab implements ISelectionChangeListener { public void start() { super.start(); selection = get(Selection.class); - selection.subscribe(this); + if(selection != null) { + selection.subscribe(this); + } } @Override - public void tick(float dTime) { + public void update(float dTime) { progress = lerp(progress, opened ? 1 : 0, 0.05f); } diff --git a/src/main/java/xyz/valnet/hadean/gameobjects/tabs/MenuTab.java b/src/main/java/xyz/valnet/hadean/gameobjects/tabs/MenuTab.java index 17f5c30..642ac0a 100644 --- a/src/main/java/xyz/valnet/hadean/gameobjects/tabs/MenuTab.java +++ b/src/main/java/xyz/valnet/hadean/gameobjects/tabs/MenuTab.java @@ -11,5 +11,23 @@ public class MenuTab extends Tab { public String getTabName() { return "Menu"; } + + // @Override + // public void tick(float dTime) { + // } + + // @Override + // public void render() { + // } + + // @Override + // public void start() { + // super.start(); + // add(new GOButton() + // .setDimensions(200, 300, 100, 100, 50)); + // add(new GOButton() + // .setDimensions(250, 350, 100, 100, 55)); + + // } } diff --git a/src/main/java/xyz/valnet/hadean/input/Button.java b/src/main/java/xyz/valnet/hadean/input/Button.java index 66d509e..3eba980 100644 --- a/src/main/java/xyz/valnet/hadean/input/Button.java +++ b/src/main/java/xyz/valnet/hadean/input/Button.java @@ -2,15 +2,16 @@ package xyz.valnet.hadean.input; import static xyz.valnet.engine.util.Math.lerp; -import xyz.valnet.engine.App; +import xyz.valnet.engine.graphics.Drawing; import xyz.valnet.engine.graphics.Tile9; import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.math.Vector4i; +import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.hadean.util.Assets; -public class Button { +public class Button extends GameObject implements IMouseListener { - private final int x, y, width, height; + private int x, y, width, height; private String text; protected Tile9 frame; protected Tile9 frameHover; @@ -24,7 +25,9 @@ public class Button { protected float activeVPad = 0.1f; protected float activeHPad = 0.0f; - public Button(Tile9 frame, String text, int x, int y, int w, int h) { + protected int layer; + + public Button(Tile9 frame, String text, int x, int y, int w, int h, int l) { this.x = x; this.y = y; width = w; @@ -34,6 +37,7 @@ public class Button { this.frameHover = frame; setText(text); box = new Vector4i(x, y, w, h); + layer = l; } public void setText(String text) { @@ -43,7 +47,9 @@ public class Button { textHeight = measuredText.y; } - public void draw() { + @Override + public void render() { + Drawing.setLayer(layer); if(state == HOVER) { frameHover.draw(box.x, box.y, box.z, box.w); } else if(state == ACTIVE) { @@ -61,7 +67,16 @@ public class Button { Assets.flat.popColor(); } + // public void draw(int x, int y, int w, int h) { + // this.x = x; + // this.y = y; + // width = w; + // height = h; + // render(); + // } + private boolean hovered = false; + private boolean mouseDown = false; private int state = 0; private final static int IDLE = 0; @@ -73,14 +88,16 @@ public class Button { private IButtonListener listener = null; public void update() { + update(1); + } + + @Override + public void update(float dTime) { box.x = x - (int)hPad; box.y = y - (int)vPad; box.z = width + ((int)hPad) * 2; box.w = height + ((int)vPad) * 2; - hovered = App.mouseX >= box.x && App.mouseX <= box.x + box.z && App.mouseY >= box.y && App.mouseY <= box.y + box.w; - boolean mouseDown = App.mouseLeft; - float desiredVPad = 0, desiredHPad = 0; if(state == HOVER) { @@ -132,4 +149,46 @@ public class Button { public void registerClickListener(IButtonListener listener) { this.listener = listener; } + + @Override + public void mouseEnter() { + hovered = true; + } + + @Override + public void mouseLeave() { + hovered = false; + } + + @Deprecated + // this should only be used when its not added to a scene (with gameobjects!), + // which increasingly should NOT be the case. + public void setMouseCoords(float x, float y) { + hovered = x >= box.x && x <= box.x + box.z && y >= box.y && y <= box.y + box.w; + } + + @Override + public boolean mouseDown(int button) { + if(button == 0) { + mouseDown = true; + } + return false; + } + + @Override + public void mouseUp(int button) { + if(button == 0) { + mouseDown = false; + } + } + + @Override + public Vector4f getBox() { + return new Vector4f(x, y, width, height); + } + + @Override + public int getLayer() { + return layer; + } } diff --git a/src/main/java/xyz/valnet/hadean/input/GOButton.java b/src/main/java/xyz/valnet/hadean/input/GOButton.java new file mode 100644 index 0000000..12ce414 --- /dev/null +++ b/src/main/java/xyz/valnet/hadean/input/GOButton.java @@ -0,0 +1,63 @@ +package xyz.valnet.hadean.input; + +import xyz.valnet.engine.graphics.Drawing; +import xyz.valnet.engine.math.Vector4f; +import xyz.valnet.engine.scenegraph.GameObject; +import xyz.valnet.hadean.util.Assets; + +public class GOButton extends GameObject implements IMouseListener { + + private boolean hovered = false; + public int layer = 1; + public int x, y, w, h; + + public GOButton setDimensions(int x, int y, int w, int h, int l) { + this.x = x; + this.y = y; + this.w = w; + this.h = h; + this.layer = l; + return this; + } + + @Override + public void render() { + Drawing.setLayer(layer); + if(hovered) { + Assets.uiFrameLight.draw(x, y, w, h); + } else { + Assets.uiFrame.draw(x, y, w, h); + } + } + + @Override + public void mouseEnter() { + hovered = true; + } + + @Override + public void mouseLeave() { + hovered = false; + } + + @Override + public boolean mouseDown(int button) { + return false; + } + + @Override + public void mouseUp(int button) { + + } + + @Override + public Vector4f getBox() { + return new Vector4f(x, y, w, h); + } + + @Override + public int getLayer() { + return layer; + } + +} diff --git a/src/main/java/xyz/valnet/hadean/input/IMouseListener.java b/src/main/java/xyz/valnet/hadean/input/IMouseListener.java new file mode 100644 index 0000000..7a0fc58 --- /dev/null +++ b/src/main/java/xyz/valnet/hadean/input/IMouseListener.java @@ -0,0 +1,13 @@ +package xyz.valnet.hadean.input; + +import xyz.valnet.engine.math.Vector4f; + +public interface IMouseListener { + public void mouseEnter(); + public void mouseLeave(); + public boolean mouseDown(int button); + public void mouseUp(int button); + + public Vector4f getBox(); + public int getLayer(); +} diff --git a/src/main/java/xyz/valnet/hadean/input/SimpleButton.java b/src/main/java/xyz/valnet/hadean/input/SimpleButton.java index 2bb3c39..fb67262 100644 --- a/src/main/java/xyz/valnet/hadean/input/SimpleButton.java +++ b/src/main/java/xyz/valnet/hadean/input/SimpleButton.java @@ -4,8 +4,8 @@ import xyz.valnet.hadean.util.Assets; public class SimpleButton extends Button { - public SimpleButton(String text, int x, int y, int w, int h) { - super(Assets.uiFrame, text, x, y, w, h); + public SimpleButton(String text, int x, int y, int w, int h, int l) { + super(Assets.uiFrame, text, x, y, w, h, l); this.activeHPad = 0f; this.activeVPad = 0f; diff --git a/src/main/java/xyz/valnet/hadean/scenes/GameScene.java b/src/main/java/xyz/valnet/hadean/scenes/GameScene.java index 7e0eae1..800f89b 100644 --- a/src/main/java/xyz/valnet/hadean/scenes/GameScene.java +++ b/src/main/java/xyz/valnet/hadean/scenes/GameScene.java @@ -1,8 +1,10 @@ package xyz.valnet.hadean.scenes; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import xyz.valnet.engine.App; import xyz.valnet.engine.scenegraph.GameObject; import xyz.valnet.engine.scenegraph.IScene; import xyz.valnet.hadean.gameobjects.BottomBar; @@ -13,6 +15,16 @@ import xyz.valnet.hadean.gameobjects.SelectionUI; import xyz.valnet.hadean.gameobjects.Terrain; import xyz.valnet.hadean.gameobjects.tabs.ArchitectTab; import xyz.valnet.hadean.gameobjects.tabs.MenuTab; +import xyz.valnet.hadean.input.IMouseListener; + +// TODO BIG IDEAS +// have caches of types that ill need (Like IMouseListener) +// and the add method, simply puts things into the newObjects +// then at the beginning of each frame, they are all loaded. +// then, even userspace scenes can add all their objects in +// one fell swoop and the timings will be maintained +// IE: all objects will be linked and able to be `get`ed +// at their start call! :D public class GameScene implements IScene { @@ -22,6 +34,8 @@ public class GameScene implements IScene { private List removeObjects = new ArrayList(); // private List renderables = new ArrayList(); + private IMouseListener hoveredMouseListener = null; + // specific public T get(Class clazz) { @@ -52,6 +66,7 @@ public class GameScene implements IScene { @Override public void update(float dTime) { + // ADD OBJECTS if(!newObjects.isEmpty()) { List added = new ArrayList(); @@ -66,6 +81,7 @@ public class GameScene implements IScene { } } + // REMOVE OBJECTS if(!removeObjects.isEmpty()) { for(GameObject obj : removeObjects) { objects.remove(obj); @@ -73,8 +89,38 @@ public class GameScene implements IScene { removeObjects.clear(); } + // TICK OBJECTS for(GameObject obj : objects) { - obj.tick(dTime); + obj.update(dTime); + } + + // DO MOUSE UPDATES! + List mouseListeners = getAll(IMouseListener.class); + mouseListeners.sort(new Comparator() { + @Override + public int compare(IMouseListener a, IMouseListener b) { + int al = a.getLayer(); + int bl = b.getLayer(); + return al < bl ? 1 : bl < al ? -1 : 0; + } + }); + for(IMouseListener listener : mouseListeners) { + boolean currentlyEntered = listener.getBox().contains(App.mouseX, App.mouseY); + if(currentlyEntered) { + if(listener != hoveredMouseListener) { + if(hoveredMouseListener != null) { + hoveredMouseListener.mouseLeave(); + } + hoveredMouseListener = listener; + listener.mouseEnter(); + } + break; + } else if(listener == hoveredMouseListener) { + // this is the one that is currently hovered, but it isnt! + // turn that shit OFF + hoveredMouseListener.mouseLeave(); + hoveredMouseListener = null; + } } } @@ -84,6 +130,7 @@ public class GameScene implements IScene { for(int i = 0; i < 5; i ++) { objects.add(new Pawn()); } + objects.add(new Camera()); objects.add(new Selection()); objects.add(new SelectionUI()); @@ -117,5 +164,19 @@ public class GameScene implements IScene { public boolean inScene(GameObject gameObject) { return objects.contains(gameObject); } + + @Override + public void mouseDown(int button) { + for(IMouseListener iml : getAll(IMouseListener.class)) { + iml.mouseDown(button); + } + } + + @Override + public void mouseUp(int button) { + for(IMouseListener iml : getAll(IMouseListener.class)) { + iml.mouseUp(button); + } + } } diff --git a/src/main/java/xyz/valnet/hadean/scenes/MenuScene.java b/src/main/java/xyz/valnet/hadean/scenes/MenuScene.java index fcaa5a5..797d0ae 100644 --- a/src/main/java/xyz/valnet/hadean/scenes/MenuScene.java +++ b/src/main/java/xyz/valnet/hadean/scenes/MenuScene.java @@ -1,7 +1,9 @@ package xyz.valnet.hadean.scenes; +import xyz.valnet.engine.App; import xyz.valnet.engine.math.Vector4f; import xyz.valnet.engine.scenegraph.IScene; +import xyz.valnet.hadean.Layers; import xyz.valnet.hadean.input.Button; import xyz.valnet.hadean.input.IButtonListener; import xyz.valnet.hadean.util.Assets; @@ -10,10 +12,10 @@ import static xyz.valnet.hadean.HadeanGame.Hadean; public class MenuScene implements IScene, IButtonListener { - private Button btnNewGame = new Button(Assets.frame, "New Game", 50, 200, 128, 32); - private Button btnLoadGame = new Button(Assets.frame, "Load Game", 50, 240, 128, 32); - private Button btnOptions = new Button(Assets.frame, "Options", 50, 280, 128, 32); - private Button btnQuit = new Button(Assets.frame, "Quit", 50, 320, 128, 32); + private Button btnNewGame = new Button(Assets.frame, "New Game", 50, 200, 128, 32, Layers.GENERAL_UI); + private Button btnLoadGame = new Button(Assets.frame, "Load Game", 50, 240, 128, 32, Layers.GENERAL_UI); + private Button btnOptions = new Button(Assets.frame, "Options", 50, 280, 128, 32, Layers.GENERAL_UI); + private Button btnQuit = new Button(Assets.frame, "Quit", 50, 320, 128, 32, Layers.GENERAL_UI); public MenuScene() { btnNewGame.registerClickListener(this); @@ -30,18 +32,22 @@ public class MenuScene implements IScene, IButtonListener { @Override public void render() { Assets.flat.pushColor(green); - btnNewGame.draw(); + btnNewGame.render(); Assets.flat.swapColor(cyan); - btnLoadGame.draw(); + btnLoadGame.render(); Assets.flat.swapColor(yellow); - btnOptions.draw(); + btnOptions.render(); Assets.flat.swapColor(red); - btnQuit.draw(); + btnQuit.render(); Assets.flat.popColor(); } @Override public void update(float dTime) { + btnNewGame.setMouseCoords(App.mouseX, App.mouseY); + btnLoadGame.setMouseCoords(App.mouseX, App.mouseY); + btnOptions.setMouseCoords(App.mouseX, App.mouseY); + btnQuit.setMouseCoords(App.mouseX, App.mouseY); btnNewGame.update(); btnLoadGame.update(); btnOptions.update(); @@ -74,5 +80,21 @@ public class MenuScene implements IScene, IButtonListener { public void disable() { } + + @Override + public void mouseDown(int button) { + btnNewGame.mouseDown(button); + btnLoadGame.mouseDown(button); + btnOptions.mouseDown(button); + btnQuit.mouseDown(button); + } + + @Override + public void mouseUp(int button) { + btnNewGame.mouseUp(button); + btnLoadGame.mouseUp(button); + btnOptions.mouseUp(button); + btnQuit.mouseUp(button); + } } diff --git a/src/main/java/xyz/valnet/hadean/util/Assets.java b/src/main/java/xyz/valnet/hadean/util/Assets.java index 49b6818..44b2932 100644 --- a/src/main/java/xyz/valnet/hadean/util/Assets.java +++ b/src/main/java/xyz/valnet/hadean/util/Assets.java @@ -29,6 +29,7 @@ public class Assets { public static final Sprite rocks; public static final Sprite log; public static final Sprite lilAxe; + public static final Sprite haulArrow; public static final SimpleShader flat; @@ -49,6 +50,7 @@ public class Assets { rocks = new Sprite(atlas, 64, 104, 8, 8); log = new Sprite(atlas, 48, 96, 16, 16); lilAxe = new Sprite(atlas, 64, 88, 16, 16); + haulArrow = new Sprite(atlas, 80, 88, 16, 16); Map charset = new HashMap();