ufog, green hat, map zoom, Sides, remade tile renderers

v5stable
ondra 10 years ago
parent a24d6c37a4
commit 307d8d2b10
  1. BIN
      res/img/dudes-b.png
  2. BIN
      res/img/dudes.xcf
  3. BIN
      res/img/tiles16.png
  4. BIN
      res/img/tiles16.xcf
  5. 25
      src/mightypork/rogue/Res.java
  6. 29
      src/mightypork/rogue/screens/gamescreen/world/MapView.java
  7. 45
      src/mightypork/rogue/world/Sides.java
  8. 41
      src/mightypork/rogue/world/WorldRenderer.java
  9. 53
      src/mightypork/rogue/world/gen/ScratchMap.java
  10. 3
      src/mightypork/rogue/world/gen/rooms/SimpleRectRoom.java
  11. 8
      src/mightypork/rogue/world/level/render/TileRenderContext.java
  12. 6
      src/mightypork/rogue/world/tile/Tile.java
  13. 3
      src/mightypork/rogue/world/tile/TileModel.java
  14. 117
      src/mightypork/rogue/world/tile/TileRenderer.java
  15. 8
      src/mightypork/rogue/world/tile/Tiles.java
  16. 6
      src/mightypork/rogue/world/tile/models/AbstractTile.java
  17. 2
      src/mightypork/rogue/world/tile/renderers/BasicTileRenderer.java
  18. 2
      src/mightypork/rogue/world/tile/renderers/DoorRenderer.java
  19. 81
      src/mightypork/rogue/world/tile/renderers/FloorRenderer.java
  20. 3
      src/mightypork/rogue/world/tile/renderers/NullTileRenderer.java
  21. 11
      src/mightypork/rogue/world/tile/renderers/WallRenderer.java

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

@ -80,7 +80,7 @@ public final class Res {
textures.addQuad("panel", gui.makeQuad(0, 3.75, 4, .25)); textures.addQuad("panel", gui.makeQuad(0, 3.75, 4, .25));
// sprites // sprites
texture = textures.loadTexture("mob", "/res/img/dudes.png", FilterMode.NEAREST, WrapMode.CLAMP); texture = textures.loadTexture("mob", "/res/img/dudes-b.png", FilterMode.NEAREST, WrapMode.CLAMP);
tiles = texture.grid(8, 8); tiles = texture.grid(8, 8);
textures.addSheet("player", tiles.makeSheet(0, 0, 4, 1)); textures.addSheet("player", tiles.makeSheet(0, 0, 4, 1));
@ -96,13 +96,24 @@ public final class Res {
textures.addQuad("tile.shadow.n", tiles.makeQuad(0, 7)); textures.addQuad("tile.shadow.n", tiles.makeQuad(0, 7));
textures.addQuad("tile.shadow.s", tiles.makeQuad(0, 7).flipY()); textures.addQuad("tile.shadow.s", tiles.makeQuad(0, 7).flipY());
textures.addQuad("tile.shadow.w", tiles.makeQuad(2, 7)); textures.addQuad("tile.shadow.w", tiles.makeQuad(1, 7));
textures.addQuad("tile.shadow.e", tiles.makeQuad(2, 7).flipX()); textures.addQuad("tile.shadow.e", tiles.makeQuad(1, 7).flipX());
textures.addQuad("tile.shadow.nw", tiles.makeQuad(1, 7)); textures.addQuad("tile.shadow.nw", tiles.makeQuad(2, 7));
textures.addQuad("tile.shadow.ne", tiles.makeQuad(1, 7).flipX()); textures.addQuad("tile.shadow.ne", tiles.makeQuad(2, 7).flipX());
textures.addQuad("tile.shadow.sw", tiles.makeQuad(1, 7).flipY()); textures.addQuad("tile.shadow.sw", tiles.makeQuad(2, 7).flipY());
textures.addQuad("tile.shadow.se", tiles.makeQuad(1, 7).flipY().flipX()); textures.addQuad("tile.shadow.se", tiles.makeQuad(2, 7).flipY().flipX());
// unexplored fog
textures.addQuad("tile.ufog.n", tiles.makeQuad(3, 7));
textures.addQuad("tile.ufog.s", tiles.makeQuad(3, 7).flipY());
textures.addQuad("tile.ufog.w", tiles.makeQuad(4, 7));
textures.addQuad("tile.ufog.e", tiles.makeQuad(4, 7).flipX());
textures.addQuad("tile.ufog.nw", tiles.makeQuad(5, 7));
textures.addQuad("tile.ufog.ne", tiles.makeQuad(5, 7).flipX());
textures.addQuad("tile.ufog.sw", tiles.makeQuad(5, 7).flipY());
textures.addQuad("tile.ufog.se", tiles.makeQuad(5, 7).flipY().flipX());
} }

