MapLoader.java
package com.devcharles.piazzapanic.utility;
import java.util.HashMap;
import java.util.Map;
import com.badlogic.ashley.core.Engine;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.maps.MapObject;
import com.badlogic.gdx.maps.MapObjects;
import com.badlogic.gdx.maps.MapProperties;
import com.badlogic.gdx.maps.objects.RectangleMapObject;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;
import com.badlogic.gdx.maps.tiled.TmxMapLoader;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.utils.Array;
import com.devcharles.piazzapanic.components.PlayerComponent;
import com.devcharles.piazzapanic.components.FoodComponent.FoodType;
import com.devcharles.piazzapanic.utility.Station.StationType;
import com.devcharles.piazzapanic.utility.box2d.Box2dLocation;
import com.devcharles.piazzapanic.utility.box2d.LightBuilder;
import com.devcharles.piazzapanic.utility.box2d.MapBodyBuilder;
import box2dLight.RayHandler;
/**
* Loads and owns the {@link TiledMap} object. Creates entities from map
* metadata.
*/
public class MapLoader {
public TiledMap map;
private int ppt = 16;
private EntityFactory factory;
// Object properties
static final String lightIdProperty = "lightID";
static final String cookSpawnPoint = "cookspawnpoint";
static final String aiSpawnPoint = "aispawnpoint";
static final String aiObjective = "aiobjective";
// Layers relevant to loading the map
static final String objectLayer = "MapObjects";
static final String collisionLayer = "Obstacles";
static final String stationLayer = "station";
static final String counterTopLayer = "countertop";
// Tile properties
static final String stationIdProperty = "stationID";
static final String ingredientTypeProperty = "ingredientType";
private Map<Integer, Box2dLocation> aiObjectives;
/**
* Load the {@link TiledMap} from a {@code .tmx} file.
*
* @param path Path to map file.
* @param ppt Pixels per tile (default 16).
* @param factory {@link EntityFactory} instance to create entities based on the
* map metadata.
*/
public MapLoader(String path, Integer ppt, EntityFactory factory) {
if (ppt != null) {
this.ppt = ppt;
}
if (path != null) {
map = new TmxMapLoader().load(path);
} else {
map = new TmxMapLoader().load("v2/map.tmx");
}
this.factory = factory;
}
/**
*
* @param world The Box2D world instance to add bodies to.
* @return The bodies created from the map.
*/
public Array<Body> buildCollisions(World world) {
return MapBodyBuilder.buildShapes(map, ppt, world);
}
/**
* Create lights, spawnpoints, AI paths from map metadata.
*
* @param engine Ashley {@link Engine} instance.
* @param rayHandler {@link RayHandler} to add lights to.
*/
public void buildFromObjects(Engine engine, RayHandler rayHandler) {
MapObjects objects = map.getLayers().get(objectLayer).getObjects();
aiObjectives = new HashMap<Integer, Box2dLocation>();
for (MapObject mapObject : objects) {
if (mapObject instanceof RectangleMapObject) {
MapProperties properties = mapObject.getProperties();
RectangleMapObject point = (RectangleMapObject) mapObject;
Vector2 pos = new Vector2(point.getRectangle().x / ppt, point.getRectangle().y / ppt);
if (properties.containsKey(lightIdProperty)) {
int lightID = (int) properties.get(lightIdProperty);
Gdx.app.log("map parsing",
String.format("Light typeid %d at x:%.2f y:%.2f", lightID, pos.x, pos.y));
switch (lightID) {
case 0:
LightBuilder.createPointLight(rayHandler, pos.x, pos.y, Color.TAN.cpy().sub(0, 0, 0, 0.25f),
10, true);
break;
case 1:
LightBuilder.createPointLight(rayHandler, pos.x, pos.y, Color.TAN.cpy().sub(0, 0, 0, 0.5f),
0.8f, false);
break;
case 2:
LightBuilder.createRoomLight(rayHandler, pos.x, pos.y, Color.TAN.cpy().sub(0, 0, 0, 0.25f),
25, true);
break;
case 3:
LightBuilder.createRoomLight(rayHandler, pos.x, pos.y, Color.TAN.cpy().sub(0, 0, 0, 0.25f),
25, false);
break;
}
} else if (properties.containsKey(cookSpawnPoint)) {
int cookID = (int) properties.get(cookSpawnPoint);
Gdx.app.log("map parsing", String.format("Cook spawn point at x:%.2f y:%.2f", pos.x, pos.y));
Entity cook = factory.createCook((int) pos.x, (int) pos.y);
if (cookID == 0) {
cook.add(new PlayerComponent());
}
} else if (properties.containsKey(aiSpawnPoint)) {
Gdx.app.log("map parsing", String.format("Ai spawn point at x:%.2f y:%.2f", pos.x, pos.y));
aiObjectives.put(-2, new Box2dLocation(pos, 0));
} else if (properties.containsKey(aiObjective)) {
int objective = (int) properties.get(aiObjective);
aiObjectives.put(objective, new Box2dLocation(new Vector2(pos.x, pos.y), (float) (1.5f * Math.PI)));
Gdx.app.log("map parsing",
String.format("Ai objective %d at x:%.2f y:%.2f", objective, pos.x, pos.y));
}
}
}
}
/**
* Get the {@link Map} of objectives the AI can travel to.
* See the map file in the Tiled editor to preview ai objectives.
*
* @return
*/
public Map<Integer, Box2dLocation> getObjectives() {
return aiObjectives;
}
/**
* Create station entities from map metadata. Metadata is given to the tile in
* Edit Tileset -> Tile Properties.
*
* @param engine Ashley {@link Engine} instance.
* @param world The Box2D world instance to add sensor bodies to.
*/
public void buildStations(Engine engine, World world) {
TiledMapTileLayer stations = (TiledMapTileLayer) (map.getLayers().get(stationLayer));
TiledMapTileLayer stations_f = (TiledMapTileLayer) (map.getLayers().get(stationLayer + "_f"));
int columns = stations.getWidth();
int rows = stations.getHeight();
Cell currentCell;
for (int i = 0; i < columns; i++) {
for (int j = 0; j < rows; j++) {
currentCell = stations.getCell(i, j) != null ? stations.getCell(i, j) : stations_f.getCell(i, j);
if (currentCell != null) {
Object object = currentCell.getTile().getProperties().get(stationIdProperty);
if (object != null && object instanceof Integer) {
StationType stationType = StationType.from((int) object);
FoodType ingredientType = null;
if (stationType == StationType.ingredient) {
ingredientType = FoodType
.from((Integer) currentCell.getTile().getProperties().get(ingredientTypeProperty));
}
Object lockedProperty = currentCell.getTile().getProperties().get("locked");
boolean locked =false;
if(lockedProperty!=null){
if(lockedProperty.equals(true)){
locked=true;
}
}
factory.createStation(stationType, new Vector2((i * 2) + 1, (j * 2) + 1), ingredientType, new Vector2(i,j),locked);
}
}
}
}
}
}