<ItemGroup>\r
<Compile Include="GameLogic.cs" />\r
<Compile Include="IEntity.cs" />\r
+ <Compile Include="Key.cs" />\r
<Compile Include="Melee.cs" />\r
<Compile Include="Player.cs" />\r
<Compile Include="SaberMonster.cs" />\r
<Compile Include="Properties\AssemblyInfo.cs" />\r
<Compile Include="Program.cs" />\r
<Compile Include="Script.cs" />\r
+ <Compile Include="Tilemap.cs" />\r
<Compile Include="Timer.cs" />\r
<Compile Include="Trigger.cs" />\r
<Compile Include="XnaGame.cs" />\r
[metadata]\r
author = Chaz McGarvey\r
- levelname = Stable\r
+ levelname = The Beginning\r
type = Campaign\r
dimensions = [80,21]\r
- tileset = FuturisticBuilding\r
+ tileset = Warehouse\r
numplayers = <1,4>\r
\r
[M]\r
speed = 10\r
path = [16,8] [20,6] wait(5) [56,9] [71,17] [75,2] [11,13]\r
\r
+[k]\r
+ type = Key\r
+ condition = True()\r
+ event = PickUp()\r
+\r
[T]\r
type = Trigger\r
condition = Print("Trigger tested.") False()\r
\r
[maptable]\r
+------------------------------------------------------------------------------+\r
-|T |\r
-| 1 |\r
-| M |\r
-| 2 +---- |\r
+| |\r
+| 1 2 |\r
+| T |\r
+| 3 4 +---- |\r
| | M |\r
-| 3 | |\r
+| k | |\r
| |------------------------------------------ |\r
-| 4 | | |\r
+| | | |\r
| | | |\r
+-------------+----+ | \ / |\r
| | | \ / |\r
State.mDisplay = new Display(this);\r
State.mDisplay.LoadContent(mContentManager);\r
\r
+ Texture2D mapTiles = mContentManager.Load<Texture2D>("graphics/wallAndFloorTilesNoEdgeScale");\r
+ Tilemap tilemap = new Tilemap(mapTiles, 10, 7);\r
+ tilemap.SetTile(' ', new Point(4, 5));\r
+ tilemap.SetTile('`', new Point(0, 1));\r
+ tilemap.SetTile('~', new Point(1, 1));\r
+ tilemap.SetTile('!', new Point(3, 1));\r
+ tilemap.SetTile('@', new Point(4, 1));\r
+ tilemap.SetTile('#', new Point(5, 1));\r
+ tilemap.SetTile('$', new Point(6, 1));\r
+ tilemap.SetTile('%', new Point(8, 1));\r
+ tilemap.SetTile('^', new Point(9, 1));\r
+ tilemap.SetTile('&', new Point(0, 2));\r
+ tilemap.SetTile('=', new Point(1, 2));\r
+ tilemap.SetTile('*', new Point(2, 2));\r
+ tilemap.SetTile('(', new Point(4, 2));\r
+ tilemap.SetTile(')', new Point(0, 3));\r
+ tilemap.SetTile('_', new Point(2, 3));\r
+ tilemap.SetTile('-', new Point(9, 3));\r
+ tilemap.SetTile(',', new Point(1, 4));\r
+ tilemap.SetTile('+', new Point(2, 4));\r
+ tilemap.SetTile('[', new Point(3, 4));\r
+ tilemap.SetTile(']', new Point(4, 4));\r
+ tilemap.SetTile('{', new Point(5, 4));\r
+ tilemap.SetTile('}', new Point(6, 4));\r
+ tilemap.SetTile('\\', new Point(8, 4));\r
+ tilemap.SetTile('|', new Point(9, 4));\r
+ tilemap.SetTile(';', new Point(0, 5));\r
+ tilemap.SetTile(':', new Point(1, 5));\r
+ tilemap.SetTile('\'', new Point(2, 5));\r
+ tilemap.SetTile('"', new Point(3, 5));\r
+ tilemap.SetTile('.', new Point(5, 5));\r
+ tilemap.SetTile('<', new Point(6, 5));\r
+ tilemap.SetTile('>', new Point(7, 5));\r
+ tilemap.SetTile('/', new Point(8, 5));\r
+ tilemap.SetTile('?', new Point(9, 5));\r
+\r
State.Map = mContentManager.Load<Map>("Maps/level1");\r
+ State.Map.Tilemap = tilemap;\r
State.Entities = State.Map.GetAllEntities(this);\r
- Map.DefaultTile = mContentManager.Load<Texture2D>("default");\r
\r
/*\r
mPlayers.Clear();\r
--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using Microsoft.Xna.Framework;\r
+using Microsoft.Xna.Framework.Content;\r
+using Microsoft.Xna.Framework.Graphics;\r
+\r
+namespace CarFire\r
+{\r
+ /// <summary>\r
+ /// A key entity. Keys can be used to unlock doors... what a surprise.\r
+ /// </summary>\r
+ public class Key : Trigger\r
+ {\r
+ #region Public Methods\r
+\r
+ /// <summary>\r
+ /// Construct a key entity.\r
+ /// </summary>\r
+ /// <param name="identifier">The entity identifier.</param>\r
+ /// <param name="position">The position.</param>\r
+ /// <param name="info">The key-value pairs.</param>\r
+ /// <param name="game">The game reference.</param>\r
+ public Key(char identifier, Point position, Dictionary<string, string> info, Game game) :\r
+ base(identifier, position, info, game)\r
+ {\r
+ mPosition = new Vector2(position.X, position.Y);\r
+ mGame = game;\r
+ }\r
+\r
+ public override void LoadContent(ContentManager contentManager)\r
+ {\r
+ mTexture = contentManager.Load<Texture2D>("default");\r
+ }\r
+\r
+ public override void Draw(SpriteBatch spriteBatch)\r
+ {\r
+ Rectangle position = mGame.State.Map.GetRectangleFromCoordinates(mPosition);\r
+ spriteBatch.Draw(mTexture, position, Color.White);\r
+ }\r
+\r
+ #endregion\r
+\r
+\r
+ #region Private Variables\r
+\r
+ Texture2D mTexture;\r
+ Game mGame;\r
+ Vector2 mPosition;\r
+\r
+ #endregion\r
+ }\r
+}\r
/// </summary>\r
public class Map\r
{\r
- // DEBUG: Tilesets not implemented at all.\r
- public static Texture2D DefaultTile;\r
-\r
-\r
#region Public Constants\r
\r
public const float PixelsToUnitSquares = 64.0f;\r
/// </summary>\r
public int Height { get { return mData.Metadata.GridHeight; } }\r
\r
- // TODO: This should return whatever object we end up using for tilesets.\r
+ /// <summary>\r
+ /// Get the name of the tileset.\r
+ /// </summary>\r
public string Tileset { get { return mData.Metadata.Tileset; } }\r
\r
/// <summary>\r
set { mView.CenterCell = value; }\r
}\r
\r
+ /// <summary>\r
+ /// Get and set the tilemap with its associated texture and tile\r
+ /// character to coordinate mappings. This effects what the map looks\r
+ /// like when it is drawn.\r
+ /// </summary>\r
+ public Tilemap Tilemap\r
+ {\r
+ get { return mView.Tilemap; }\r
+ set { mView.Tilemap = value; }\r
+ }\r
+\r
/// <summary>\r
/// Get and set the zoom of the map view. The default zoom is\r
/// Map.PixelsToUnitSquares.\r
}\r
}\r
\r
+ public char GetCell(int x, int y)\r
+ {\r
+ if (IsOnMap(x, y)) return mGrid[x, y];\r
+ return mDefaultTile;\r
+ }\r
+\r
public void ClearCell(int x, int y)\r
{\r
SetCell(x, y, mDefaultTile);\r
class View\r
{\r
public Vector2 CenterCell;\r
+ public Tilemap Tilemap;\r
public float Zoom;\r
\r
\r
\r
public void Draw(SpriteBatch spriteBatch)\r
{\r
+ if (Tilemap == null) throw new Exception("Cannot draw map without first setting the tilemap.");\r
mViewport = spriteBatch.GraphicsDevice.Viewport;\r
\r
- // TODO: There is no culling yet, but it runs so fast that it probably won't ever need it.\r
for (int y = 0; y < mData.Metadata.GridHeight; y++)\r
{\r
for (int x = 0; x < mData.Metadata.GridWidth; x++)\r
{\r
- if (mData.IsCellOpen(x, y))\r
- {\r
- spriteBatch.Draw(Map.DefaultTile, GetRectangleFromCoordinates(x, y), Color.White);\r
- }\r
- else\r
- {\r
- spriteBatch.Draw(Map.DefaultTile, GetRectangleFromCoordinates(x, y), Color.DarkBlue);\r
- }\r
+ Tilemap.Draw(spriteBatch, mData.GetCell(x, y), GetRectangleFromCoordinates(x, y));\r
}\r
}\r
}\r
int coolDown;\r
Texture2D charModel;\r
Texture2D projectileModel;\r
+ int velocityX;\r
+ int velocityY;\r
#endregion \r
\r
#region Public Methods\r
\r
namespace CarFire\r
{\r
+ /// <summary>\r
+ /// The Script class handles the parsing and execution of lists\r
+ /// of functions. Scripts are closely related to triggers.\r
+ /// </summary>\r
public class Script\r
{\r
#region Public Properties\r
\r
+ /// <summary>\r
+ /// Determine if the script is in the process of being run.\r
+ /// </summary>\r
public bool IsRunning { get { return mIsRunning; } }\r
\r
#endregion\r
\r
#region Public Methods\r
\r
+ /// <summary>\r
+ /// Construct a script object with code and a game reference.\r
+ /// </summary>\r
+ /// <param name="code">The script code.</param>\r
+ /// <param name="game">A game reference.</param>\r
public Script(string code, Game game)\r
{\r
- mGame = game;\r
+ mImpl = new Impl(game);\r
\r
string[] functions = Parse.List(code);\r
if (functions != null)\r
else throw new Exception("Script could not be parsed: " + code);\r
}\r
\r
+ /// <summary>\r
+ /// Start execution of the script. If there is no need to break\r
+ /// execution before the script ends, it will finish before this method\r
+ /// call ends. Otherwise, execution will be delayed and will finish sometime\r
+ /// in the future. This will execute each function in sequence as long\r
+ /// as each function evaluates to true. If a function does not evaluate to true,\r
+ /// this method will return and execution will be delayed. In either case,\r
+ /// the evaluation of the last function is returned by this method.\r
+ /// </summary>\r
+ /// <param name="player">The player associated with this script.</param>\r
+ /// <returns>Evaluation of the last function call.</returns>\r
public bool Run(Player player)\r
{\r
bool result = false;\r
\r
#region Private Methods\r
\r
+ /// <summary>\r
+ /// Call a function in the last at a certain index.\r
+ /// </summary>\r
+ /// <param name="index">The function index.</param>\r
+ /// <param name="player">The associated player object.</param>\r
+ /// <returns>The evaluation of the function.</returns>\r
bool Call(int index, Player player)\r
{\r
Debug.Assert(0 <= index && index < mFunctions.Count);\r
}\r
return true;\r
}\r
+\r
+\r
+ public Impl(Game game)\r
+ {\r
+ mGame = game;\r
+ }\r
+\r
+ Game mGame;\r
}\r
\r
class Function\r
\r
#region Private Variables\r
\r
- Game mGame;\r
+ Impl mImpl;\r
List<Function> mFunctions = new List<Function>();\r
bool mIsRunning;\r
int mRunningIndex;\r
- Impl mImpl = new Impl();\r
\r
#endregion\r
}\r
--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using System.Diagnostics;\r
+using Microsoft.Xna.Framework;\r
+using Microsoft.Xna.Framework.Content;\r
+using Microsoft.Xna.Framework.Graphics;\r
+namespace CarFire\r
+{\r
+ /// <summary>\r
+ /// Small wrapper around a texture to provide easy access to\r
+ /// tile rectangles.\r
+ /// </summary>\r
+ public class Tilemap\r
+ {\r
+ #region Public Properties\r
+\r
+ /// <summary>\r
+ /// Get the texture for this tilemap.\r
+ /// </summary>\r
+ public Texture2D Texture { get { return mTexture; } }\r
+\r
+ #endregion\r
+\r
+\r
+ #region Public Methods\r
+\r
+ /// <summary>\r
+ /// Construct a tilemap with a texture and dimensions in\r
+ /// tiles.\r
+ /// </summary>\r
+ /// <param name="texture">The texture.</param>\r
+ /// <param name="width">Number of tiles across.</param>\r
+ /// <param name="height">Number of tiles down.</param>\r
+ public Tilemap(Texture2D texture, int width, int height)\r
+ {\r
+ mTexture = texture;\r
+ mWidth = width;\r
+ mHeight = height;\r
+ mTileW = mTexture.Width / mWidth;\r
+ mTileH = mTexture.Height / mHeight;\r
+ }\r
+\r
+\r
+ /// <summary>\r
+ /// Get a tile rectangle from a tile coordinate.\r
+ /// </summary>\r
+ /// <param name="point">Tile coordinates; [0,0] being the\r
+ /// top-left tile.</param>\r
+ /// <returns>Rectangle surrounding the tile.</returns>\r
+ public Rectangle GetRectangleForTile(Point point)\r
+ {\r
+ return GetRectangleForTile(point.X, point.Y);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Get a tile rectangle from a tile coordinate\r
+ /// </summary>\r
+ /// <param name="x">X-coordinate.</param>\r
+ /// <param name="y">Y-coordinate.</param>\r
+ /// <returns>Rectangle surrounding the tile.</returns>\r
+ public Rectangle GetRectangleForTile(int x, int y)\r
+ {\r
+ Debug.Assert(0 <= x && x < mWidth && 0 <= y && y < mHeight);\r
+ return new Rectangle(x * mTileW, y * mTileH, mTileW, mTileH);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Get a tile rectangle from a tile character.\r
+ /// </summary>\r
+ /// <param name="tile">Tile character.</param>\r
+ /// <returns>Rectangle surrounding the tile.</returns>\r
+ public Rectangle GetRectangleForTile(char tile)\r
+ {\r
+ return mTiles[tile];\r
+ }\r
+\r
+\r
+ /// <summary>\r
+ /// Associate a tile character with tile coordinates. This\r
+ /// lets you access tile rectangles by character.\r
+ /// </summary>\r
+ /// <param name="tile">Tile character.</param>\r
+ /// <param name="point">Coordinates.</param>\r
+ public void SetTile(char tile, Point point)\r
+ {\r
+ mTiles.Add(tile, GetRectangleForTile(point));\r
+ }\r
+\r
+\r
+ /// <summary>\r
+ /// Draw a tile to the screen.\r
+ /// </summary>\r
+ /// <param name="spriteBatch">The b2bomber.</param>\r
+ /// <param name="tile">The tile.</param>\r
+ /// <param name="screenRect">The screen rectangle to draw at.</param>\r
+ public void Draw(SpriteBatch spriteBatch, char tile, Rectangle screenRect)\r
+ {\r
+ spriteBatch.Draw(mTexture, screenRect, GetRectangleForTile(tile), Color.White);\r
+ }\r
+\r
+ #endregion\r
+\r
+\r
+ #region Private Variables\r
+\r
+ Texture2D mTexture;\r
+ int mWidth;\r
+ int mHeight;\r
+ int mTileW;\r
+ int mTileH;\r
+ Dictionary<char, Rectangle> mTiles = new Dictionary<char, Rectangle>();\r
+\r
+ #endregion\r
+ }\r
+}\r
{\r
#region Public Methods\r
\r
+ /// <summary>\r
+ /// Construct a trigger entity.\r
+ /// </summary>\r
+ /// <param name="identifier">The entity identifier.</param>\r
+ /// <param name="position">The position.</param>\r
+ /// <param name="info">The key-value pairs.</param>\r
+ /// <param name="game">The game reference.</param>\r
public Trigger(char identifier, Point position, Dictionary<string, string> info, Game game)\r
{\r
mGame = game;\r
else throw new Exception("Triggers must define an event script.");\r
}\r
\r
- public void Update(TimeSpan timeSpan)\r
+ /// <summary>\r
+ /// Check the trigger condition and execute the event if the\r
+ /// condition evaluates to true.\r
+ /// </summary>\r
+ public void Call()\r
{\r
Player player = mGame.GetPlayerAtCoordinates(mCoordinates);\r
if (player != null)\r
}\r
}\r
\r
- public void LoadContent(ContentManager contentManager)\r
+\r
+ /// <summary>\r
+ /// Calls the trigger.\r
+ /// </summary>\r
+ /// <param name="timeSpan">Unused.</param>\r
+ public virtual void Update(TimeSpan timeSpan)\r
+ {\r
+ Call();\r
+ }\r
+\r
+ public virtual void LoadContent(ContentManager contentManager)\r
{\r
// No implementation needed.\r
}\r
\r
- public void Draw(SpriteBatch spriteBatch)\r
+ public virtual void Draw(SpriteBatch spriteBatch)\r
{\r
// No implementation needed.\r
}\r