@ -9,28 +9,36 @@ import mightypork.gamecore.control.events.input.KeyListener;
import mightypork.gamecore.control.events.input.MouseButtonEvent; import mightypork.gamecore.control.events.input.MouseButtonEvent;
import mightypork.gamecore.control.events.input.MouseButtonListener; import mightypork.gamecore.control.events.input.MouseButtonListener;
import mightypork.gamecore.gui.components.InputComponent; import mightypork.gamecore.gui.components.InputComponent;
import mightypork.gamecore.input.Keys;
import mightypork.rogue.world.Coord; import mightypork.rogue.world.Coord;
import mightypork.rogue.world.PlayerControl; import mightypork.rogue.world.PlayerControl;
import mightypork.rogue.world.World; import mightypork.rogue.world.World;
import mightypork.rogue.world.WorldRenderer; import mightypork.rogue.world.WorldRenderer;
import mightypork.rogue.world.entity.Entity; import mightypork.rogue.world.entity.Entity;
import mightypork.rogue.world.entity.models.EntityMoveListener; import mightypork.rogue.world.entity.models.EntityMoveListener;
import mightypork.util.math.Easing;
import mightypork.util.math.constraints.num.Num;
import mightypork.util.math.constraints.num.mutable.NumAnimated;
import mightypork.util.math.constraints.vect.Vect; import mightypork.util.math.constraints.vect.Vect;
import mightypork.util.timing.Updateable;
public class MapView extends InputComponent implements KeyListener, MouseButtonListener, EntityMoveListener { public class MapView extends InputComponent implements KeyListener, MouseButtonListener, EntityMoveListener, Updateable {
protected final WorldRenderer worldRenderer; protected final WorldRenderer worldRenderer;
protected final World world; protected final World world;
private final PlayerControl pc; private final PlayerControl pc;
private final Set<MapInteractionPlugin> plugins = new HashSet<>(); private final Set<MapInteractionPlugin> plugins = new HashSet<>();
private Num tileSize;
private final NumAnimated zoom = new NumAnimated(0, Easing.SINE_BOTH);
public MapView(World world) public MapView(World world)
{ {
this.world = world; this.world = world;
this.worldRenderer = new WorldRenderer(world, this, 12, 8, 32);//8, 8, 64 this.tileSize = height().min(width()).div(8).max(32).mul(Num.make(1).sub(zoom.mul(0.66)));
this.worldRenderer = new WorldRenderer(world, this, tileSize);
pc = world.getPlayerControl(); pc = world.getPlayerControl();
pc.addMoveListener(this); pc.addMoveListener(this);
} }
@ -109,6 +117,16 @@ public class MapView extends InputComponent implements KeyListener, MouseButtonL
p.onKey(this, pc, event.getKey(), event.isDown()); p.onKey(this, pc, event.getKey(), event.isDown());
} }
if(event.getKey() == Keys.Z) {
if(event.isDown()) {
zoom.fadeIn(1);
} else {
zoom.fadeOut(1);
}
}
// don't consume key events, can be useful for others. // don't consume key events, can be useful for others.
} }
@ -117,4 +135,11 @@ public class MapView extends InputComponent implements KeyListener, MouseButtonL
{ {
plugins.add(plugin); plugins.add(plugin);
} }
@Override
public void update(double delta)
{
zoom.update(delta);
}
} }

