Refactored world renderer & world controls.

v5stable
ondra 11 years ago
parent 30857951e0
commit 0860836f85
  1. 7
      src/mightypork/gamecore/control/events/MouseButtonEvent.java
  2. 18
      src/mightypork/gamecore/gui/components/ClickableComponent.java
  3. 21
      src/mightypork/gamecore/gui/components/InputComponent.java
  4. 6
      src/mightypork/gamecore/input/InputSystem.java
  5. 2
      src/mightypork/rogue/App.java
  6. 2
      src/mightypork/rogue/screens/gamescreen/GameGui.java
  7. 2
      src/mightypork/rogue/screens/gamescreen/HeartBar.java
  8. 2
      src/mightypork/rogue/screens/gamescreen/NavItemSlot.java
  9. 2
      src/mightypork/rogue/screens/gamescreen/ScreenGame.java
  10. 115
      src/mightypork/rogue/screens/gamescreen/WRBasicControls.java
  11. 77
      src/mightypork/rogue/screens/gamescreen/WorldLayer.java
  12. 44
      src/mightypork/rogue/screens/gamescreen/WorldRenderComponent.java
  13. 157
      src/mightypork/rogue/screens/ingame/WorldLayer.java
  14. 67
      src/mightypork/rogue/screens/ingame/WorldRenderer.java
  15. 21
      src/mightypork/rogue/world/PathStep.java
  16. 12
      src/mightypork/rogue/world/PlayerControl.java
  17. 21
      src/mightypork/rogue/world/World.java
  18. 181
      src/mightypork/rogue/world/WorldRenderer.java
  19. 12
      src/mightypork/rogue/world/entity/Entity.java
  20. 2
      src/mightypork/rogue/world/entity/models/EntityModel.java
  21. 4
      src/mightypork/rogue/world/entity/models/EntityMoveListener.java
  22. 2
      src/mightypork/rogue/world/entity/models/PlayerModel.java
  23. 4
      src/mightypork/rogue/world/entity/renderers/EntityRenderer.java
  24. 4
      src/mightypork/rogue/world/entity/renderers/NullEntityRenderer.java
  25. 4
      src/mightypork/rogue/world/entity/renderers/PlayerRenderer.java
  26. 101
      src/mightypork/rogue/world/level/Level.java

@ -3,6 +3,7 @@ package mightypork.gamecore.control.events;
import mightypork.util.constraints.rect.proxy.RectBound; import mightypork.util.constraints.rect.proxy.RectBound;
import mightypork.util.constraints.vect.Vect; import mightypork.util.constraints.vect.Vect;
import mightypork.util.constraints.vect.VectConst;
import mightypork.util.control.eventbus.events.Event; import mightypork.util.control.eventbus.events.Event;
@ -19,7 +20,7 @@ public class MouseButtonEvent implements Event<MouseButtonEvent.Listener> {
private final int button; private final int button;
private final int wheeld; private final int wheeld;
private final Vect pos; private final VectConst pos;
private final boolean down; private final boolean down;
@ -35,7 +36,7 @@ public class MouseButtonEvent implements Event<MouseButtonEvent.Listener> {
{ {
this.button = button; this.button = button;
this.down = down; this.down = down;
this.pos = pos; this.pos = pos.freeze();
this.wheeld = wheeld; this.wheeld = wheeld;
} }
@ -79,7 +80,7 @@ public class MouseButtonEvent implements Event<MouseButtonEvent.Listener> {
/** /**
* @return mouse position when the event occurred * @return mouse position when the event occurred
*/ */
public Vect getPos() public VectConst getPos()
{ {
return pos; return pos;
} }

@ -2,11 +2,27 @@ package mightypork.gamecore.gui.components;
import mightypork.gamecore.control.events.MouseButtonEvent; 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 boolean btnDownOver;
private Action action;
@Override
public void setAction(Action action)
{
this.action = action;
}
protected void triggerAction()
{
if (action != null && isEnabled()) action.run();
}
@Override @Override

@ -1,23 +1,13 @@
package mightypork.gamecore.gui.components; 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.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 boolean enabled = true;
private Action action;
@Override
public void setAction(Action action)
{
this.action = action;
}
@Override @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();
} }
} }

@ -210,4 +210,10 @@ public class InputSystem extends RootBusNode implements Updateable, KeyBinder {
{ {
return Keyboard.isKeyDown(key); return Keyboard.isKeyDown(key);
} }
public static boolean isMouseButtonDown(int button)
{
return Mouse.isButtonDown(button);
}
} }

