diff --git a/src/mightypork/gamecore/control/events/MouseButtonEvent.java b/src/mightypork/gamecore/control/events/MouseButtonEvent.java index 11d66af..924ef0a 100644 --- a/src/mightypork/gamecore/control/events/MouseButtonEvent.java +++ b/src/mightypork/gamecore/control/events/MouseButtonEvent.java @@ -3,6 +3,7 @@ package mightypork.gamecore.control.events; import mightypork.util.constraints.rect.proxy.RectBound; import mightypork.util.constraints.vect.Vect; +import mightypork.util.constraints.vect.VectConst; import mightypork.util.control.eventbus.events.Event; @@ -19,7 +20,7 @@ public class MouseButtonEvent implements Event { private final int button; private final int wheeld; - private final Vect pos; + private final VectConst pos; private final boolean down; @@ -35,7 +36,7 @@ public class MouseButtonEvent implements Event { { this.button = button; this.down = down; - this.pos = pos; + this.pos = pos.freeze(); this.wheeld = wheeld; } @@ -79,7 +80,7 @@ public class MouseButtonEvent implements Event { /** * @return mouse position when the event occurred */ - public Vect getPos() + public VectConst getPos() { return pos; } diff --git a/src/mightypork/gamecore/gui/components/ClickableComponent.java b/src/mightypork/gamecore/gui/components/ClickableComponent.java index a17afef..d76719f 100644 --- a/src/mightypork/gamecore/gui/components/ClickableComponent.java +++ b/src/mightypork/gamecore/gui/components/ClickableComponent.java @@ -2,11 +2,27 @@ package mightypork.gamecore.gui.components; import mightypork.gamecore.control.events.MouseButtonEvent; +import mightypork.util.control.Action; +import mightypork.util.control.ActionTrigger; -public abstract class ClickableComponent extends InputComponent { +public abstract class ClickableComponent extends InputComponent implements ActionTrigger, MouseButtonEvent.Listener { private boolean btnDownOver; + private Action action; + + + @Override + public void setAction(Action action) + { + this.action = action; + } + + + protected void triggerAction() + { + if (action != null && isEnabled()) action.run(); + } @Override diff --git a/src/mightypork/gamecore/gui/components/InputComponent.java b/src/mightypork/gamecore/gui/components/InputComponent.java index 8143ec5..c69aa32 100644 --- a/src/mightypork/gamecore/gui/components/InputComponent.java +++ b/src/mightypork/gamecore/gui/components/InputComponent.java @@ -1,23 +1,13 @@ package mightypork.gamecore.gui.components; -import mightypork.gamecore.control.events.MouseButtonEvent; -import mightypork.util.control.Action; -import mightypork.util.control.ActionTrigger; import mightypork.util.control.Enableable; +import mightypork.util.control.eventbus.clients.ToggleableClient; -public abstract class InputComponent extends VisualComponent implements Enableable, ActionTrigger, MouseButtonEvent.Listener { +public abstract class InputComponent extends VisualComponent implements Enableable, ToggleableClient { - private boolean enabled; - private Action action; - - - @Override - public void setAction(Action action) - { - this.action = action; - } + private boolean enabled = true; @Override @@ -34,8 +24,9 @@ public abstract class InputComponent extends VisualComponent implements Enableab } - protected void triggerAction() + @Override + public boolean isListening() { - if (action != null) action.run(); + return isEnabled(); } } diff --git a/src/mightypork/gamecore/input/InputSystem.java b/src/mightypork/gamecore/input/InputSystem.java index 52d9bfb..c018702 100644 --- a/src/mightypork/gamecore/input/InputSystem.java +++ b/src/mightypork/gamecore/input/InputSystem.java @@ -210,4 +210,10 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder { { return Keyboard.isKeyDown(key); } + + + public static boolean isMouseButtonDown(int button) + { + return Mouse.isButtonDown(button); + } } diff --git a/src/mightypork/rogue/App.java b/src/mightypork/rogue/App.java index c8ef4d8..9e24342 100644 --- a/src/mightypork/rogue/App.java +++ b/src/mightypork/rogue/App.java @@ -17,7 +17,7 @@ import mightypork.rogue.events.ActionRequest.RequestType; import mightypork.rogue.screens.CrossfadeOverlay; import mightypork.rogue.screens.CrossfadeRequest; import mightypork.rogue.screens.FpsOverlay; -import mightypork.rogue.screens.ingame.ScreenGame; +import mightypork.rogue.screens.gamescreen.ScreenGame; import mightypork.rogue.screens.main_menu.ScreenMainMenu; import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy; import mightypork.rogue.screens.test_cat_sound.ScreenTestCat; diff --git a/src/mightypork/rogue/screens/ingame/GameGui.java b/src/mightypork/rogue/screens/gamescreen/GameGui.java similarity index 97% rename from src/mightypork/rogue/screens/ingame/GameGui.java rename to src/mightypork/rogue/screens/gamescreen/GameGui.java index 6728abe..b123fcf 100644 --- a/src/mightypork/rogue/screens/ingame/GameGui.java +++ b/src/mightypork/rogue/screens/gamescreen/GameGui.java @@ -1,4 +1,4 @@ -package mightypork.rogue.screens.ingame; +package mightypork.rogue.screens.gamescreen; import mightypork.gamecore.gui.AlignX; diff --git a/src/mightypork/rogue/screens/ingame/HeartBar.java b/src/mightypork/rogue/screens/gamescreen/HeartBar.java similarity index 96% rename from src/mightypork/rogue/screens/ingame/HeartBar.java rename to src/mightypork/rogue/screens/gamescreen/HeartBar.java index 3773517..7d00a1e 100644 --- a/src/mightypork/rogue/screens/ingame/HeartBar.java +++ b/src/mightypork/rogue/screens/gamescreen/HeartBar.java @@ -1,4 +1,4 @@ -package mightypork.rogue.screens.ingame; +package mightypork.rogue.screens.gamescreen; import mightypork.gamecore.gui.AlignX; diff --git a/src/mightypork/rogue/screens/ingame/NavItemSlot.java b/src/mightypork/rogue/screens/gamescreen/NavItemSlot.java similarity index 97% rename from src/mightypork/rogue/screens/ingame/NavItemSlot.java rename to src/mightypork/rogue/screens/gamescreen/NavItemSlot.java index 1b30faa..b9874ea 100644 --- a/src/mightypork/rogue/screens/ingame/NavItemSlot.java +++ b/src/mightypork/rogue/screens/gamescreen/NavItemSlot.java @@ -1,4 +1,4 @@ -package mightypork.rogue.screens.ingame; +package mightypork.rogue.screens.gamescreen; import mightypork.gamecore.control.events.MouseMotionEvent; diff --git a/src/mightypork/rogue/screens/ingame/ScreenGame.java b/src/mightypork/rogue/screens/gamescreen/ScreenGame.java similarity index 89% rename from src/mightypork/rogue/screens/ingame/ScreenGame.java rename to src/mightypork/rogue/screens/gamescreen/ScreenGame.java index e9c90db..0de6641 100644 --- a/src/mightypork/rogue/screens/ingame/ScreenGame.java +++ b/src/mightypork/rogue/screens/gamescreen/ScreenGame.java @@ -1,4 +1,4 @@ -package mightypork.rogue.screens.ingame; +package mightypork.rogue.screens.gamescreen; import mightypork.gamecore.control.AppAccess; diff --git a/src/mightypork/rogue/screens/gamescreen/WRBasicControls.java b/src/mightypork/rogue/screens/gamescreen/WRBasicControls.java new file mode 100644 index 0000000..59d090e --- /dev/null +++ b/src/mightypork/rogue/screens/gamescreen/WRBasicControls.java @@ -0,0 +1,115 @@ +package mightypork.rogue.screens.gamescreen; + + +import mightypork.rogue.world.PlayerControl; +import mightypork.rogue.world.World; +import mightypork.rogue.world.WorldPos; +import mightypork.rogue.world.entity.Entity; +import mightypork.rogue.world.entity.models.EntityMoveListener; +import mightypork.rogue.world.level.Level; +import mightypork.util.constraints.vect.Vect; +import mightypork.util.math.Polar; +import mightypork.util.math.Calc.Deg; +import mightypork.gamecore.control.events.KeyEvent; +import mightypork.gamecore.control.events.MouseButtonEvent; +import mightypork.gamecore.input.InputSystem; +import mightypork.gamecore.input.Keys; + + +public class WRBasicControls extends WorldRenderComponent implements KeyEvent.Listener, MouseButtonEvent.Listener, EntityMoveListener { + + private final PlayerControl pc; + + + public WRBasicControls(World world) { + super(world); + pc = world.getPlayerControl(); + pc.addMoveListener(this); + } + + + private void handleHeldKey() + { + if (InputSystem.isKeyDown(Keys.LEFT)) { + pc.walkWest(); + } else if (InputSystem.isKeyDown(Keys.RIGHT)) { + pc.walkEast(); + } else if (InputSystem.isKeyDown(Keys.UP)) { + pc.walkNorth(); + } else if (InputSystem.isKeyDown(Keys.DOWN)) { + pc.walkSouth(); + } + + if(InputSystem.isMouseButtonDown(0)) { + walkByMouse(InputSystem.getMousePos()); + } + } + + + @Override + public void onStepFinished(Entity entity, World world, Level level) + { + handleHeldKey(); + } + + + @Override + public void onPathFinished(Entity entity, World world, Level level) + { + handleHeldKey(); + } + + + @Override + public void onPathInterrupted(Entity entity, World world, Level level) + { + handleHeldKey(); + } + + + @Override + public void receive(MouseButtonEvent event) + { + if (!event.isDown()) return; + + walkByMouse(event.getPos()); + } + + + private void walkByMouse(Vect mouse) + { + + WorldPos clicked = toWorldPos(mouse); + WorldPos plpos = pc.getPos(); + + Polar p = Polar.fromCoord(clicked.x - plpos.x, clicked.y - plpos.y); + + int dir = Deg.round90(p.getAngleDeg()) / 90; + + switch (dir) { + case 0: + pc.walkEast(); + return; + + case 1: + pc.walkSouth(); + return; + + case 2: + pc.walkWest(); + return; + + case 3: + pc.walkNorth(); + return; + } + } + + + @Override + public void receive(KeyEvent event) + { + handleHeldKey(); + } + +} diff --git a/src/mightypork/rogue/screens/gamescreen/WorldLayer.java b/src/mightypork/rogue/screens/gamescreen/WorldLayer.java new file mode 100644 index 0000000..b1bcfd7 --- /dev/null +++ b/src/mightypork/rogue/screens/gamescreen/WorldLayer.java @@ -0,0 +1,77 @@ +package mightypork.rogue.screens.gamescreen; + + +import java.io.File; +import java.io.IOException; +import java.util.Random; + +import mightypork.gamecore.gui.components.InputComponent; +import mightypork.gamecore.gui.screens.Screen; +import mightypork.gamecore.gui.screens.ScreenLayer; +import mightypork.rogue.Paths; +import mightypork.rogue.world.MapGenerator; +import mightypork.rogue.world.World; +import mightypork.util.constraints.num.Num; +import mightypork.util.ion.Ion; + + +public class WorldLayer extends ScreenLayer { + + private World world; + private InputComponent worldView; + + + public WorldLayer(Screen screen) { + super(screen); + + // FIXME just temporary test here + + final Random rand = new Random(); + final File f = new File(Paths.WORKDIR, "test-world.ion"); + + // SAVE + + world = MapGenerator.createWorld(rand.nextLong()); + updated.add(world); + + try { + Ion.toFile(f, world); + } catch (final IOException e) { + e.printStackTrace(); + System.exit(1); // fail + return; + } + + // LOAD + +// final World w; +// +// try { +// world = Ion.fromFile(f, World.class); +// } catch (IOException e) { +// e.printStackTrace(); +// System.exit(1); +// return; +// } + + + + // render component + + worldView = new WRBasicControls(world); + + // size of lower navbar + final Num lownav = root.width().min(root.height()).max(700).perc(7); + worldView.setRect(root.shrinkBottom(lownav)); + + root.add(worldView); + } + + + @Override + public int getPriority() + { + return -1; // stay down + } + +} diff --git a/src/mightypork/rogue/screens/gamescreen/WorldRenderComponent.java b/src/mightypork/rogue/screens/gamescreen/WorldRenderComponent.java new file mode 100644 index 0000000..c07751f --- /dev/null +++ b/src/mightypork/rogue/screens/gamescreen/WorldRenderComponent.java @@ -0,0 +1,44 @@ +package mightypork.rogue.screens.gamescreen; + + +import mightypork.gamecore.gui.components.InputComponent; +import mightypork.rogue.world.World; +import mightypork.rogue.world.WorldPos; +import mightypork.rogue.world.WorldRenderer; +import mightypork.util.constraints.vect.Vect; + + +public class WorldRenderComponent extends InputComponent { + + protected final WorldRenderer worldRenderer; + protected final World world; + + + public WorldRenderComponent(World world) { + this.world = world; + this.worldRenderer = new WorldRenderer(world, this, 8, 6, 72); + } + + + @Override + protected void renderComponent() + { + worldRenderer.render(); + } + + + @Override + public void updateLayout() + { + worldRenderer.poll(); // update sizing + } + + + /** + * Get tile coord at a screen position + */ + public WorldPos toWorldPos(Vect pos) + { + return worldRenderer.getClickedTile(pos); + } +} diff --git a/src/mightypork/rogue/screens/ingame/WorldLayer.java b/src/mightypork/rogue/screens/ingame/WorldLayer.java deleted file mode 100644 index 756530c..0000000 --- a/src/mightypork/rogue/screens/ingame/WorldLayer.java +++ /dev/null @@ -1,157 +0,0 @@ -package mightypork.rogue.screens.ingame; - - -import java.io.File; -import java.io.IOException; -import java.util.Random; - -import mightypork.gamecore.gui.screens.Screen; -import mightypork.gamecore.gui.screens.ScreenLayer; -import mightypork.gamecore.input.InputSystem; -import mightypork.gamecore.input.KeyStroke; -import mightypork.gamecore.input.Keys; -import mightypork.rogue.Paths; -import mightypork.rogue.world.MapGenerator; -import mightypork.rogue.world.PlayerControl; -import mightypork.rogue.world.World; -import mightypork.rogue.world.entity.Entity; -import mightypork.rogue.world.entity.models.EntityMoveListener; -import mightypork.rogue.world.level.Level; -import mightypork.util.constraints.num.Num; -import mightypork.util.ion.Ion; - - -public class WorldLayer extends ScreenLayer { - - public WorldLayer(Screen screen) - { - super(screen); - - // FIXME just temporary test here - - final Random rand = new Random(); - final File f = new File(Paths.WORKDIR, "test-world.ion"); - final World w = MapGenerator.createWorld(rand.nextLong()); - - try { - Ion.toFile(f, w); - } catch (final IOException e) { - e.printStackTrace(); - System.exit(1); - return; - } - -// final World w; -// -// try { -// w = Ion.fromFile(f, World.class); -// } catch (IOException e) { -// e.printStackTrace(); -// System.exit(1); -// return; -// } - - final Num minWH = root.width().min(root.height()).max(700); // avoid too small shrinking - - final WorldRenderer wr = new WorldRenderer(w); - wr.setRect(root.shrinkBottom(minWH.perc(7))); - root.add(wr); - - final PlayerControl c = w.getPlayerControl(); - - bindKey(new KeyStroke(true, Keys.LEFT), new Runnable() { - - @Override - public void run() - { - c.walkWest(); - } - }); - - bindKey(new KeyStroke(true, Keys.RIGHT), new Runnable() { - - @Override - public void run() - { - c.walkEast(); - } - }); - - bindKey(new KeyStroke(true, Keys.UP), new Runnable() { - - @Override - public void run() - { - c.walkNorth(); - } - }); - - bindKey(new KeyStroke(true, Keys.DOWN), new Runnable() { - - @Override - public void run() - { - c.walkSouth(); - } - }); - - bindKey(new KeyStroke(Keys.L_CONTROL, Keys.S), new Runnable() { - - @Override - public void run() - { - try { - Ion.toFile(f, w); - } catch (final IOException e) { - e.printStackTrace(); - } - } - }); - - c.addMoveListener(new EntityMoveListener() { - - private void tryGo(Entity entity) - { - if (InputSystem.isKeyDown(Keys.LEFT)) { - c.walkWest(); - } else if (InputSystem.isKeyDown(Keys.RIGHT)) { - c.walkEast(); - } else if (InputSystem.isKeyDown(Keys.UP)) { - c.walkNorth(); - } else if (InputSystem.isKeyDown(Keys.DOWN)) { - c.walkSouth(); - } - } - - - @Override - public void onStepFinished(Entity entity, World world, Level level) - { - entity.cancelPath(); // halt - tryGo(entity); - } - - - @Override - public void onPathFinished(Entity entity, World world, Level level) - { - entity.cancelPath(); // halt - tryGo(entity); - } - - - @Override - public void onPathAborted(Entity entity, World world, Level level) - { - } - }); - } - - - @Override - public int getPriority() - { - return -1; - } - -} diff --git a/src/mightypork/rogue/screens/ingame/WorldRenderer.java b/src/mightypork/rogue/screens/ingame/WorldRenderer.java deleted file mode 100644 index d834f96..0000000 --- a/src/mightypork/rogue/screens/ingame/WorldRenderer.java +++ /dev/null @@ -1,67 +0,0 @@ -package mightypork.rogue.screens.ingame; - - -import mightypork.gamecore.control.events.MouseButtonEvent; -import mightypork.gamecore.gui.components.InputComponent; -import mightypork.gamecore.render.Render; -import mightypork.rogue.world.World; -import mightypork.util.constraints.num.Num; -import mightypork.util.constraints.rect.Rect; -import mightypork.util.control.timing.Updateable; -import mightypork.util.math.color.RGB; - - -public class WorldRenderer extends InputComponent implements Updateable { - - private final World world; - private final Rect rightShadow; - private final Rect leftShadow; - private final Rect topShadow; - private final Rect bottomShadow; - - - public WorldRenderer(World world) - { - this.world = world; - - final Num h = height(); - final Num w = width(); - final Num minWH = w.min(h).max(700); - - final Num grX = w.perc(30); - final Num grY = h.perc(20); - - leftShadow = leftEdge().growRight(grX); - rightShadow = rightEdge().growLeft(grX); - topShadow = topEdge().growDown(grY); - bottomShadow = bottomEdge().growUp(grY); //.moveY(minWH.perc(-6)) - } - - - @Override - public void receive(MouseButtonEvent event) - { - System.out.println("world clciked, yo"); - } - - - @Override - protected void renderComponent() - { - world.render(this, 8, 7, 100); - - Render.quadGradH(leftShadow, RGB.BLACK, RGB.NONE); - Render.quadGradH(rightShadow, RGB.NONE, RGB.BLACK); - - Render.quadGradV(topShadow, RGB.BLACK, RGB.NONE); - Render.quadGradV(bottomShadow, RGB.NONE, RGB.BLACK); - } - - - @Override - public void update(double delta) - { - world.update(delta); - } - -} diff --git a/src/mightypork/rogue/world/PathStep.java b/src/mightypork/rogue/world/PathStep.java index b5b7174..4a5ce14 100644 --- a/src/mightypork/rogue/world/PathStep.java +++ b/src/mightypork/rogue/world/PathStep.java @@ -14,10 +14,6 @@ public class PathStep implements IonBinary { public static final PathStep SOUTH = new PathStep(0, 1); public static final PathStep EAST = new PathStep(1, 0); public static final PathStep WEST = new PathStep(-1, 0); - public static final PathStep NORTH_EAST = new PathStep(1, -1); - public static final PathStep NORTH_WEST = new PathStep(-1, -1); - public static final PathStep SOUTH_EAST = new PathStep(1, 1); - public static final PathStep SOUTH_WEST = new PathStep(-1, 1); public static final PathStep NONE = new PathStep(0, 0); @@ -26,19 +22,12 @@ public class PathStep implements IonBinary { x = x < 0 ? -1 : x > 0 ? 1 : 0; y = y < 0 ? -1 : y > 0 ? 1 : 0; - if (x == 0 && y == -1) return NORTH; - if (x == 0 && y == 1) return SOUTH; - if (x == -1 && y == 0) return WEST; - if (x == 1 && y == 0) return EAST; + if (y == -1) return NORTH; + if (y == 1) return SOUTH; + if (x == -1) return WEST; + if (x == 1) return EAST; - if (x == -1 && y == -1) return NORTH_WEST; - if (x == 1 && y == -1) return NORTH_EAST; - if (x == -1 && y == 1) return SOUTH_WEST; - if (x == 1 && y == 1) return SOUTH_EAST; - - if (x == 0 && y == 0) return NONE; - - return new PathStep(x, y); + return NONE; } public static final int ION_MARK = 0; diff --git a/src/mightypork/rogue/world/PlayerControl.java b/src/mightypork/rogue/world/PlayerControl.java index 14982ca..0052c8c 100644 --- a/src/mightypork/rogue/world/PlayerControl.java +++ b/src/mightypork/rogue/world/PlayerControl.java @@ -43,4 +43,16 @@ public class PlayerControl { { world.playerEntity.addMoveListener(eml); } + + + public WorldPos getPos() + { + return world.playerEntity.getPosition(); + } + + + public void walk(PathStep step) + { + world.playerEntity.addStep(step); + } } diff --git a/src/mightypork/rogue/world/World.java b/src/mightypork/rogue/world/World.java index 3130024..f467ec7 100644 --- a/src/mightypork/rogue/world/World.java +++ b/src/mightypork/rogue/world/World.java @@ -7,7 +7,6 @@ import java.util.ArrayList; import mightypork.rogue.world.entity.Entities; import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.level.Level; -import mightypork.util.constraints.rect.proxy.RectBound; import mightypork.util.control.timing.Updateable; import mightypork.util.ion.IonBundle; import mightypork.util.ion.IonBundled; @@ -105,20 +104,6 @@ public class World implements IonBundled, Updateable { } - /** - * Draw on screen - * - * @param viewport rendering area on screen - * @param xTiles Desired nr of tiles horizontally - * @param yTiles Desired nr of tiles vertically - * @param minSize minimum tile size - */ - public void render(RectBound viewport, final int xTiles, final int yTiles, final int minSize) - { - getCurrentLevel().render(playerEntity.getPosition(), viewport, xTiles, yTiles, minSize); - } - - public Level getCurrentLevel() { return levels.get(player.getLevel()); @@ -129,4 +114,10 @@ public class World implements IonBundled, Updateable { { return control; } + + + public Entity getPlayerEntity() + { + return playerEntity; + } } diff --git a/src/mightypork/rogue/world/WorldRenderer.java b/src/mightypork/rogue/world/WorldRenderer.java new file mode 100644 index 0000000..3b65d71 --- /dev/null +++ b/src/mightypork/rogue/world/WorldRenderer.java @@ -0,0 +1,181 @@ +package mightypork.rogue.world; + + +import mightypork.gamecore.render.Render; +import mightypork.rogue.Res; +import mightypork.rogue.world.entity.Entity; +import mightypork.rogue.world.level.Level; +import mightypork.rogue.world.level.render.TileRenderContext; +import mightypork.util.constraints.Pollable; +import mightypork.util.constraints.num.Num; +import mightypork.util.constraints.num.caching.NumCache; +import mightypork.util.constraints.rect.Rect; +import mightypork.util.constraints.rect.RectConst; +import mightypork.util.constraints.rect.caching.RectCache; +import mightypork.util.constraints.rect.proxy.RectProxy; +import mightypork.util.constraints.vect.Vect; +import mightypork.util.constraints.vect.caching.VectCache; +import mightypork.util.math.color.RGB; + + +/** + * World rendering untility + * + * @author MightyPork + */ +public class WorldRenderer extends RectProxy implements Pollable { + + private static final boolean USE_BATCH_RENDERING = true; + + private final VectCache vpCenter; + private final NumCache tileSize; + + private final World world; + private final Entity player; + + // can be changed + private RectCache mapRect; + private Level activeLevel; + + private final Rect rightShadow; + private final Rect leftShadow; + private final Rect topShadow; + private final Rect bottomShadow; + + + public WorldRenderer(World world, Rect viewport, int xTiles, int yTiles, int minTileSize) { + super(viewport); + + this.world = world; + this.player = world.playerEntity; + + tileSize = width().div(xTiles).min(height().div(yTiles)).max(minTileSize).cached(); + + final Num th = tileSize.half(); + vpCenter = center().sub(th, th).cached(); + + final Num grX = width().perc(30); + leftShadow = leftEdge().growRight(grX); + rightShadow = rightEdge().growLeft(grX); + + final Num grY = height().perc(20); + topShadow = topEdge().growDown(grY); + bottomShadow = bottomEdge().growUp(grY); + + setupMapRect(); + } + + + private void setupMapRect() + { + Level level = world.getCurrentLevel(); + + if (activeLevel == level) return; + activeLevel = level; + + mapRect = Rect.make(vpCenter, tileSize.mul(level.getWidth()), tileSize.mul(level.getHeight())).cached(); + } + + + private RectConst getCurrentDrawRect() + { + + WorldPos pos = player.getPosition(); + final double playerX = pos.getVisualX(); + final double playerY = pos.getVisualY(); + + double ts = tileSize.value(); + + final RectConst drawRect = mapRect.move(-ts * playerX, -ts * playerY).freeze(); + + return drawRect; + } + + + public void render() + { + setupMapRect(); + + final TileRenderContext rc = new TileRenderContext(activeLevel, getCurrentDrawRect()); + + // tiles to render + final WorldPos pos = player.getPosition(); + final double w = width().value(); + final double h = height().value(); + final double ts = tileSize.value(); + final double tsh = ts / 2; + + final int x1 = (int) Math.floor(pos.x - (w / tsh)); + final int y1 = (int) Math.floor(pos.y - (h / tsh)); + final int x2 = (int) Math.ceil(pos.x + (w / tsh)); + final int y2 = (int) Math.ceil(pos.y + (h / tsh)); + + // === TILES === + + // batch rendering of the tiles + if (USE_BATCH_RENDERING) { + Render.enterBatchTexturedQuadMode(Res.getTexture("tiles16")); + } + + for (rc.y = y1; rc.y <= y2; rc.y++) { + for (rc.x = x1; rc.x <= x2; rc.x++) { + rc.renderTile(); + } + } + + if (USE_BATCH_RENDERING) { + Render.leaveBatchTexturedQuadMode(); + } + + // === ITEMS ON TILES === + + for (rc.y = y1; rc.y <= y2; rc.y++) { + for (rc.x = x1; rc.x <= x2; rc.x++) { + rc.renderItems(); + } + } + + // === ENTITIES === + + for (final Entity e : activeLevel.getEntities()) { + + // avoid entities out of view rect + int x = (int) Math.round(e.getPosition().getVisualX()); + int y = (int) Math.round(e.getPosition().getVisualY()); + + if (x < x1 - ts || x > x2 + ts) continue; + if (y < y1 - ts || y > y2 + ts) continue; + + e.render(rc); + } + + // === OVERLAY SHADOW === + + Render.quadGradH(leftShadow, RGB.BLACK, RGB.NONE); + Render.quadGradH(rightShadow, RGB.NONE, RGB.BLACK); + + Render.quadGradV(topShadow, RGB.BLACK, RGB.NONE); + Render.quadGradV(bottomShadow, RGB.NONE, RGB.BLACK); + } + + + public WorldPos getClickedTile(Vect clickPos) + { + RectConst drawRect = getCurrentDrawRect(); + Vect v = clickPos.sub(drawRect.origin()); + int ts = (int)tileSize.value(); + return new WorldPos(v.xi() / ts, v.yi() / ts); + } + + + @Override + public void poll() + { + // in order of dependency + vpCenter.poll(); + tileSize.poll(); + + mapRect.poll(); + } + +} diff --git a/src/mightypork/rogue/world/entity/Entity.java b/src/mightypork/rogue/world/entity/Entity.java index 182b2ac..49498fa 100644 --- a/src/mightypork/rogue/world/entity/Entity.java +++ b/src/mightypork/rogue/world/entity/Entity.java @@ -13,7 +13,7 @@ import mightypork.rogue.world.WorldPos; import mightypork.rogue.world.entity.models.EntityModel; import mightypork.rogue.world.entity.models.EntityMoveListener; import mightypork.rogue.world.level.Level; -import mightypork.rogue.world.level.render.EntityRenderContext; +import mightypork.rogue.world.level.render.MapRenderContext; import mightypork.util.ion.IonBinary; import mightypork.util.ion.IonBundle; import mightypork.util.ion.IonBundled; @@ -188,13 +188,13 @@ public final class Entity implements IonBinary, IonBundled, EntityMoveListener { walking = true; - final PathStep step = path.poll(); + PathStep step = path.poll(); final int projX = position.x + step.x, projY = position.y + step.y; if (!level.canWalkInto(projX, projY)) { cancelPath(); - onPathAborted(this, world, level); + onPathInterrupted(this, world, level); walking = false; } else { @@ -214,7 +214,7 @@ public final class Entity implements IonBinary, IonBundled, EntityMoveListener { } - public void render(EntityRenderContext context) + public void render(MapRenderContext context) { model.renderer.render(this, context); } @@ -263,10 +263,10 @@ public final class Entity implements IonBinary, IonBundled, EntityMoveListener { @Override - public void onPathAborted(Entity entity, World world, Level level) + public void onPathInterrupted(Entity entity, World world, Level level) { for (final EntityMoveListener l : moveListeners) { - l.onPathAborted(entity, world, level); + l.onPathInterrupted(entity, world, level); } } diff --git a/src/mightypork/rogue/world/entity/models/EntityModel.java b/src/mightypork/rogue/world/entity/models/EntityModel.java index c9c126a..136cf9d 100644 --- a/src/mightypork/rogue/world/entity/models/EntityModel.java +++ b/src/mightypork/rogue/world/entity/models/EntityModel.java @@ -71,6 +71,6 @@ public abstract class EntityModel implements EntityMoveListener { @Override - public abstract void onPathAborted(Entity entity, World world, Level level); + public abstract void onPathInterrupted(Entity entity, World world, Level level); } diff --git a/src/mightypork/rogue/world/entity/models/EntityMoveListener.java b/src/mightypork/rogue/world/entity/models/EntityMoveListener.java index 110e1df..7c6a7c0 100644 --- a/src/mightypork/rogue/world/entity/models/EntityMoveListener.java +++ b/src/mightypork/rogue/world/entity/models/EntityMoveListener.java @@ -21,8 +21,8 @@ public interface EntityMoveListener { /** - * Path was aborted (bumped into a wall or entity) + * Path was interrupted (bumped into a wall or entity) */ - void onPathAborted(Entity entity, World world, Level level); + void onPathInterrupted(Entity entity, World world, Level level); } diff --git a/src/mightypork/rogue/world/entity/models/PlayerModel.java b/src/mightypork/rogue/world/entity/models/PlayerModel.java index 937c7fb..2e281bf 100644 --- a/src/mightypork/rogue/world/entity/models/PlayerModel.java +++ b/src/mightypork/rogue/world/entity/models/PlayerModel.java @@ -69,7 +69,7 @@ public class PlayerModel extends EntityModel { @Override - public void onPathAborted(Entity entity, World world, Level level) + public void onPathInterrupted(Entity entity, World world, Level level) { } } diff --git a/src/mightypork/rogue/world/entity/renderers/EntityRenderer.java b/src/mightypork/rogue/world/entity/renderers/EntityRenderer.java index 3251867..ff5f3db 100644 --- a/src/mightypork/rogue/world/entity/renderers/EntityRenderer.java +++ b/src/mightypork/rogue/world/entity/renderers/EntityRenderer.java @@ -2,7 +2,7 @@ package mightypork.rogue.world.entity.renderers; import mightypork.rogue.world.entity.Entity; -import mightypork.rogue.world.level.render.EntityRenderContext; +import mightypork.rogue.world.level.render.MapRenderContext; public abstract class EntityRenderer { @@ -10,6 +10,6 @@ public abstract class EntityRenderer { public static final EntityRenderer NONE = new NullEntityRenderer(); - public abstract void render(Entity entity, EntityRenderContext context); + public abstract void render(Entity entity, MapRenderContext context); } diff --git a/src/mightypork/rogue/world/entity/renderers/NullEntityRenderer.java b/src/mightypork/rogue/world/entity/renderers/NullEntityRenderer.java index 012d658..0fe0d97 100644 --- a/src/mightypork/rogue/world/entity/renderers/NullEntityRenderer.java +++ b/src/mightypork/rogue/world/entity/renderers/NullEntityRenderer.java @@ -2,13 +2,13 @@ package mightypork.rogue.world.entity.renderers; import mightypork.rogue.world.entity.Entity; -import mightypork.rogue.world.level.render.EntityRenderContext; +import mightypork.rogue.world.level.render.MapRenderContext; public class NullEntityRenderer extends EntityRenderer { @Override - public void render(Entity entity, EntityRenderContext context) + public void render(Entity entity, MapRenderContext context) { // hell no } diff --git a/src/mightypork/rogue/world/entity/renderers/PlayerRenderer.java b/src/mightypork/rogue/world/entity/renderers/PlayerRenderer.java index adb2a94..91c40a4 100644 --- a/src/mightypork/rogue/world/entity/renderers/PlayerRenderer.java +++ b/src/mightypork/rogue/world/entity/renderers/PlayerRenderer.java @@ -7,7 +7,7 @@ import mightypork.gamecore.render.textures.TxSheet; import mightypork.rogue.Res; import mightypork.rogue.world.WorldPos; import mightypork.rogue.world.entity.Entity; -import mightypork.rogue.world.level.render.EntityRenderContext; +import mightypork.rogue.world.level.render.MapRenderContext; import mightypork.util.constraints.rect.Rect; import mightypork.util.math.Calc; @@ -24,7 +24,7 @@ public class PlayerRenderer extends EntityRenderer { @Override - public void render(Entity entity, EntityRenderContext context) + public void render(Entity entity, MapRenderContext context) { TxQuad q = sheet.getQuad(Calc.frag(entity.getPosition().getProgress())); diff --git a/src/mightypork/rogue/world/level/Level.java b/src/mightypork/rogue/world/level/Level.java index 781a5f1..e1c30c1 100644 --- a/src/mightypork/rogue/world/level/Level.java +++ b/src/mightypork/rogue/world/level/Level.java @@ -2,25 +2,17 @@ package mightypork.rogue.world.level; import java.io.IOException; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import mightypork.gamecore.render.Render; -import mightypork.rogue.Res; import mightypork.rogue.world.World; -import mightypork.rogue.world.WorldPos; import mightypork.rogue.world.entity.Entity; -import mightypork.rogue.world.level.render.EntityRenderContext; -import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.tile.Tile; import mightypork.rogue.world.tile.Tiles; import mightypork.rogue.world.tile.models.TileModel; -import mightypork.util.constraints.rect.Rect; -import mightypork.util.constraints.rect.RectConst; -import mightypork.util.constraints.rect.proxy.RectBound; -import mightypork.util.constraints.vect.VectConst; import mightypork.util.ion.IonBinary; import mightypork.util.ion.IonBundle; import mightypork.util.ion.IonInput; @@ -37,8 +29,6 @@ public class Level implements MapAccess, IonBinary { public static final int ION_MARK = 53; - private static final boolean USE_BATCH_RENDERING = true; - private int width, height; /** Array of tiles [y][x] */ @@ -53,13 +43,11 @@ public class Level implements MapAccess, IonBinary { private transient NoiseGen noiseGen; - public Level() - { + public Level() { } - public Level(int width, int height) - { + public Level(int width, int height) { this.width = width; this.height = height; buildArray(); @@ -231,83 +219,6 @@ public class Level implements MapAccess, IonBinary { } - /** - * Draw on screen - * - * @param playerInfo layer - * @param viewport rendering area on screen - * @param xTiles Desired nr of tiles horizontally - * @param yTiles Desired nr of tiles vertically - * @param minSize minimum tile size - */ - public void render(WorldPos pos, RectBound viewport, final int xTiles, final int yTiles, final int minSize) - { - final Rect r = viewport.getRect(); - final double vpH = r.height().value(); - final double vpW = r.width().value(); - - // adjust tile size to fit desired amount of tiles - - final double allowedSizeW = vpW / xTiles; - final double allowedSizeH = vpH / yTiles; - final int tileSize = (int) Math.round(Math.max(Math.min(allowedSizeH, allowedSizeW), minSize)); - - //tileSize -= tileSize % 8; - - final VectConst vpCenter = r.center().sub(tileSize * 0.5, tileSize * 0.5).freeze(); // 0.5 to center, 1 to move up (down is teh navbar) - - final double playerX = pos.getVisualX(); - final double playerY = pos.getVisualY(); - - // total map area - //@formatter:off - final RectConst mapRect = vpCenter.startRect().grow( - playerX*tileSize, - (getWidth() - playerX) * tileSize, - playerY*tileSize, - (getHeight() - playerY) * tileSize - ).freeze(); - //@formatter:on - - // tiles to render - final int x1 = (int) Math.floor(playerX - (vpW / tileSize / 2)); - - final int y1 = (int) Math.floor(playerY - (vpH / tileSize / 2)); - final int x2 = (int) Math.ceil(playerX + (vpW / tileSize / 2)); - final int y2 = (int) Math.ceil(playerY + (vpH / tileSize / 2)); - - final TileRenderContext trc = new TileRenderContext(this, mapRect); //-tileSize*0.5 - - // batch rendering of the tiles - if (USE_BATCH_RENDERING) { - Render.enterBatchTexturedQuadMode(Res.getTexture("tiles16")); - } - - for (trc.y = y1; trc.y <= y2; trc.y++) { - for (trc.x = x1; trc.x <= x2; trc.x++) { - trc.renderTile(); - } - } - - if (USE_BATCH_RENDERING) { - Render.leaveBatchTexturedQuadMode(); - } - - // render extras - for (trc.y = y1; trc.y <= y2; trc.y++) { - for (trc.x = x1; trc.x <= x2; trc.x++) { - trc.renderItems(); - } - } - - // render entities - final EntityRenderContext erc = new EntityRenderContext(this, mapRect); - for (final Entity e : entity_set) { - e.render(erc); - } - } - - public Entity getEntity(int eid) { return entity_map.get(eid); @@ -359,4 +270,10 @@ public class Level implements MapAccess, IonBinary { { getTile(x, y).setOccupied(false); } + + + public Collection getEntities() + { + return entity_set; + } }