@ -0,0 +1,45 @@
package mightypork.rogue.world;
public class Sides {
//@formatter:off
public static final byte NW = (byte) 0b10000000;
public static final byte N = 0b01000000;
public static final byte NE = 0b00100000;
public static final byte E = 0b00010000;
public static final byte SE = 0b00001000;
public static final byte S = 0b00000100;
public static final byte SW = 0b00000010;
public static final byte W = 0b00000001;
public static final byte CARDINAL = N|S|E|W;
public static final byte DIAGONAL = NE|NW|SE|SW;
public static final byte NW_CORNER = W|NW|N;
public static final byte NE_CORNER = E|NE|N;
public static final byte SW_CORNER = W|SW|S;
public static final byte SE_CORNER = E|SE|S;
private final static Coord[] side = {
Coord.make(-1, -1),
Coord.make(0, -1),
Coord.make(1, -1),
Coord.make(1, 0),
Coord.make(1, 1),
Coord.make(0, 1),
Coord.make(-1, 1),
Coord.make(-1, 0)
};
//@formatter:on
public static Coord get(int i)
{
return side[i]; // FIXME Coord is mutable
}
public static byte bit(int i)
{
return (byte) (1 << (7 - i));
}
}

@ -10,12 +10,11 @@ import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.util.math.color.RGB; import mightypork.util.math.color.RGB;
import mightypork.util.math.constraints.Pollable; import mightypork.util.math.constraints.Pollable;
import mightypork.util.math.constraints.num.Num; import mightypork.util.math.constraints.num.Num;
import mightypork.util.math.constraints.num.caching.NumCache;
import mightypork.util.math.constraints.rect.Rect; import mightypork.util.math.constraints.rect.Rect;
import mightypork.util.math.constraints.rect.caching.RectCache; import mightypork.util.math.constraints.rect.RectConst;
import mightypork.util.math.constraints.rect.proxy.RectProxy; import mightypork.util.math.constraints.rect.proxy.RectProxy;
import mightypork.util.math.constraints.vect.Vect; import mightypork.util.math.constraints.vect.Vect;
import mightypork.util.math.constraints.vect.caching.VectCache; import mightypork.util.math.constraints.vect.VectConst;
/** /**
@ -27,14 +26,13 @@ public class WorldRenderer extends RectProxy implements Pollable {
private static final boolean USE_BATCH_RENDERING = true; private static final boolean USE_BATCH_RENDERING = true;
private final VectCache vpCenter; private final Num tileSize;
private final NumCache tileSize;
private final World world; private final World world;
private final Entity player; private final Entity player;
// can be changed // can be changed
private RectCache mapRect; private RectConst mapRect;
private Level activeLevel; private Level activeLevel;
private final Rect rightShadow; private final Rect rightShadow;
@ -45,17 +43,13 @@ public class WorldRenderer extends RectProxy implements Pollable {
private TileRenderContext trc; private TileRenderContext trc;
public WorldRenderer(World world, Rect viewport, int xTiles, int yTiles, int minTileSize) public WorldRenderer(World world, Rect viewport, Num tileSize) {
{
super(viewport); super(viewport);
this.world = world; this.world = world;
this.player = world.getPlayerEntity(); this.player = world.getPlayerEntity();
tileSize = width().div(xTiles).min(height().div(yTiles)).max(minTileSize).cached(); this.tileSize = tileSize;
final Num th = tileSize.half();
vpCenter = center().sub(th, th).cached();
final Num grX = width().perc(30); final Num grX = width().perc(30);
leftShadow = leftEdge().growRight(grX); leftShadow = leftEdge().growRight(grX);
@ -76,21 +70,18 @@ public class WorldRenderer extends RectProxy implements Pollable {
if (activeLevel == level) return; if (activeLevel == level) return;
activeLevel = level; activeLevel = level;
mapRect = Rect.make(vpCenter, tileSize.mul(level.getWidth()), tileSize.mul(level.getHeight())).cached(); mapRect = Rect.make(0, 0, level.getWidth(), level.getHeight());
trc = new TileRenderContext(activeLevel, mapRect); trc = new TileRenderContext(activeLevel, mapRect);
} }
private Vect getOffset() private VectConst getOffset()
{ {
final EntityPos pos = player.getPosition(); final EntityPos pos = player.getPosition();
final double playerX = pos.visualX(); final double playerX = pos.visualX();
final double playerY = pos.visualY(); final double playerY = pos.visualY();
return Vect.make(-playerX-0.5, -playerY-0.5);
final double ts = tileSize.value();
return Vect.make((-ts * playerX), (-ts * playerY));
} }
@ -98,12 +89,16 @@ public class WorldRenderer extends RectProxy implements Pollable {
{ {
Render.pushMatrix(); Render.pushMatrix();
Render.setColor(RGB.WHITE); Render.setColor(RGB.WHITE);
Render.translate(center());
Render.scaleXY(tileSize.value());
Render.translate(getOffset()); Render.translate(getOffset());
// tiles to render // tiles to render
final EntityPos pos = player.getPosition(); final EntityPos pos = player.getPosition();
final double w = width().value(); final double w = width().value();
final double h = height().value(); final double h = height().value();
final double ts = tileSize.value(); final double ts = tileSize.value();
final int xtilesh = (int) (w / (ts * 2)) + 1; final int xtilesh = (int) (w / (ts * 2)) + 1;
@ -167,8 +162,8 @@ public class WorldRenderer extends RectProxy implements Pollable {
public Coord getClickedTile(Vect clickPos) public Coord getClickedTile(Vect clickPos)
{ {
final Vect v = clickPos.sub(mapRect.origin().add(getOffset()));
final int ts = (int) tileSize.value(); final int ts = (int) tileSize.value();
final Vect v = clickPos.sub(center().add(getOffset().mul(ts)));
return new Coord(v.xi() / ts, v.yi() / ts); return new Coord(v.xi() / ts, v.yi() / ts);
} }
@ -176,12 +171,6 @@ public class WorldRenderer extends RectProxy implements Pollable {
@Override @Override
public void poll() public void poll()
{ {
// in order of dependency
vpCenter.poll();
tileSize.poll();
mapRect.poll();
rebuildTiles(); rebuildTiles();
} }

@ -8,6 +8,7 @@ import java.util.Random;
import java.util.Set; import java.util.Set;
import mightypork.rogue.world.Coord; import mightypork.rogue.world.Coord;
import mightypork.rogue.world.Sides;
import mightypork.rogue.world.level.Level; import mightypork.rogue.world.level.Level;
import mightypork.rogue.world.pathfinding.Heuristic; import mightypork.rogue.world.pathfinding.Heuristic;
import mightypork.rogue.world.pathfinding.PathFinder; import mightypork.rogue.world.pathfinding.PathFinder;
@ -21,19 +22,6 @@ import mightypork.util.math.Calc;
public class ScratchMap { public class ScratchMap {
//@formatter:off
public static final Coord[] MOVES = {
Coord.make(-1, 0),
Coord.make(-1, -1),
Coord.make(0, -1),
Coord.make(1, -1),
Coord.make(1, 0),
Coord.make(1, 1),
Coord.make(0, 1),
Coord.make(-1, 1)
};
//@formatter:on
private Tile[][] map; private Tile[][] map;
private final int width; private final int width;
private final int height; private final int height;
@ -88,9 +76,6 @@ public class ScratchMap {
private final Random rand; private final Random rand;
private Coord enterPoint; private Coord enterPoint;
public static final byte CARDINAL = (byte) 0b10101010;
public static final byte DIAGONAL = (byte) 0b01010101;
private static final boolean FIX_GLITCHES = true; private static final boolean FIX_GLITCHES = true;
@ -341,12 +326,12 @@ public class ScratchMap {
public byte findWalls(Coord pos) public byte findWalls(Coord pos)
{ {
byte walls = 0; byte walls = 0;
for (int i = 0; i <= 7; i++) { for (int i = 0; i < 8; i++) {
final Coord cc = pos.add(MOVES[i]); final Coord cc = pos.add(Sides.get(i));
if (!isIn(cc)) continue; if (!isIn(cc)) continue;
if (get(cc).isWall()) { if (get(cc).isWall()) {
walls |= 1 << (7 - i); walls |= Sides.bit(i);
} }
} }
return walls; return walls;
@ -357,11 +342,11 @@ public class ScratchMap {
{ {
byte floors = 0; byte floors = 0;
for (int i = 0; i <= 7; i++) { for (int i = 0; i <= 7; i++) {
final Coord cc = pos.add(MOVES[i]); final Coord cc = pos.add(Sides.get(i));
if (!isIn(cc)) continue; if (!isIn(cc)) continue;
if (get(cc).isFloor()) { if (get(cc).isFloor()) {
floors |= 1 << (7 - i); floors |= Sides.bit(i);
} }
} }
return floors; return floors;
@ -372,11 +357,11 @@ public class ScratchMap {
{ {
byte doors = 0; byte doors = 0;
for (int i = 0; i <= 7; i++) { for (int i = 0; i <= 7; i++) {
final Coord cc = pos.add(MOVES[i]); final Coord cc = pos.add(Sides.get(i));
if (!isIn(cc)) continue; if (!isIn(cc)) continue;
if (get(cc).isDoor()) { if (get(cc).isDoor()) {
doors |= 1 << (7 - i); doors |= Sides.bit(i);
} }
} }
return doors; return doors;
@ -387,10 +372,10 @@ public class ScratchMap {
{ {
byte nils = 0; byte nils = 0;
for (int i = 0; i <= 7; i++) { for (int i = 0; i <= 7; i++) {
final Coord cc = pos.add(MOVES[i]); final Coord cc = pos.add(Sides.get(i));
if (!isIn(cc) || get(cc).isNull()) { if (!isIn(cc) || get(cc).isNull()) {
nils |= 1 << (7 - i); nils |= Sides.bit(i);
} }
} }
return nils; return nils;
@ -432,12 +417,12 @@ public class ScratchMap {
break; break;
} }
if (isFloor && (nils & CARDINAL) != 0) { if (isFloor && (nils & Sides.CARDINAL) != 0) {
toWall = true; // floor with adjacent cardinal null toWall = true; // floor with adjacent cardinal null
break; break;
} }
if (isNull && (floors & DIAGONAL) != 0) { if (isNull && (floors & Sides.DIAGONAL) != 0) {
System.out.println(c); System.out.println(c);
toWall = true; // null with adjacent diagonal floor toWall = true; // null with adjacent diagonal floor
break; break;
@ -445,25 +430,25 @@ public class ScratchMap {
if (isDoor) { if (isDoor) {
if (countBits((byte) (floors & CARDINAL)) < 2) { if (countBits((byte) (floors & Sides.CARDINAL)) < 2) {
toWall = true; toWall = true;
break; break;
} }
if (countBits((byte) (walls & CARDINAL)) > 2) { if (countBits((byte) (walls & Sides.CARDINAL)) > 2) {
toWall = true; toWall = true;
break; break;
} }
if (countBits((byte) (floors & CARDINAL)) > 2) { if (countBits((byte) (floors & Sides.CARDINAL)) > 2) {
toFloor = true; toFloor = true;
break; break;
} }
if ((floors & 0b11100000) == 0b11100000) toWall = true; if ((floors & Sides.NW_CORNER) == Sides.NW_CORNER) toWall = true;
if ((floors & 0b00111000) == 0b00111000) toWall = true; if ((floors & Sides.NE_CORNER) == Sides.NE_CORNER) toWall = true;
if ((floors & 0b00001110) == 0b00001110) toWall = true; if ((floors & Sides.SW_CORNER) == Sides.SW_CORNER) toWall = true;
if ((floors & 0b10000011) == 0b10000011) toWall = true; if ((floors & Sides.SE_CORNER) == Sides.SE_CORNER) toWall = true;
} }
} while (false); } while (false);

@ -4,6 +4,7 @@ package mightypork.rogue.world.gen.rooms;
import java.util.Random; import java.util.Random;
import mightypork.rogue.world.Coord; import mightypork.rogue.world.Coord;
import mightypork.rogue.world.Sides;
import mightypork.rogue.world.gen.RoomBuilder; import mightypork.rogue.world.gen.RoomBuilder;
import mightypork.rogue.world.gen.RoomDesc; import mightypork.rogue.world.gen.RoomDesc;
import mightypork.rogue.world.gen.ScratchMap; import mightypork.rogue.world.gen.ScratchMap;
@ -49,7 +50,7 @@ public class SimpleRectRoom implements RoomBuilder {
break; break;
} }
if ((map.findDoors(door) & map.CARDINAL) == 0) { if ((map.findDoors(door) & Sides.CARDINAL) == 0) {
map.set(door, theme.door()); map.set(door, theme.door());
} }
} }

@ -42,13 +42,12 @@ public final class TileRenderContext extends MapRenderContext implements RectBou
/** /**
* Get a neighbor tile * Get a neighbor tile
* *
* @param offsetX x offset (left-right) * @param offset offsets
* @param offsetY y offset (up-down)
* @return the tile at that position * @return the tile at that position
*/ */
public Tile getAdjacentTile(int offsetX, int offsetY) public Tile getAdjacentTile(Coord offset)
{ {
return map.getTile(pos.add(offsetX, offsetY)); return map.getTile(pos.add(offset));
} }
@ -63,6 +62,7 @@ public final class TileRenderContext extends MapRenderContext implements RectBou
public void renderTile() public void renderTile()
{ {
if(!map.getTile(pos).isExplored()) return;
map.getTile(pos).renderTile(this); map.getTile(pos).renderTile(this);
} }

