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