|
|
@ -5,25 +5,49 @@ using System.Collections.Generic; |
|
|
|
using System.Linq; |
|
|
|
|
|
|
|
namespace SemiColinGames { |
|
|
|
enum Terrain { |
|
|
|
Grass, |
|
|
|
GrassL, |
|
|
|
GrassR, |
|
|
|
Rock, |
|
|
|
RockL, |
|
|
|
RockR, |
|
|
|
WaterL, |
|
|
|
WaterR, |
|
|
|
Block, |
|
|
|
Spike, |
|
|
|
Wood, |
|
|
|
WoodL, |
|
|
|
WoodR, |
|
|
|
WoodVert, |
|
|
|
FenceL, |
|
|
|
Fence, |
|
|
|
FencePost, |
|
|
|
FenceR, |
|
|
|
class Terrain { |
|
|
|
|
|
|
|
public static Terrain FromSymbol(char symbol) { |
|
|
|
if (mapping.ContainsKey(symbol)) { |
|
|
|
return mapping[symbol]; |
|
|
|
} else { |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private static Dictionary<char, Terrain> mapping = new Dictionary<char, Terrain>(); |
|
|
|
|
|
|
|
public static Terrain Grass = new Terrain('=', true); |
|
|
|
public static Terrain GrassL = new Terrain('<', true); |
|
|
|
public static Terrain GrassR = new Terrain('>', true); |
|
|
|
public static Terrain Rock = new Terrain('.', true); |
|
|
|
public static Terrain RockL = new Terrain('[', true); |
|
|
|
public static Terrain RockR = new Terrain(']', true); |
|
|
|
public static Terrain WaterL = new Terrain('~', false); |
|
|
|
public static Terrain WaterR = new Terrain('`', false); |
|
|
|
public static Terrain Block = new Terrain('X', true); |
|
|
|
public static Terrain Spike = new Terrain('^', true); |
|
|
|
public static Terrain Wood = new Terrain('_', true); |
|
|
|
public static Terrain WoodL = new Terrain('(', true); |
|
|
|
public static Terrain WoodR = new Terrain(')', true); |
|
|
|
public static Terrain WoodVert = new Terrain('|', false); |
|
|
|
public static Terrain WoodVertL = new Terrain('/', false); |
|
|
|
public static Terrain WoodVertR = new Terrain('\\', false); |
|
|
|
public static Terrain WoodBottom = new Terrain('v', false); |
|
|
|
public static Terrain FenceL = new Terrain('d', false); |
|
|
|
public static Terrain Fence = new Terrain('f', false); |
|
|
|
public static Terrain FencePost = new Terrain('x', false); |
|
|
|
public static Terrain FenceR = new Terrain('b', false); |
|
|
|
|
|
|
|
public bool IsObstacle { get; private set; } |
|
|
|
|
|
|
|
private Terrain(char symbol, bool isObstacle) { |
|
|
|
if (mapping.ContainsKey(symbol)) { |
|
|
|
throw new ArgumentException("already have a terrain with symbol " + symbol); |
|
|
|
} |
|
|
|
IsObstacle = isObstacle; |
|
|
|
mapping[symbol] = this; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
class TileFactory { |
|
|
@ -56,6 +80,9 @@ namespace SemiColinGames { |
|
|
|
{ Terrain.WoodL, GetTextureSource(Textures.Grassland, 9, 3) }, |
|
|
|
{ Terrain.WoodR, GetTextureSource(Textures.Grassland, 12, 3) }, |
|
|
|
{ Terrain.WoodVert, GetTextureSource(Textures.Grassland, 9, 5) }, |
|
|
|
{ Terrain.WoodVertL, GetTextureSource(Textures.Grassland, 9, 4) }, |
|
|
|
{ Terrain.WoodVertR, GetTextureSource(Textures.Grassland, 12, 4) }, |
|
|
|
{ Terrain.WoodBottom, GetTextureSource(Textures.Grassland, 10, 5) }, |
|
|
|
{ Terrain.FenceL, GetTextureSource(Textures.Grassland, 5, 4) }, |
|
|
|
{ Terrain.Fence, GetTextureSource(Textures.Grassland, 6, 4) }, |
|
|
|
{ Terrain.FencePost, GetTextureSource(Textures.Grassland, 7, 4) }, |
|
|
@ -98,6 +125,7 @@ namespace SemiColinGames { |
|
|
|
|
|
|
|
public const int TileSize = 16; |
|
|
|
readonly Tile[] tiles; |
|
|
|
readonly Tile[] decorations; |
|
|
|
|
|
|
|
// Size of World in terms of tile grid.
|
|
|
|
private readonly int tileWidth; |
|
|
@ -112,31 +140,10 @@ namespace SemiColinGames { |
|
|
|
get { return tileHeight * TileSize; } |
|
|
|
} |
|
|
|
|
|
|
|
private static readonly Dictionary<char, Terrain> charToTerrain = |
|
|
|
new Dictionary<char, Terrain>() { |
|
|
|
{ '=', Terrain.Grass }, |
|
|
|
{ '<', Terrain.GrassL }, |
|
|
|
{ '>', Terrain.GrassR }, |
|
|
|
{ '.', Terrain.Rock }, |
|
|
|
{ '[', Terrain.RockL }, |
|
|
|
{ ']', Terrain.RockR }, |
|
|
|
{ '~', Terrain.WaterL }, |
|
|
|
{ '`', Terrain.WaterR }, |
|
|
|
{ 'X', Terrain.Block }, |
|
|
|
{ '^', Terrain.Spike }, |
|
|
|
{ '_', Terrain.Wood }, |
|
|
|
{ '(', Terrain.WoodL }, |
|
|
|
{ ')', Terrain.WoodR }, |
|
|
|
{ '|', Terrain.WoodVert }, |
|
|
|
{ 'd', Terrain.FenceL }, |
|
|
|
{ 'f', Terrain.Fence }, |
|
|
|
{ 'x', Terrain.FencePost }, |
|
|
|
{ 'b', Terrain.FenceR }, |
|
|
|
}; |
|
|
|
|
|
|
|
public World(string levelSpecification) { |
|
|
|
TileFactory factory = new TileFactory(); |
|
|
|
var tilesList = new List<Tile>(); |
|
|
|
var decorationsList = new List<Tile>(); |
|
|
|
string[] worldDesc = levelSpecification.Split('\n'); |
|
|
|
tileWidth = worldDesc.AsQueryable().Max(a => a.Length); |
|
|
|
tileHeight = worldDesc.Length; |
|
|
@ -145,15 +152,21 @@ namespace SemiColinGames { |
|
|
|
for (int j = 0; j < tileHeight; j++) { |
|
|
|
if (i < worldDesc[j].Length) { |
|
|
|
char key = worldDesc[j][i]; |
|
|
|
if (charToTerrain.ContainsKey(key)) { |
|
|
|
Terrain terrain = charToTerrain[key]; |
|
|
|
Terrain terrain = Terrain.FromSymbol(key); |
|
|
|
if (terrain != null) { |
|
|
|
var position = new Rectangle(i * TileSize, j * TileSize, TileSize, TileSize); |
|
|
|
tilesList.Add(factory.MakeTile(terrain, position)); |
|
|
|
Tile tile = factory.MakeTile(terrain, position); |
|
|
|
if (tile.Terrain.IsObstacle) { |
|
|
|
tilesList.Add(tile); |
|
|
|
} else { |
|
|
|
decorationsList.Add(tile); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
tiles = tilesList.ToArray(); |
|
|
|
decorations = decorationsList.ToArray(); |
|
|
|
|
|
|
|
// Because we added tiles from left to right, the CollisionTargets are sorted by x-position.
|
|
|
|
// We maintain this invariant so that it's possible to efficiently find CollisionTargets that
|
|
|
@ -176,7 +189,13 @@ namespace SemiColinGames { |
|
|
|
new Vector2(Width + 1, 0), new Vector2(1, float.MaxValue)); |
|
|
|
} |
|
|
|
|
|
|
|
public void Draw(SpriteBatch spriteBatch) { |
|
|
|
public void DrawBackground(SpriteBatch spriteBatch) { |
|
|
|
foreach (Tile t in decorations) { |
|
|
|
t.Draw(spriteBatch); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void DrawForeground(SpriteBatch spriteBatch) { |
|
|
|
foreach (Tile t in tiles) { |
|
|
|
t.Draw(spriteBatch); |
|
|
|
} |
|
|
|