@ -219,4 +219,10 @@ public final class Tile implements IonBinary {
{ {
data.explored = true; data.explored = true;
} }
public boolean doesReceiveShadow()
{
return model.doesReceiveShadow();
}
} }

@ -53,6 +53,9 @@ public abstract class TileModel {
public abstract boolean doesCastShadow(); public abstract boolean doesCastShadow();
public abstract boolean doesReceiveShadow();
public boolean isNullTile() public boolean isNullTile()

@ -1,9 +1,13 @@
package mightypork.rogue.world.tile; package mightypork.rogue.world.tile;
import mightypork.gamecore.render.Render;
import mightypork.gamecore.render.textures.TxQuad;
import mightypork.rogue.Res;
import mightypork.rogue.world.Sides;
import mightypork.rogue.world.item.Item; import mightypork.rogue.world.item.Item;
import mightypork.rogue.world.level.render.TileRenderContext; import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.renderers.NullTileRenderer; import mightypork.rogue.world.tile.renderers.NullTileRenderer;
import mightypork.util.math.constraints.rect.Rect;
/** /**
@ -15,9 +19,38 @@ public abstract class TileRenderer {
public static final TileRenderer NONE = new NullTileRenderer(); public static final TileRenderer NONE = new NullTileRenderer();
private static TxQuad SH_N, SH_S, SH_E, SH_W, SH_NW, SH_NE, SH_SW, SH_SE;
private static TxQuad UFOG_N, UFOG_S, UFOG_E, UFOG_W, UFOG_NW, UFOG_NE, UFOG_SW, UFOG_SE;
private static boolean inited;
private DroppedItemRenderer itemRenderer; private DroppedItemRenderer itemRenderer;
public TileRenderer() {
if (!inited) {
SH_N = Res.getTxQuad("tile.shadow.n");
SH_S = Res.getTxQuad("tile.shadow.s");
SH_E = Res.getTxQuad("tile.shadow.e");
SH_W = Res.getTxQuad("tile.shadow.w");
SH_NW = Res.getTxQuad("tile.shadow.nw");
SH_NE = Res.getTxQuad("tile.shadow.ne");
SH_SW = Res.getTxQuad("tile.shadow.sw");
SH_SE = Res.getTxQuad("tile.shadow.se");
UFOG_N = Res.getTxQuad("tile.ufog.n");
UFOG_S = Res.getTxQuad("tile.ufog.s");
UFOG_E = Res.getTxQuad("tile.ufog.e");
UFOG_W = Res.getTxQuad("tile.ufog.w");
UFOG_NW = Res.getTxQuad("tile.ufog.nw");
UFOG_NE = Res.getTxQuad("tile.ufog.ne");
UFOG_SW = Res.getTxQuad("tile.ufog.sw");
UFOG_SE = Res.getTxQuad("tile.ufog.se");
}
}
/** /**
* Update tile renderer * Update tile renderer
* *
@ -36,7 +69,87 @@ public abstract class TileRenderer {
* *
* @param context * @param context
*/ */
public abstract void render(TileRenderContext context); public final void render(TileRenderContext context)
{
Tile t = context.getTile();
if (t.isNull() || !t.isExplored()) return;
renderTile(context);
if (t.doesReceiveShadow()) renderShadows(context);
renderUFog(context);
}
protected abstract void renderTile(TileRenderContext context);
protected void renderShadows(TileRenderContext context)
{
final TileRenderData trd = context.getTile().renderData;
if (!trd.shadowsComputed) {
// no shadows computed yet
trd.shadows = 0; // reset the mask
for (int i = 0; i < 8; i++) {
final Tile t2 = context.getAdjacentTile(Sides.get(i));
if (t2.doesCastShadow()) {
trd.shadows |= Sides.bit(i);
}
}
trd.shadowsComputed = true;
}
if (trd.shadows == 0) return;
final Rect rect = context.getRect();
if ((trd.shadows & Sides.NW) != 0) Render.quadTextured(rect, SH_NW);
if ((trd.shadows & Sides.N) != 0) Render.quadTextured(rect, SH_N);
if ((trd.shadows & Sides.NE) != 0) Render.quadTextured(rect, SH_NE);
if ((trd.shadows & Sides.W) != 0) Render.quadTextured(rect, SH_W);
if ((trd.shadows & Sides.E) != 0) Render.quadTextured(rect, SH_E);
if ((trd.shadows & Sides.SW) != 0) Render.quadTextured(rect, SH_SW);
if ((trd.shadows & Sides.S) != 0) Render.quadTextured(rect, SH_S);
if ((trd.shadows & Sides.SE) != 0) Render.quadTextured(rect, SH_SE);
}
protected void renderUFog(TileRenderContext context)
{
// TODO cache in tile, update neighbouring tiles upon "explored" flag changed.
byte ufog = 0;
ufog = 0; // reset the mask
for (int i = 0; i < 8; i++) {
final Tile t2 = context.getAdjacentTile(Sides.get(i));
if (t2.isNull() || !t2.isExplored()) {
ufog |= Sides.bit(i);
}
}
if (ufog == 0) return;
final Rect rect = context.getRect();
if ((ufog & Sides.NW_CORNER) == Sides.NW) Render.quadTextured(rect, UFOG_NW);
if ((ufog & Sides.N) != 0) Render.quadTextured(rect, UFOG_N);
if ((ufog & Sides.NE_CORNER) == Sides.NE) Render.quadTextured(rect, UFOG_NE);
if ((ufog & Sides.W) != 0) Render.quadTextured(rect, UFOG_W);
if ((ufog & Sides.E) != 0) Render.quadTextured(rect, UFOG_E);
if ((ufog & Sides.SW_CORNER) == Sides.SW) Render.quadTextured(rect, UFOG_SW);
if ((ufog & Sides.S) != 0) Render.quadTextured(rect, UFOG_S);
if ((ufog & Sides.SE_CORNER) == Sides.SE) Render.quadTextured(rect, UFOG_SE);
}
public void renderItemOnTile(Item item, TileRenderContext context) public void renderItemOnTile(Item item, TileRenderContext context)

@ -5,9 +5,7 @@ import mightypork.rogue.world.tile.models.Floor;
import mightypork.rogue.world.tile.models.NullTile; import mightypork.rogue.world.tile.models.NullTile;
import mightypork.rogue.world.tile.models.SimpleDoor; import mightypork.rogue.world.tile.models.SimpleDoor;
import mightypork.rogue.world.tile.models.Wall; import mightypork.rogue.world.tile.models.Wall;
import mightypork.rogue.world.tile.renderers.FloorRenderer; import mightypork.rogue.world.tile.renderers.BasicTileRenderer;
import mightypork.rogue.world.tile.renderers.WallRenderer;
/** /**
* Tile registry * Tile registry
@ -20,8 +18,8 @@ public final class Tiles {
public static final TileModel NULL = new NullTile(0); public static final TileModel NULL = new NullTile(0);
public static final TileModel FLOOR_DARK = new Floor(10).setRenderer(new FloorRenderer("tile.floor.dark")); public static final TileModel FLOOR_DARK = new Floor(10).setRenderer(new BasicTileRenderer("tile.floor.dark"));
public static final TileModel WALL_BRICK = new Wall(11).setRenderer(new WallRenderer("tile.wall.brick")); public static final TileModel WALL_BRICK = new Wall(11).setRenderer(new BasicTileRenderer("tile.wall.brick"));
public static final TileModel DOOR = new SimpleDoor(12); public static final TileModel DOOR = new SimpleDoor(12);

@ -47,6 +47,12 @@ public abstract class AbstractTile extends TileModel {
return false; return false;
} }
@Override
public boolean doesReceiveShadow()
{
return isFloor();
}
@Override @Override
@DefaultImpl @DefaultImpl

@ -21,7 +21,7 @@ public class BasicTileRenderer extends TileRenderer {
@Override @Override
public void render(TileRenderContext context) public void renderTile(TileRenderContext context)
{ {
final Rect rect = context.getRect(); final Rect rect = context.getRect();
Render.quadTextured(rect, sheet.getRandomQuad(context.getTileNoise())); Render.quadTextured(rect, sheet.getRandomQuad(context.getTileNoise()));

@ -24,7 +24,7 @@ public class DoorRenderer extends TileRenderer {
@Override @Override
public void render(TileRenderContext context) public void renderTile(TileRenderContext context)
{ {
final Tile t = context.getTile(); final Tile t = context.getTile();
final Rect rect = context.getRect(); final Rect rect = context.getRect();

@ -1,81 +0,0 @@
package mightypork.rogue.world.tile.renderers;
import mightypork.gamecore.render.Render;
import mightypork.gamecore.render.textures.TxQuad;
import mightypork.rogue.Res;
import mightypork.rogue.world.level.render.TileRenderContext;
import mightypork.rogue.world.tile.Tile;
import mightypork.rogue.world.tile.TileRenderData;
import mightypork.util.math.constraints.rect.Rect;
public class FloorRenderer extends BasicTileRenderer {
private static boolean inited;
private static TxQuad SH_N, SH_S, SH_E, SH_W, SH_NW, SH_NE, SH_SW, SH_SE;
public FloorRenderer(String sheetKey)
{
super(sheetKey);
if (!inited) {
SH_N = Res.getTxQuad("tile.shadow.n");
SH_S = Res.getTxQuad("tile.shadow.s");
SH_E = Res.getTxQuad("tile.shadow.e");
SH_W = Res.getTxQuad("tile.shadow.w");
SH_NW = Res.getTxQuad("tile.shadow.nw");
SH_NE = Res.getTxQuad("tile.shadow.ne");
SH_SW = Res.getTxQuad("tile.shadow.sw");
SH_SE = Res.getTxQuad("tile.shadow.se");
}
}
@Override
public void render(TileRenderContext context)
{
super.render(context);
final Rect rect = context.getRect();
final TileRenderData trd = context.getTile().renderData;
if (!trd.shadowsComputed) {
// no shadows computed yet
trd.shadows = 0; // reset the mask
int move = 0;
for (int y = -1; y <= 1; y++) {
for (int x = -1; x <= 1; x++) {
if (x == 0 && y == 0) continue;
final Tile t2 = context.getAdjacentTile(x, y);
if (t2.doesCastShadow()) {
trd.shadows |= 1 << move;
}
move++;
}
}
trd.shadowsComputed = true;
}
if (trd.shadows == 0) return;
if ((trd.shadows & (1 << 0)) != 0) Render.quadTextured(rect, SH_NW);
if ((trd.shadows & (1 << 1)) != 0) Render.quadTextured(rect, SH_N);
if ((trd.shadows & (1 << 2)) != 0) Render.quadTextured(rect, SH_NE);
if ((trd.shadows & (1 << 3)) != 0) Render.quadTextured(rect, SH_W);
if ((trd.shadows & (1 << 4)) != 0) Render.quadTextured(rect, SH_E);
if ((trd.shadows & (1 << 5)) != 0) Render.quadTextured(rect, SH_SW);
if ((trd.shadows & (1 << 6)) != 0) Render.quadTextured(rect, SH_S);
if ((trd.shadows & (1 << 7)) != 0) Render.quadTextured(rect, SH_SE);
}
}

@ -8,9 +8,8 @@ import mightypork.rogue.world.tile.TileRenderer;
public class NullTileRenderer extends TileRenderer { public class NullTileRenderer extends TileRenderer {
@Override @Override
public void render(TileRenderContext context) protected void renderTile(TileRenderContext context)
{ {
// nope
} }
} }

@ -1,11 +0,0 @@
package mightypork.rogue.world.tile.renderers;
public class WallRenderer extends BasicTileRenderer {
public WallRenderer(String sheetKey)
{
super(sheetKey);
}
}
Loading…
Cancel
Save