186 lines
6.1 KiB
Java
186 lines
6.1 KiB
Java
package tfg;
|
|
|
|
import org.jsfml.graphics.Drawable;
|
|
import org.jsfml.graphics.PrimitiveType;
|
|
import org.jsfml.graphics.RenderStates;
|
|
import org.jsfml.graphics.RenderTarget;
|
|
import org.jsfml.graphics.RenderWindow;
|
|
import org.jsfml.graphics.Texture;
|
|
import org.jsfml.graphics.Vertex;
|
|
import org.jsfml.graphics.VertexArray;
|
|
import org.jsfml.system.Vector2f;
|
|
import org.jsfml.system.Vector2i;
|
|
|
|
import java.io.IOException;
|
|
import java.nio.file.Paths;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collections;
|
|
import java.util.Iterator;
|
|
|
|
/**
|
|
* A map or level for the player to interact in. Can be created
|
|
* manually or procedurally.
|
|
* @author Ritchie Cunningham
|
|
*/
|
|
public class Map implements Drawable {
|
|
/**
|
|
* The size (length, width) of the map.
|
|
*/
|
|
private Vector2i dimensions = new Vector2i(0, 0);
|
|
private Tile[][] tileArray;
|
|
/**
|
|
* The tilesheet texture.
|
|
*/
|
|
private Texture tilesheetTexture = new Texture();
|
|
/**
|
|
* Vertex array for the tile map.
|
|
* This is a streamlined way to draw many sprites at once.
|
|
*/
|
|
private VertexArray vertexArray = new VertexArray();
|
|
|
|
private final ArrayList<Entity> entitiesOnMap = new ArrayList<Entity>();
|
|
|
|
/**
|
|
* Create a new map of specified size and tile type.
|
|
* @param l Map length.
|
|
* @param w Map width.
|
|
* @param t Default tile to auto-pupulate map.
|
|
*/
|
|
public Map(int l, int w, Tile t) {
|
|
dimensions = new Vector2i(l,w);
|
|
tileArray = new Tile[dimensions.x][dimensions.y];
|
|
try {
|
|
tilesheetTexture.loadFromFile(Paths.get("res/terrain.png"));
|
|
} catch(IOException ex) {
|
|
ex.printStackTrace();
|
|
}
|
|
/* Set vertex array to use quads because the tiles are square. */
|
|
vertexArray.setPrimitiveType(PrimitiveType.QUADS);
|
|
initializeMap(t); /* Auto-populate the map with specified tile. */
|
|
}
|
|
|
|
/**
|
|
* Create a new map of speceified size that default to grass.
|
|
* @param l Map length.
|
|
* @param w Map width.
|
|
*/
|
|
public Map(int l, int w) {
|
|
this(l,w,Tile.GRASS);
|
|
}
|
|
|
|
/**
|
|
* Fill the entire map to the specified tile.
|
|
* @param initialTile The tile to populate the map with.
|
|
*/
|
|
public void initializeMap(Tile initialTile) {
|
|
/**
|
|
* Arrays.fill does not work with matrices,
|
|
* therefore we have to loop through the outer level to fill the inner.
|
|
*/
|
|
for(Tile[] row : tileArray) {
|
|
/* Set each tile in the row to the specified tile. */
|
|
Arrays.fill(row,initialTile);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Draw the map onto the window.
|
|
*/
|
|
public void draw(RenderTarget target, RenderStates states) {
|
|
vertexArray.clear(); /* empty array from previous draw. */
|
|
final int tileSize = Tile.getSize();
|
|
/* Iterate through every tile in the map. */
|
|
for(int i = 0; i < dimensions.x; i++) {
|
|
for(int j = 0; j < dimensions.y; j++) {
|
|
Tile tileType = tileArray[i][j]; /* Grab current tile in the loop. */
|
|
/* Grab texture coord to render the tile. */
|
|
Vector2f textureCoords = Tile.getTextureCoords(tileType);
|
|
|
|
/*
|
|
* Add each corner of the tile to the vertex array
|
|
* counter-clockwise.
|
|
*/
|
|
/* Top left. */
|
|
vertexArray.add(new Vertex(
|
|
new Vector2f(i*tileSize, j* tileSize), textureCoords));
|
|
|
|
/* Bottom left. */
|
|
vertexArray.add(new Vertex(
|
|
new Vector2f(i*tileSize,(j*tileSize)+tileSize),
|
|
Vector2f.add(textureCoords, new Vector2f(tileSize,tileSize))));
|
|
|
|
/* Bottom right. */
|
|
vertexArray.add(new Vertex(
|
|
new Vector2f((i*tileSize)+tileSize, (j*tileSize)+tileSize),
|
|
Vector2f.add(textureCoords, new Vector2f(tileSize,tileSize))));
|
|
|
|
/* Top right. */
|
|
vertexArray.add(new Vertex(
|
|
new Vector2f((i*tileSize)+tileSize, j*tileSize),
|
|
Vector2f.add(textureCoords, new Vector2f(tileSize,0))));
|
|
}
|
|
}
|
|
/* Apply texture to the vertex array. */
|
|
RenderStates newStates = new RenderStates(tilesheetTexture);
|
|
vertexArray.draw(target, newStates); /* Draw vertex array. */
|
|
}
|
|
|
|
/**
|
|
* Return the tile at specified location.
|
|
* @param l Location of the tile to get.
|
|
* @return Tile at the specified location.
|
|
*/
|
|
public Tile getTile(Location l) {
|
|
Vector2i position = l.getPosition(); /* Get pos from loc. */
|
|
Tile t = tileArray[position.x][position.y]; /* Get tile at this pos. */
|
|
return t;
|
|
}
|
|
|
|
/**
|
|
* Determine whether or not the location fits within the map.
|
|
* @param l Location to test.
|
|
* @return If location is valid.
|
|
*/
|
|
public boolean isValidLocation(Location l) {
|
|
Vector2i coordinates = l.getPosition(); /* Pos from last location. */
|
|
/* Return true if the location is greater than 0. */
|
|
return ((coordinates.x >= 0) && (coordinates.y >=0) &&
|
|
(coordinates.x < dimensions.x) &&
|
|
(coordinates.y < dimensions.y) &&
|
|
Tile.getCanWalkOn(getTile(l)) &&
|
|
(getEntityatLocation(l) == null));
|
|
}
|
|
|
|
public Entity getEntityatLocation(Location l) {
|
|
Iterator<Entity> it = entitiesOnMap.iterator();
|
|
while(it.hasNext()) {
|
|
Entity e = it.next();
|
|
if(e.getLocation().equals(1)) {
|
|
return e;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public void addEntity(Entity e) {
|
|
if(getEntityatLocation(e.getLocation()) == null) {
|
|
e.setParentMap(this);
|
|
entitiesOnMap.add(e);
|
|
}
|
|
}
|
|
|
|
public void drawAllEntities(RenderWindow w) {
|
|
for(Entity e : entitiesOnMap) {
|
|
w.draw(e);
|
|
}
|
|
}
|
|
|
|
public void updateAllEntities() {
|
|
Collections.sort(entitiesOnMap);
|
|
for(Entity e : entitiesOnMap) {
|
|
e.update();
|
|
}
|
|
}
|
|
}
|