@ -17,7 +17,7 @@ import mightypork.rogue.events.ActionRequest.RequestType;
import mightypork.rogue.screens.CrossfadeOverlay; import mightypork.rogue.screens.CrossfadeOverlay;
import mightypork.rogue.screens.CrossfadeRequest; import mightypork.rogue.screens.CrossfadeRequest;
import mightypork.rogue.screens.FpsOverlay; 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.main_menu.ScreenMainMenu;
import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy; import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy;
import mightypork.rogue.screens.test_cat_sound.ScreenTestCat; import mightypork.rogue.screens.test_cat_sound.ScreenTestCat;

@ -1,4 +1,4 @@
package mightypork.rogue.screens.ingame; package mightypork.rogue.screens.gamescreen;
import mightypork.gamecore.gui.AlignX; import mightypork.gamecore.gui.AlignX;

@ -1,4 +1,4 @@
package mightypork.rogue.screens.ingame; package mightypork.rogue.screens.gamescreen;
import mightypork.gamecore.gui.AlignX; import mightypork.gamecore.gui.AlignX;

@ -1,4 +1,4 @@
package mightypork.rogue.screens.ingame; package mightypork.rogue.screens.gamescreen;
import mightypork.gamecore.control.events.MouseMotionEvent; import mightypork.gamecore.control.events.MouseMotionEvent;

@ -1,4 +1,4 @@
package mightypork.rogue.screens.ingame; package mightypork.rogue.screens.gamescreen;
import mightypork.gamecore.control.AppAccess; import mightypork.gamecore.control.AppAccess;

@ -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();
}
}

@ -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
}
}

@ -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);
}
}

@ -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;
}
}

@ -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);
}
}

@ -14,10 +14,6 @@ public class PathStep implements IonBinary {
public static final PathStep SOUTH = new PathStep(0, 1); public static final PathStep SOUTH = new PathStep(0, 1);
public static final PathStep EAST = new PathStep(1, 0); public static final PathStep EAST = new PathStep(1, 0);
public static final PathStep WEST = 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); 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; x = x < 0 ? -1 : x > 0 ? 1 : 0;
y = y < 0 ? -1 : y > 0 ? 1 : 0; y = y < 0 ? -1 : y > 0 ? 1 : 0;
if (x == 0 && y == -1) return NORTH; if (y == -1) return NORTH;
if (x == 0 && y == 1) return SOUTH; if (y == 1) return SOUTH;
if (x == -1 && y == 0) return WEST; if (x == -1) return WEST;
if (x == 1 && y == 0) return EAST; if (x == 1) return EAST;
if (x == -1 && y == -1) return NORTH_WEST; return NONE;
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);
} }
public static final int ION_MARK = 0; public static final int ION_MARK = 0;

@ -43,4 +43,16 @@ public class PlayerControl {
{ {
world.playerEntity.addMoveListener(eml); world.playerEntity.addMoveListener(eml);
} }
public WorldPos getPos()
{
return world.playerEntity.getPosition();
}
public void walk(PathStep step)
{
world.playerEntity.addStep(step);
}
} }

@ -7,7 +7,6 @@ import java.util.ArrayList;
import mightypork.rogue.world.entity.Entities; import mightypork.rogue.world.entity.Entities;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.Level;
import mightypork.util.constraints.rect.proxy.RectBound;
import mightypork.util.control.timing.Updateable; import mightypork.util.control.timing.Updateable;
import mightypork.util.ion.IonBundle; import mightypork.util.ion.IonBundle;
import mightypork.util.ion.IonBundled; 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() public Level getCurrentLevel()
{ {
return levels.get(player.getLevel()); return levels.get(player.getLevel());
@ -129,4 +114,10 @@ public class World implements IonBundled, Updateable {
{ {
return control; return control;
} }
public Entity getPlayerEntity()
{
return playerEntity;
}
} }

@ -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();
}
}

@ -13,7 +13,7 @@ import mightypork.rogue.world.WorldPos;
import mightypork.rogue.world.entity.models.EntityModel; import mightypork.rogue.world.entity.models.EntityModel;
import mightypork.rogue.world.entity.models.EntityMoveListener; import mightypork.rogue.world.entity.models.EntityMoveListener;
import mightypork.rogue.world.level.Level; 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.IonBinary;
import mightypork.util.ion.IonBundle; import mightypork.util.ion.IonBundle;
import mightypork.util.ion.IonBundled; import mightypork.util.ion.IonBundled;
@ -188,13 +188,13 @@ public final class Entity implements IonBinary, IonBundled, EntityMoveListener {
walking = true; walking = true;
final PathStep step = path.poll(); PathStep step = path.poll();
final int projX = position.x + step.x, projY = position.y + step.y; final int projX = position.x + step.x, projY = position.y + step.y;
if (!level.canWalkInto(projX, projY)) { if (!level.canWalkInto(projX, projY)) {
cancelPath(); cancelPath();
onPathAborted(this, world, level); onPathInterrupted(this, world, level);
walking = false; walking = false;
} else { } 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); model.renderer.render(this, context);
} }
@ -263,10 +263,10 @@ public final class Entity implements IonBinary, IonBundled, EntityMoveListener {
@Override @Override
public void onPathAborted(Entity entity, World world, Level level) public void onPathInterrupted(Entity entity, World world, Level level)
{ {
for (final EntityMoveListener l : moveListeners) { for (final EntityMoveListener l : moveListeners) {
l.onPathAborted(entity, world, level); l.onPathInterrupted(entity, world, level);
} }
} }

@ -71,6 +71,6 @@ public abstract class EntityModel implements EntityMoveListener {
@Override @Override
public abstract void onPathAborted(Entity entity, World world, Level level); public abstract void onPathInterrupted(Entity entity, World world, Level level);
} }

