diff --git a/Shared/World.cs b/Shared/World.cs index b904a70..c840efd 100644 --- a/Shared/World.cs +++ b/Shared/World.cs @@ -8,6 +8,10 @@ using System.Linq; namespace SemiColinGames { public class Tile { + public static int CompareByX(Tile t1, Tile t2) { + return t1.Position.X.CompareTo(t2.Position.X); + } + private TextureRef texture; private Rectangle textureSource; @@ -29,19 +33,19 @@ namespace SemiColinGames { public class World { + public const int TileSize = 16; + // Size of World in terms of tile grid. private int gridWidth; private int gridHeight; - - // TODO: remove this. - public const int TileSize = 16; - readonly Tile[] obstacles; - readonly Tile[] decorations; + private readonly Tile[] obstacles; + private readonly Tile[] decorations; // Kept around for resetting the world's entities after player death or level restart. - readonly JToken entitiesLayer; + private readonly JToken entitiesLayer; + private NPC[] npcs; - NPC[] npcs; public Player Player { get; private set; } + public AABB[] CollisionTargets { get; } // Size of World in pixels. public int Width { @@ -52,61 +56,6 @@ namespace SemiColinGames { get { return gridHeight * TileSize; } } - private List ParseLayer(JToken layer) { - string layerName = layer.SelectToken("name").Value(); - - var tileList = new List(); - - int layerWidth = layer.SelectToken("gridCellsX").Value(); - int layerHeight = layer.SelectToken("gridCellsY").Value(); - gridWidth = Math.Max(gridWidth, layerWidth); - gridHeight = Math.Max(gridHeight, layerHeight); - - int dataIndex = -1; - int tileWidth = layer.SelectToken("gridCellWidth").Value(); - int tileHeight = layer.SelectToken("gridCellHeight").Value(); - int textureWidth = Textures.Grassland.Get.Width / tileWidth; - foreach (int textureIndex in layer.SelectToken("data").Values()) { - dataIndex++; - if (textureIndex == -1) { - continue; - } - int i = dataIndex % layerWidth; - int j = dataIndex / layerWidth; - Rectangle position = new Rectangle( - i * tileWidth, j * tileHeight, tileWidth, tileHeight); - int x = textureIndex % textureWidth; - int y = textureIndex / textureWidth; - Rectangle textureSource = new Rectangle( - x * tileWidth, y * tileHeight, tileWidth, tileHeight); - bool isHazard = layerName == "hazards"; - tileList.Add(new Tile(Textures.Grassland, textureSource, position, isHazard)); - } - - return tileList; - } - - private (Player, NPC[]) ParseEntities(JToken layer) { - Player player = null; - List npcs = new List(); - foreach (JToken entity in layer.SelectToken("entities").Children()) { - string name = entity.SelectToken("name").Value(); - int x = entity.SelectToken("x").Value(); - int y = entity.SelectToken("y").Value(); - int facing = entity.SelectToken("flippedX").Value() ? -1 : 1; - if (name == "player") { - player = new Player(new Point(x, y), facing); - } else if (name == "executioner") { - npcs.Add(new NPC(new Point(x, y), facing)); - } - } - return (player, npcs.ToArray()); - } - - static int CompareByX(Tile t1, Tile t2) { - return t1.Position.X.CompareTo(t2.Position.X); - } - public World(string json) { JObject root = JObject.Parse(json); @@ -135,7 +84,7 @@ namespace SemiColinGames { // Get all the obstacles into a single array, sorted by X. obstacleTiles.AddRange(hazardTiles); obstacles = obstacleTiles.ToArray(); - Array.Sort(obstacles, CompareByX); + Array.Sort(obstacles, Tile.CompareByX); // The background tiles are added before the rest of the decorations, so that they're drawn // in the back. backgroundTiles.AddRange(decorationTiles); @@ -162,6 +111,61 @@ namespace SemiColinGames { new Vector2(Width + 1, 0), new Vector2(1, float.MaxValue)); } + private List ParseLayer(JToken layer) { + string layerName = layer.SelectToken("name").Value(); + + var tileList = new List(); + + int layerWidth = layer.SelectToken("gridCellsX").Value(); + int layerHeight = layer.SelectToken("gridCellsY").Value(); + gridWidth = Math.Max(gridWidth, layerWidth); + gridHeight = Math.Max(gridHeight, layerHeight); + + int dataIndex = -1; + int tileWidth = layer.SelectToken("gridCellWidth").Value(); + int tileHeight = layer.SelectToken("gridCellHeight").Value(); + int textureWidth = Textures.Grassland.Get.Width / tileWidth; + foreach (int textureIndex in layer.SelectToken("data").Values()) { + dataIndex++; + if (textureIndex == -1) { + continue; + } + int i = dataIndex % layerWidth; + int j = dataIndex / layerWidth; + Rectangle position = new Rectangle( + i * tileWidth, j * tileHeight, tileWidth, tileHeight); + int x = textureIndex % textureWidth; + int y = textureIndex / textureWidth; + Rectangle textureSource = new Rectangle( + x * tileWidth, y * tileHeight, tileWidth, tileHeight); + bool isHazard = layerName == "hazards"; + tileList.Add(new Tile(Textures.Grassland, textureSource, position, isHazard)); + } + + return tileList; + } + + private (Player, NPC[]) ParseEntities(JToken layer) { + Player player = null; + List npcs = new List(); + foreach (JToken entity in layer.SelectToken("entities").Children()) { + string name = entity.SelectToken("name").Value(); + int x = entity.SelectToken("x").Value(); + int y = entity.SelectToken("y").Value(); + int facing = entity.SelectToken("flippedX").Value() ? -1 : 1; + if (name == "player") { + player = new Player(new Point(x, y), facing); + } else if (name == "executioner") { + npcs.Add(new NPC(new Point(x, y), facing)); + } + } + return (player, npcs.ToArray()); + } + + private void Reset() { + (Player, npcs) = ParseEntities(entitiesLayer); + } + public void Update(float modelTime, History input) { Player.Update(modelTime, this, input); foreach (NPC npc in npcs) { @@ -172,10 +176,6 @@ namespace SemiColinGames { } } - void Reset() { - (Player, npcs) = ParseEntities(entitiesLayer); - } - // Draws everything that's behind the player, from back to front. public void DrawBackground(SpriteBatch spriteBatch) { foreach (Tile t in decorations) { @@ -192,7 +192,5 @@ namespace SemiColinGames { t.Draw(spriteBatch); } } - - public AABB[] CollisionTargets { get; } } }