Files
depthsbelow/DepthsBelow/DepthsBelow/Map.cs
T
2012-09-30 00:05:35 +02:00

180 lines
4.1 KiB
C#
Executable File

using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace DepthsBelow
{
public class MapTile
{
public int LocalId;
public Texture2D Texture;
public Rectangle SourceRectangle;
public SpriteEffects SpriteEffects;
}
public enum MapObjectType : byte
{
Plain,
Tile,
Polygon,
Polyline
}
public class MapObject
{
//public MapObjectType ObjectType;
public string Name;
public string Type;
public Rectangle Bounds;
public List<Vector2> Points;
}
public class MapLayer
{
public int Width;
public int Height;
public string Name;
}
public class MapTileLayer : MapLayer
{
public MapTile[] Tiles;
}
public class MapObjectLayer : MapLayer
{
public MapObject[] Objects;
}
public class Map
{
public int TileWidth;
public int TileHeight;
public List<MapLayer> Layers = new List<MapLayer>();
public Map()
{
}
public void Initialize(Core core, Krypton.KryptonEngine kryptonEngine)
{
foreach (var layer in Layers)
{
var objectLayer = layer as MapObjectLayer;
if (objectLayer != null)
{
// Parse objects
foreach (var mapObject in objectLayer.Objects)
{
if (mapObject.Type == "SquadStart")
{
var soldier = new Soldier(core);
// HACK: For some reason, the tile object coordinates are offset by one tile on the Y-axis in the Tiled map file (https://github.com/bjorn/tiled/issues/91)
var mapObjectPos = new Vector2(mapObject.Bounds.X, mapObject.Bounds.Y - Grid.TileSize);
var mapObjectGridPos = Grid.WorldToGrid(mapObjectPos);
soldier.X = mapObjectGridPos.X;
soldier.Y = mapObjectGridPos.Y;
core.Squad.Add(soldier);
}
}
}
var tileLayer = layer as MapTileLayer;
if (tileLayer != null)
{
// Prepare collision hulls for lighting engine
if (tileLayer.Name == "Collision")
{
for (int y = 0; y < tileLayer.Height; y++)
{
for (int x = 0; x < tileLayer.Width; x++)
{
MapTile mapTile = tileLayer.Tiles[y * layer.Width + x];
if (mapTile != null && mapTile.LocalId != 0)
{
var hull = Krypton.ShadowHull.CreateRectangle(new Vector2(TileWidth, TileHeight));
hull.Position.X = x * TileWidth + TileWidth/2;
hull.Position.Y = y * TileHeight + TileWidth / 2;
kryptonEngine.Hulls.Add(hull);
}
}
}
}
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
foreach (var layer in Layers)
{
var tileLayer = layer as MapTileLayer;
if (tileLayer == null)
continue;
// Don't draw the collision layer
if (tileLayer.Name == "Collision")
continue;
for (int y = 0; y < tileLayer.Height; y++)
{
for (int x = 0; x < tileLayer.Width; x++)
{
MapTile mapTile = tileLayer.Tiles[y * layer.Width + x];
if (mapTile != null)
{
spriteBatch.Draw(
mapTile.Texture,
new Rectangle(x * TileWidth, y * TileHeight, TileWidth, TileHeight),
mapTile.SourceRectangle,
Color.White,
0,
Vector2.Zero,
mapTile.SpriteEffects,
0);
}
}
}
}
}
public byte[,] GetCollisionMap()
{
byte[,] collisionMap = null;
foreach (var layer in Layers)
{
var tileLayer = layer as MapTileLayer;
if (tileLayer != null && tileLayer.Name == "Collision")
{
collisionMap = new byte[1024,1024];
for (int y = 0; y < tileLayer.Height; y++)
{
for (int x = 0; x < tileLayer.Width; x++)
{
MapTile tile = tileLayer.Tiles[y * layer.Width + x];
if (tile == null || tile.LocalId == 0)
collisionMap[x, y] = 1;
else
collisionMap[x, y] = 0;
}
}
break;
}
}
if (collisionMap == null)
Debug.WriteLine("Map lacks a Collision layer! Pathfinding won't work.");
return collisionMap;
}
}
}