parent
69f55dcc12
commit
eef373eb24
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 4.5 KiB |
@ -0,0 +1,38 @@ |
|||||||
|
package mightypork.rogue.screens.gamescreen.world; |
||||||
|
|
||||||
|
|
||||||
|
import mightypork.gamecore.input.InputSystem; |
||||||
|
import mightypork.rogue.world.PlayerControl; |
||||||
|
import mightypork.rogue.world.WorldPos; |
||||||
|
import mightypork.util.math.constraints.vect.Vect; |
||||||
|
|
||||||
|
|
||||||
|
public class MIPClickPathfWalk implements MapInteractionPlugin { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onStepEnd(MapView wv, PlayerControl player) |
||||||
|
{ |
||||||
|
if (InputSystem.isMouseButtonDown(0)) { |
||||||
|
final WorldPos clicked = wv.toWorldPos(InputSystem.getMousePos()); |
||||||
|
player.navigateTo(clicked); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void onClick(MapView wv, PlayerControl player, Vect mouse, int button, boolean down) |
||||||
|
{ |
||||||
|
if (!down) return; |
||||||
|
|
||||||
|
final WorldPos clicked = wv.toWorldPos(mouse); |
||||||
|
|
||||||
|
player.navigateTo(clicked); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void onKey(MapView wv, PlayerControl player, int key, boolean down) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,12 +1,17 @@ |
|||||||
package mightypork.rogue.world.gen; |
package mightypork.rogue.world.gen; |
||||||
|
|
||||||
import java.util.List; |
|
||||||
import java.util.Random; |
import java.util.Random; |
||||||
|
|
||||||
import mightypork.rogue.world.tile.Tile; |
import mightypork.rogue.world.Coord; |
||||||
|
|
||||||
|
|
||||||
// room builder interface
|
/** |
||||||
public interface RoomBuilder { |
* Room model |
||||||
|
* |
||||||
|
* @author MightyPork |
||||||
|
*/ |
||||||
|
public interface RoomBuilder { |
||||||
|
|
||||||
RoomDesc buildToFit(ScratchMap map, Theme theme, Random rand, Coord center); |
RoomDesc buildToFit(ScratchMap map, Theme theme, Random rand, Coord center); |
||||||
} |
} |
||||||
|
@ -1,15 +1,21 @@ |
|||||||
package mightypork.rogue.world.gen; |
package mightypork.rogue.world.gen; |
||||||
|
|
||||||
|
|
||||||
import mightypork.rogue.world.tile.models.TileModel; |
import mightypork.rogue.world.tile.models.TileModel; |
||||||
|
|
||||||
// map theme
|
|
||||||
|
/** |
||||||
|
* Map theme to use for building |
||||||
|
* |
||||||
|
* @author MightyPork |
||||||
|
*/ |
||||||
public interface Theme { |
public interface Theme { |
||||||
|
|
||||||
TileModel wall(); |
TileModel wall(); |
||||||
|
|
||||||
|
|
||||||
TileModel floor(); |
TileModel floor(); |
||||||
|
|
||||||
|
|
||||||
TileModel door(); |
TileModel door(); |
||||||
} |
} |
||||||
|
@ -1,49 +0,0 @@ |
|||||||
package mightypork.rogue.world.gen.rooms; |
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.List; |
|
||||||
import java.util.Random; |
|
||||||
|
|
||||||
import mightypork.rogue.world.gen.Coord; |
|
||||||
import mightypork.rogue.world.gen.RoomBuilder; |
|
||||||
import mightypork.rogue.world.gen.RoomDesc; |
|
||||||
import mightypork.rogue.world.gen.Theme; |
|
||||||
import mightypork.rogue.world.gen.ScratchMap; |
|
||||||
|
|
||||||
|
|
||||||
public class IntersectionRoom extends SquareRoom { |
|
||||||
|
|
||||||
@Override |
|
||||||
protected int getMinHalfSide() |
|
||||||
{ |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
@Override |
|
||||||
protected int getMaxHalfSide() |
|
||||||
{ |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
protected int[] getDoorTypes() |
|
||||||
{ |
|
||||||
//@formatter:off
|
|
||||||
return new int[] { |
|
||||||
// dead ends
|
|
||||||
0b1000,0b0100,0b0010,0b0001, |
|
||||||
|
|
||||||
// corridor pieces
|
|
||||||
0b0011, 0b0101, 0b0110, 0b1010, 0b1100, 0b1001, |
|
||||||
|
|
||||||
// crossings
|
|
||||||
0b0111, 0b1101, 0b1011, 0b1110, 0b1111, |
|
||||||
|
|
||||||
// repeat to get more
|
|
||||||
0b0111, 0b1101, 0b1011, 0b1110, 0b1111, |
|
||||||
}; |
|
||||||
//@formatter:on
|
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,35 @@ |
|||||||
|
package mightypork.rogue.world.gen.rooms; |
||||||
|
|
||||||
|
|
||||||
|
import java.util.Random; |
||||||
|
|
||||||
|
import mightypork.rogue.world.Coord; |
||||||
|
import mightypork.rogue.world.gen.RoomBuilder; |
||||||
|
import mightypork.rogue.world.gen.RoomDesc; |
||||||
|
import mightypork.rogue.world.gen.ScratchMap; |
||||||
|
import mightypork.rogue.world.gen.Theme; |
||||||
|
|
||||||
|
|
||||||
|
public class SimpleRectRoom implements RoomBuilder { |
||||||
|
|
||||||
|
@Override |
||||||
|
public RoomDesc buildToFit(ScratchMap map, Theme theme, Random rand, Coord center) |
||||||
|
{ |
||||||
|
// half width, half height actually
|
||||||
|
final int width = 2 + rand.nextInt(2); |
||||||
|
final int height = 2 + rand.nextInt(2); |
||||||
|
|
||||||
|
final Coord min = new Coord(center.x - width, center.y - height); |
||||||
|
final Coord max = new Coord(center.x + height, center.y + height); |
||||||
|
|
||||||
|
if (!map.isClear(min, max)) return null; |
||||||
|
|
||||||
|
map.fill(min, max, theme.floor()); |
||||||
|
map.border(min, max, theme.wall()); |
||||||
|
|
||||||
|
// TODO place some doors
|
||||||
|
|
||||||
|
return new RoomDesc(min.add(-1, -1), max.add(1, 1)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,98 +0,0 @@ |
|||||||
package mightypork.rogue.world.gen.rooms; |
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList; |
|
||||||
import java.util.List; |
|
||||||
import java.util.Random; |
|
||||||
|
|
||||||
import mightypork.rogue.world.gen.Coord; |
|
||||||
import mightypork.rogue.world.gen.RoomBuilder; |
|
||||||
import mightypork.rogue.world.gen.RoomDesc; |
|
||||||
import mightypork.rogue.world.gen.Theme; |
|
||||||
import mightypork.rogue.world.gen.ScratchMap; |
|
||||||
|
|
||||||
|
|
||||||
public class SquareRoom implements RoomBuilder { |
|
||||||
|
|
||||||
@Override |
|
||||||
public RoomDesc buildToFit(ScratchMap map, Theme theme, Random rand, Coord center) |
|
||||||
{ |
|
||||||
int hside = getMinHalfSide(); |
|
||||||
if (getMaxHalfSide() > getMinHalfSide()) hside += rand.nextInt(getMaxHalfSide() - getMinHalfSide()); |
|
||||||
|
|
||||||
Coord min = new Coord(center.x - hside, center.y - hside); |
|
||||||
Coord max = new Coord(center.x + hside, center.y + hside); |
|
||||||
|
|
||||||
for (;; hside--) { |
|
||||||
if (hside < getMinHalfSide()) return null; |
|
||||||
if (map.isClear(min, max)) break; |
|
||||||
} |
|
||||||
|
|
||||||
map.fill(min, max, theme.floor()); |
|
||||||
map.border(min, max, theme.wall()); |
|
||||||
|
|
||||||
List<Coord> doors = new ArrayList<>(); |
|
||||||
|
|
||||||
int door_types[] = getDoorTypes(); |
|
||||||
|
|
||||||
int drs = door_types[rand.nextInt(door_types.length)]; |
|
||||||
|
|
||||||
Coord door; |
|
||||||
|
|
||||||
if ((drs & 1) != 0) { |
|
||||||
door = min.add(hside, 0); |
|
||||||
map.set(door, theme.door()); |
|
||||||
doors.add(door); |
|
||||||
} |
|
||||||
|
|
||||||
if ((drs & 2) != 0) { |
|
||||||
door = max.add(-hside, 0); |
|
||||||
map.set(door, theme.door()); |
|
||||||
} |
|
||||||
|
|
||||||
if ((drs & 4) != 0) { |
|
||||||
door = min.add(0, hside); |
|
||||||
map.set(door, theme.door()); |
|
||||||
} |
|
||||||
|
|
||||||
if ((drs & 8) != 0) { |
|
||||||
door = max.add(0, -hside); |
|
||||||
map.set(door, theme.door()); |
|
||||||
} |
|
||||||
|
|
||||||
return new RoomDesc(min.add(-1, -1), max.add(1, 1), doors); |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
protected int[] getDoorTypes() |
|
||||||
{ |
|
||||||
//@formatter:off
|
|
||||||
return new int[] { |
|
||||||
// one
|
|
||||||
0b0001, 0b0010, 0b0100, 0b1000, |
|
||||||
|
|
||||||
// two
|
|
||||||
0b0011, 0b0101, 0b0110, 0b1010, 0b1100, 0b1001, |
|
||||||
0b0011, 0b0101, 0b0110, 0b1010, 0b1100, 0b1001, |
|
||||||
|
|
||||||
//three+four
|
|
||||||
0b0111, 0b1101, 0b1011, 0b1110, 0b1111, |
|
||||||
0b0111, 0b1101, 0b1011, 0b1110, 0b1111, |
|
||||||
0b0111, 0b1101, 0b1011, 0b1110, 0b1111 |
|
||||||
}; |
|
||||||
//@formatter:on
|
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
protected int getMinHalfSide() |
|
||||||
{ |
|
||||||
return 2; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
protected int getMaxHalfSide() |
|
||||||
{ |
|
||||||
return 4; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
@ -0,0 +1,14 @@ |
|||||||
|
package mightypork.rogue.world.pathfinding; |
||||||
|
|
||||||
|
|
||||||
|
import mightypork.rogue.world.Coord; |
||||||
|
|
||||||
|
|
||||||
|
public class DiagonalHeuristic extends Heuristic { |
||||||
|
|
||||||
|
@Override |
||||||
|
public double getCost(Coord pos, Coord target) |
||||||
|
{ |
||||||
|
return Math.sqrt(Math.pow(pos.x - target.x, 2) + Math.pow(pos.y - target.y, 2)); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,17 @@ |
|||||||
|
package mightypork.rogue.world.pathfinding; |
||||||
|
|
||||||
|
|
||||||
|
import mightypork.rogue.world.Coord; |
||||||
|
|
||||||
|
|
||||||
|
public abstract class Heuristic { |
||||||
|
|
||||||
|
/** |
||||||
|
* Get tile cost (estimate of how many tiles remain to the target) |
||||||
|
* |
||||||
|
* @param pos current pos |
||||||
|
* @param target target pos |
||||||
|
* @return estimated number of tiles |
||||||
|
*/ |
||||||
|
public abstract double getCost(Coord pos, Coord target); |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package mightypork.rogue.world.pathfinding; |
||||||
|
|
||||||
|
|
||||||
|
import mightypork.rogue.world.Coord; |
||||||
|
|
||||||
|
|
||||||
|
public class ManhattanHeuristic extends Heuristic { |
||||||
|
|
||||||
|
@Override |
||||||
|
public double getCost(Coord pos, Coord target) |
||||||
|
{ |
||||||
|
return Math.abs(target.x - pos.x) + Math.abs(target.y - pos.y); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,30 @@ |
|||||||
|
package mightypork.rogue.world.pathfinding; |
||||||
|
|
||||||
|
|
||||||
|
import mightypork.rogue.world.Coord; |
||||||
|
|
||||||
|
|
||||||
|
public interface PathCostProvider { |
||||||
|
|
||||||
|
/** |
||||||
|
* @param pos tile pos |
||||||
|
* @return true if the tile is walkable |
||||||
|
*/ |
||||||
|
boolean isAccessible(Coord pos); |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Cost of walking onto a tile. It's useful to use ie. 10 for basic step. |
||||||
|
* |
||||||
|
* @param from last tile |
||||||
|
* @param to current tile |
||||||
|
* @return cost |
||||||
|
*/ |
||||||
|
int getCost(Coord from, Coord to); |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @return lowest cost. Used to multiply heuristics. |
||||||
|
*/ |
||||||
|
int getMinCost(); |
||||||
|
} |
@ -0,0 +1,205 @@ |
|||||||
|
package mightypork.rogue.world.pathfinding; |
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Collections; |
||||||
|
import java.util.Comparator; |
||||||
|
import java.util.LinkedList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import mightypork.rogue.world.Coord; |
||||||
|
import mightypork.rogue.world.PathStep; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* A* pathfinder |
||||||
|
* |
||||||
|
* @author MightyPork |
||||||
|
*/ |
||||||
|
public class PathFinder { |
||||||
|
|
||||||
|
private static final FComparator F_COMPARATOR = new FComparator(); |
||||||
|
public static final Heuristic CORNER_HEURISTIC = new ManhattanHeuristic(); |
||||||
|
public static final Heuristic DIAGONAL_HEURISTIC = new DiagonalHeuristic(); |
||||||
|
|
||||||
|
private final PathCostProvider costProvider; |
||||||
|
private final Heuristic heuristic; |
||||||
|
|
||||||
|
|
||||||
|
public PathFinder(PathCostProvider costProvider, Heuristic heuristic) |
||||||
|
{ |
||||||
|
this.costProvider = costProvider; |
||||||
|
this.heuristic = heuristic; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public List<PathStep> findPathRelative(Coord start, Coord end) |
||||||
|
{ |
||||||
|
final List<Coord> path = findPath(start, end); |
||||||
|
if (path == null) return null; |
||||||
|
|
||||||
|
final List<PathStep> out = new ArrayList<>(); |
||||||
|
|
||||||
|
final Coord current = start; |
||||||
|
for (final Coord c : path) { |
||||||
|
if (c.equals(current)) continue; |
||||||
|
out.add(PathStep.make(c.x - current.x, c.y - current.y)); |
||||||
|
current.x = c.x; |
||||||
|
current.y = c.y; |
||||||
|
} |
||||||
|
|
||||||
|
return out; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public List<Coord> findPath(Coord start, Coord end) |
||||||
|
{ |
||||||
|
final LinkedList<Node> open = new LinkedList<>(); |
||||||
|
final LinkedList<Node> closed = new LinkedList<>(); |
||||||
|
|
||||||
|
// add first node
|
||||||
|
{ |
||||||
|
final Node n = new Node(start); |
||||||
|
n.h_cost = (int) (heuristic.getCost(start, end) * costProvider.getMinCost()); |
||||||
|
n.g_cost = 0; |
||||||
|
open.add(n); |
||||||
|
} |
||||||
|
|
||||||
|
//@formatter:off
|
||||||
|
final Coord[] walkDirs = { |
||||||
|
Coord.make(0, -1), |
||||||
|
Coord.make(0, 1), |
||||||
|
Coord.make(-1, 0), |
||||||
|
Coord.make(1, 0) |
||||||
|
}; |
||||||
|
//@formatter:on
|
||||||
|
|
||||||
|
Node current = null; |
||||||
|
|
||||||
|
while (true) { |
||||||
|
current = open.poll(); |
||||||
|
|
||||||
|
if (current == null) { |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
closed.add(current); |
||||||
|
|
||||||
|
if (current.pos.equals(end)) { |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
for (final Coord go : walkDirs) { |
||||||
|
|
||||||
|
final Coord c = current.pos.add(go); |
||||||
|
if (!costProvider.isAccessible(c)) continue; |
||||||
|
final Node a = new Node(c); |
||||||
|
a.g_cost = current.g_cost + costProvider.getCost(c, a.pos); |
||||||
|
a.h_cost = (int) (heuristic.getCost(a.pos, end) * costProvider.getMinCost()); |
||||||
|
a.parent = current; |
||||||
|
|
||||||
|
if (costProvider.isAccessible(a.pos)) { |
||||||
|
if (!closed.contains(a)) { |
||||||
|
|
||||||
|
if (open.contains(a)) { |
||||||
|
|
||||||
|
boolean needSort = false; |
||||||
|
|
||||||
|
// find where it is
|
||||||
|
for (final Node n : open) { |
||||||
|
if (n.pos.equals(a.pos)) { // found it
|
||||||
|
if (n.g_cost > a.g_cost) { |
||||||
|
n.parent = current; |
||||||
|
n.g_cost = a.g_cost; |
||||||
|
needSort = true; |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (needSort) Collections.sort(open, F_COMPARATOR); |
||||||
|
|
||||||
|
} else { |
||||||
|
open.add(a); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
if (current == null) { |
||||||
|
return null; // no path found
|
||||||
|
} |
||||||
|
|
||||||
|
final LinkedList<Coord> path = new LinkedList<>(); |
||||||
|
|
||||||
|
// extract path elements
|
||||||
|
while (current != null) { |
||||||
|
path.addFirst(current.pos); |
||||||
|
current = current.parent; |
||||||
|
} |
||||||
|
|
||||||
|
return path; |
||||||
|
} |
||||||
|
|
||||||
|
private static class Node { |
||||||
|
|
||||||
|
Coord pos; |
||||||
|
int g_cost; // to get there
|
||||||
|
int h_cost; // to target
|
||||||
|
Node parent; |
||||||
|
|
||||||
|
|
||||||
|
public Node(Coord pos) |
||||||
|
{ |
||||||
|
this.pos = pos; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
int fCost() |
||||||
|
{ |
||||||
|
return g_cost + h_cost; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public int hashCode() |
||||||
|
{ |
||||||
|
final int prime = 31; |
||||||
|
int result = 1; |
||||||
|
result = prime * result + ((pos == null) ? 0 : pos.hashCode()); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean equals(Object obj) |
||||||
|
{ |
||||||
|
if (this == obj) return true; |
||||||
|
if (obj == null) return false; |
||||||
|
if (!(obj instanceof Node)) return false; |
||||||
|
final Node other = (Node) obj; |
||||||
|
if (pos == null) { |
||||||
|
if (other.pos != null) return false; |
||||||
|
} else if (!pos.equals(other.pos)) return false; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public String toString() |
||||||
|
{ |
||||||
|
return "N " + pos + ", G =" + g_cost + ", H = " + h_cost; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static class FComparator implements Comparator<Node> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public int compare(Node n1, Node n2) |
||||||
|
{ |
||||||
|
return n1.fCost() - n2.fCost(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,14 @@ |
|||||||
|
package mightypork.rogue.world.tile; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Data storage for renderer / entity. |
||||||
|
* |
||||||
|
* @author MightyPork |
||||||
|
*/ |
||||||
|
public class TileRenderData { |
||||||
|
|
||||||
|
public byte shadows; |
||||||
|
public boolean shadowsComputed; |
||||||
|
|
||||||
|
} |
@ -0,0 +1,34 @@ |
|||||||
|
package mightypork.rogue.world.tile.models; |
||||||
|
|
||||||
|
|
||||||
|
import mightypork.rogue.world.tile.Tile; |
||||||
|
import mightypork.rogue.world.tile.renderers.DoorRenderer; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* Template for floor tiles with no metadata |
||||||
|
* |
||||||
|
* @author MightyPork |
||||||
|
*/ |
||||||
|
public class SimpleDoor extends Wall { |
||||||
|
|
||||||
|
public SimpleDoor(int id) |
||||||
|
{ |
||||||
|
super(id); |
||||||
|
setRenderer(new DoorRenderer("tile.door.closed", "tile.door.open")); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isWalkable(Tile tile) |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isDoor() |
||||||
|
{ |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
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.util.math.constraints.rect.Rect; |
||||||
|
|
||||||
|
|
||||||
|
public class DoorRenderer extends TileRenderer { |
||||||
|
|
||||||
|
private final TxQuad closed; |
||||||
|
private final TxQuad open; |
||||||
|
|
||||||
|
|
||||||
|
public DoorRenderer(String quadClosed, String quadOpen) |
||||||
|
{ |
||||||
|
this.closed = Res.getTxQuad(quadClosed); |
||||||
|
this.open = Res.getTxQuad(quadOpen); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void render(TileRenderContext context) |
||||||
|
{ |
||||||
|
final Tile t = context.getTile(); |
||||||
|
final Rect rect = context.getRect(); |
||||||
|
|
||||||
|
if (t.isOccupied()) { |
||||||
|
Render.quadTextured(rect, closed); |
||||||
|
} else { |
||||||
|
Render.quadTextured(rect, open); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,81 @@ |
|||||||
|
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.getModel().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); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,11 @@ |
|||||||
|
package mightypork.rogue.world.tile.renderers; |
||||||
|
|
||||||
|
|
||||||
|
public class WallRenderer extends BasicTileRenderer { |
||||||
|
|
||||||
|
public WallRenderer(String sheetKey) |
||||||
|
{ |
||||||
|
super(sheetKey); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -1,33 +0,0 @@ |
|||||||
package mightypork.test; |
|
||||||
|
|
||||||
|
|
||||||
import java.util.Locale; |
|
||||||
|
|
||||||
import mightypork.util.math.noise.NoiseGen; |
|
||||||
|
|
||||||
|
|
||||||
public class TestPerlin { |
|
||||||
|
|
||||||
public static void main(String[] args) |
|
||||||
{ |
|
||||||
Locale.setDefault(Locale.ENGLISH); |
|
||||||
|
|
||||||
final int w = 50, h = 50; |
|
||||||
|
|
||||||
final NoiseGen ng = new NoiseGen(0.12, 0, 2.5, 5, (long) (Math.random() * 100)); |
|
||||||
|
|
||||||
final double[][] map = ng.buildMap(w, h); |
|
||||||
|
|
||||||
final char[] colors = { ' ', '░', '▒', '▓', '█' }; |
|
||||||
|
|
||||||
for (int y = 0; y < h; y++) { |
|
||||||
for (int x = 0; x < w; x++) { |
|
||||||
// "pixels" two-thick
|
|
||||||
System.out.print(colors[(int) Math.floor(map[y][x])]); |
|
||||||
System.out.print(colors[(int) Math.floor(map[y][x])]); |
|
||||||
} |
|
||||||
System.out.println(); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
Loading…
Reference in new issue