package com.deftwun.zombiecopter; import net.dermetfan.gdx.physics.box2d.Box2DMapObjectParser; import com.badlogic.ashley.core.Entity; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.maps.Map; import com.badlogic.gdx.maps.MapLayer; 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.TmxMapLoader; import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer; import com.badlogic.gdx.math.Matrix4; import com.badlogic.gdx.math.Rectangle; 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.Logger; import com.badlogic.gdx.utils.ObjectMap; import com.deftwun.zombiecopter.components.PhysicsComponent; import com.deftwun.zombiecopter.systems.SpawnSystem; public class Level { private Logger logger = new Logger("Level",Logger.INFO); private TiledMap map; private OrthogonalTiledMapRenderer mapRenderer; private SpriteBatch batch; private Entity entity; public Level() { logger.debug("initialising"); batch = new SpriteBatch(); map = null; } public Level(String fileName){ logger.debug("initialising"); batch = new SpriteBatch(); loadTiledMap(fileName); } public void clear(){ logger.debug("Clearing"); if (map != null) { map.dispose(); map = null; } if (entity != null){ App.engine.removeEntity(entity); entity = null; } if (mapRenderer != null){ mapRenderer.dispose(); mapRenderer = null; } } public Entity getEntity(){ return entity; } public void loadTiledMap(String mapName){ logger.debug("Loading TiledMap: " + mapName); this.clear(); try{ map = new TmxMapLoader().load(mapName); } catch(Exception e){ logger.error("Map load failed .. " + e.getMessage()); return; } mapRenderer = new OrthogonalTiledMapRenderer(map,batch); createPhysics(map); createEntities(map); createSpawnZones(map); createDropOffPoints(map); } private void createPhysics(Map map) { logger.debug("Creating Physics"); String layerName = "physics"; //Layer objects MapLayer layer = map.getLayers().get(layerName); if (layer == null) { logger.error("layer " + layerName + " does not exist"); return; } World world = App.engine.systems.physics.world; //world.dispose(); Box2DMapObjectParser parser = new Box2DMapObjectParser(1/App.engine.PIXELS_PER_METER); parser.load(world,layer); logger.debug(parser.getBodies().size + " bodies were parsed in layer '" + layerName + "'"); logger.debug(parser.getFixtures().size + " fixtures were parsed in layer '" + layerName + "'"); //Level Entity (If it has physics then it needs to be associated with an entity, // other wise collisions won't be handled properly.) entity = App.engine.createEntity(); PhysicsComponent physics = App.engine.createComponent(PhysicsComponent.class); for (ObjectMap.Entry<String,Body> entry : parser.getBodies()){ physics.addBody(entry.key,entry.value); } physics.setFilter(CollisionBits.Terrain,CollisionBits.Mask_Terrain); entity.add(physics); App.engine.addEntity(entity); } private void createDropOffPoints(Map map){ logger.debug("Creating DropOffPoints"); String layerName = "dropoff"; //dropOffPoint map layer MapLayer layer = map.getLayers().get(layerName); if (layer == null) { logger.error("layer " + layerName + " does not exist"); return; } //Layer objects MapObjects objects = layer.getObjects(); for (MapObject mapObj : objects){ //Object properties. //name and position are set by the tiled editor. The rest are custom properties Vector2 position = new Vector2(); float range = 1; MapProperties prop = mapObj.getProperties(); Object x = prop.get("x"), y = prop.get("y"), r = prop.get("range"); if (r != null) range = Float.parseFloat(r.toString()); if (x != null && y != null) position.set((Float)x,(Float)y).scl(1/App.engine.PIXELS_PER_METER); App.engine.systems.dropoff.add(new DropOffPoint(position,range)); } } private void createSpawnZones(Map map){ logger.debug("Creating SpawnPoints"); String layerName = "spawn"; //spawnPoint map layer MapLayer layer = map.getLayers().get(layerName); if (layer == null) { logger.error("layer " + layerName + " does not exist"); return; } //Layer objects float units = App.engine.PIXELS_PER_METER; MapObjects objects = layer.getObjects(); for (MapObject mapObj : objects){ logger.debug("found spawn zone"); //Spawn area rectangle Rectangle rect; if (mapObj instanceof RectangleMapObject){ rect = ((RectangleMapObject) mapObj).getRectangle(); rect.height /= units; rect.width /= units; rect.x /= units; rect.y /= units; } else { logger.error("spawn zones should only be rectangles"); continue; } //Object properties. //name and position are set by the tiled editor. The rest are custom properties String name = mapObj.getName(); int maximum = 0; float delay = 3; logger.debug("Creating '" + name + "' spawn zone"); MapProperties prop = mapObj.getProperties(); Object max = prop.get("maximum"), dly = prop.get("delay"); if (max != null) maximum = Integer.parseInt(max.toString()); if (dly != null) delay = Float.parseFloat(dly.toString()); SpawnSystem spawner = App.engine.systems.spawn; spawner.add(new SpawnZone(rect,name,maximum,delay)); } } private void createEntities(Map map) { logger.debug("Creating Entities"); String layerName = "entities"; MapLayer layer = map.getLayers().get(layerName); if (layer == null) { logger.error("layer " + layerName + " does not exist"); return; } //Entity objects Vector2 position = new Vector2(), velocity = new Vector2(); MapObjects objects = layer.getObjects(); for (MapObject mapObj : objects){ MapProperties prop = mapObj.getProperties(); Object x = prop.get("x"), y = prop.get("y"), vx = prop.get("vx"), vy = prop.get("vy"); position.set(0,0); velocity.set(0,0); if (x != null && y != null) position.set((Float)x,(Float)y).scl(1/App.engine.PIXELS_PER_METER); if (vx != null && y != null) velocity.set((Float)vx,(Float)vy); logger.debug(" -Create: " + mapObj.getName()); Entity e = App.engine.factory.build(mapObj.getName(),position,velocity); if (mapObj.getName().equals("player")) App.engine.systems.player.setPlayer(e); } } public void render(Matrix4 projection){ mapRenderer.setView((OrthographicCamera) App.engine.systems.camera.getCamera()); mapRenderer.render(); } public void renderLayer(String layerName, Matrix4 projection){ mapRenderer.setView((OrthographicCamera) App.engine.systems.camera.getCamera()); MapLayer layer = map.getLayers().get(layerName); if (layer != null) mapRenderer.renderTileLayer((TiledMapTileLayer) layer); } public void renderLayer(int index, Matrix4 projection){ mapRenderer.setView((OrthographicCamera) App.engine.systems.camera.getCamera()); MapLayer layer = map.getLayers().get(index); if (layer != null) mapRenderer.renderTileLayer((TiledMapTileLayer) layer); } }