@ -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);
} }

@ -69,7 +69,7 @@ public class PlayerModel extends EntityModel {
@Override @Override
public void onPathAborted(Entity entity, World world, Level level) public void onPathInterrupted(Entity entity, World world, Level level)
{ {
} }
} }

@ -2,7 +2,7 @@ package mightypork.rogue.world.entity.renderers;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.level.render.EntityRenderContext; import mightypork.rogue.world.level.render.MapRenderContext;
public abstract class EntityRenderer { public abstract class EntityRenderer {
@ -10,6 +10,6 @@ public abstract class EntityRenderer {
public static final EntityRenderer NONE = new NullEntityRenderer(); public static final EntityRenderer NONE = new NullEntityRenderer();
public abstract void render(Entity entity, EntityRenderContext context); public abstract void render(Entity entity, MapRenderContext context);
} }

@ -2,13 +2,13 @@ package mightypork.rogue.world.entity.renderers;
import mightypork.rogue.world.entity.Entity; 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 { public class NullEntityRenderer extends EntityRenderer {
@Override @Override
public void render(Entity entity, EntityRenderContext context) public void render(Entity entity, MapRenderContext context)
{ {
// hell no // hell no
} }

@ -7,7 +7,7 @@ import mightypork.gamecore.render.textures.TxSheet;
import mightypork.rogue.Res; import mightypork.rogue.Res;
import mightypork.rogue.world.WorldPos; import mightypork.rogue.world.WorldPos;
import mightypork.rogue.world.entity.Entity; 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.constraints.rect.Rect;
import mightypork.util.math.Calc; import mightypork.util.math.Calc;
@ -24,7 +24,7 @@ public class PlayerRenderer extends EntityRenderer {
@Override @Override
public void render(Entity entity, EntityRenderContext context) public void render(Entity entity, MapRenderContext context)
{ {
TxQuad q = sheet.getQuad(Calc.frag(entity.getPosition().getProgress())); TxQuad q = sheet.getQuad(Calc.frag(entity.getPosition().getProgress()));

@ -2,25 +2,17 @@ package mightypork.rogue.world.level;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import mightypork.gamecore.render.Render;
import mightypork.rogue.Res;
import mightypork.rogue.world.World; import mightypork.rogue.world.World;
import mightypork.rogue.world.WorldPos;
import mightypork.rogue.world.entity.Entity; 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.Tile;
import mightypork.rogue.world.tile.Tiles; import mightypork.rogue.world.tile.Tiles;
import mightypork.rogue.world.tile.models.TileModel; 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.IonBinary;
import mightypork.util.ion.IonBundle; import mightypork.util.ion.IonBundle;
import mightypork.util.ion.IonInput; import mightypork.util.ion.IonInput;
@ -37,8 +29,6 @@ public class Level implements MapAccess, IonBinary {
public static final int ION_MARK = 53; public static final int ION_MARK = 53;
private static final boolean USE_BATCH_RENDERING = true;
private int width, height; private int width, height;
/** Array of tiles [y][x] */ /** Array of tiles [y][x] */
@ -53,13 +43,11 @@ public class Level implements MapAccess, IonBinary {
private transient NoiseGen noiseGen; private transient NoiseGen noiseGen;
public Level() public Level() {
{
} }
public Level(int width, int height) public Level(int width, int height) {
{
this.width = width; this.width = width;
this.height = height; this.height = height;
buildArray(); 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) public Entity getEntity(int eid)
{ {
return entity_map.get(eid); return entity_map.get(eid);
@ -359,4 +270,10 @@ public class Level implements MapAccess, IonBinary {
{ {
getTile(x, y).setOccupied(false); getTile(x, y).setOccupied(false);
} }
public Collection<Entity> getEntities()
{
return entity_set;
}
} }

Loading…
Cancel
Save