March 6th, 2010 | 17 comments

There are times when making a game that you absolutely can’t be lazy. You need to focus and get things done if you ever want to ship. But there are times when being lazy is the best way to solve a problem. Today was one of those times for me.

I’ve started working on a new ninja game that was going to use largely tile based maps. I first started down the same road of Pixel Man, using Paint.NET for my level editor. I quickly realized that the increased complexity meant a confusing palette which made life too hard. It also ruled out things like cutscenes or any other interesting level markers. So I started working on my own editor. My method for resizing 2D arrays was so I could support the editor as I went. I never got very far into making an editor because, frankly, it’s a lot of work.

So I started feeling burnt out. I want to make this game but I was stuck from the get-go without having any means to create my levels. I could have gone ahead and hard coded a few maps but I find that’s not a workflow I tend to like. I prefer to solve the content problem first that way I know what data I will be able to code around. Today I came up with a solution for all of this. I would simply be lazy and find a tile editor someone else had made, thus saving me time.

During some random searches, I found a nice tile editor called Tiled. Tiled is a near perfect editor for tile maps. You can attach metadata to pretty much everything and you can make layers that just hold arbitrary rectangles of metadata. It’s really quite nice. Here’s one of my test levels in Tiled:

Test Level in Tiled

You can see I dedicated a rectangle for a spawn point and two for cutscenes which I could use to display some text about the game or whatever (this is a test level so none of those really mean anything).

So this editor is great. It does pretty much everything I need out of an editor, but how can I use the levels? Thankfully all levels are saved as XML files which means it’s not a whole lot of work to parse them and use them. Since I was on a streak of using other people’s work, I went out in search of XNA GS code to use the level files.

My search started at the Tiled wiki which lead me to Kevin Gadd’s excellent website which pointed me to Stephen Belanger’s blog post expanding on Kevin’s code. I took a look at the code in excitement and was a bit let down. All of the XML parsing was done at runtime into very mutable objects with some design choices I didn’t quite agree with. So I decided that this is something to take into my own hands.

Starting at around 7:30 this morning (and ending just a few minutes ago), I feverishly wrote up a custom content pipeline extension project for parsing and processing the TMX files produced by Tiled and turning them into an easy to use, largely immutable structure. Why immutable? I’m personally a fan of closed systems until you need them open. Why would you make the width of the map mutable? What happens if I accidentally change that? So in my code, most variables are read only to stop me from shooting myself in the foot. Using C#’s ‘internal’ keyword, I’ve made it so most objects are only internally constructable with a lot of private members. This keeps all the data out of the hands of those meddling games (or people like me who accidentally change something and break it all).

The extensions are nice and minimal in what they require of you. Just drop a TMX file into your content project and you’re basically done. You will also need any tile sheets used by the map. You can place them anywhere in the content folder directory and you don’t need to add them to the content project; the map will build anything it needs and it also handles loading those in for you. The only parameter on the TMX processor is the directory where those sheets can be found, relative to the content project. In my project, I have a Maps directory in my content library with my TMX file and then a TileSets directory next to that with the sheets. Therefore my TMX files need to set their TileSet Directory values to “TileSets”.

Since I spent a good five hours creating this (which is likely orders of magnitude less than it would take for me to write something on par with Tiled), I decided to share with the community. I’m sure there are others out there who would want to use Tiled for their level editor and now you can have a great base on which to build up your own library for using those maps. The code is all MS-Pl so feel free to do with it what you will. I, of course, take no responsibility if the code manifests itself into the end of the world, a black hole, or your ex-girlfriend so use at your own risk. However I’ve yet to see any of those three things, so I think we’re good.

Enough blabbing. Links:

License
Libraries and Demo Project


Possibly Related Posts

(Automatically Generated)
Code Mashing
Pixel Man Post Mortem #2
Existence Progress
Pixel Man Post Mortem #3

March 5th, 2010 | 0 comments

In my last post, I showed an extension method for resizing arrays. Today I decided to come up with some more extension methods that I find handy. First up: Fill.

Fill is an extension method I wrote because I’m sick of iterating over arrays to fill them in or alter values. Fill looks like this:

public static void Fill<T>(this T[,] array, Func<int, int, T, T> fill)
{
	int width = array.GetLength(0);
	int height = array.GetLength(1);

	for (int x = 0; x < width; x++)
	{
		for (int y = 0; y < height; y++)
		{
			array[x, y] = fill(x, y, array[x, y]);
		}
	}
}

You can see that it uses a Func to generate the new values. The Func takes in the x and y indices as well as the existing value at that location in the array, then returns the new value. This can be useful for a number of things. Let’s say I have an array of objects and I just used my Resize method to expand the array. I now have a bunch of null objects in there. I can easily use Fill to fix this:

myArray.Fill((x, y, existing) => existing ?? new MyObject());

How’s that for succinct? It’s also useful for new arrays that you want to populate:

int[,] myArray = new int[10, 10];
myArray.Fill((x, y, existing) => x * y);

So you can easily ignore the existing value and simply return a value to replace the current one.

I have a blast making extension methods even if they aren’t revolutionizing how I write code. I find it gives me a chance to just think up a problem and try to solve it in a clean and simple way. Anyone else find themselves doing this? What extension methods are you writing?


Possibly Related Posts

(Automatically Generated)
Resizing 2D arrays
Extension Methods and You
Extending GamePadState
Spice up your PC input with extension methods
How Not To Write A Game – Everything Changes

March 2nd, 2010 | 0 comments

I started working on a new tile system and editor for my ninja game and realized I’m going to want the ability to change level sizes. I store my tile layouts in a basic 2D array which means that my resizing will have to do a bit of moving things around. After a little bit of work, I came up with a fairly decent (i.e. it works for my few little test cases) extension method for resizing any 2D array, including choosing where you clamp to get the same effect as Paint.NET or Photoshop when you change canvas size but get to choose where the existing data will be in relationship to the resizing.

Paint.NET Anchor Selection

Anyway, here’s the method. Hope this can save someone else some time. Also if you spot anything wrong about this let me know.

public enum HorizontalClamp
{
	Left,
	Right,
	Center
}

public enum VerticalClamp
{
	Top,
	Bottom,
	Center
}

public static class ArrayExtensions
{
	public static T[,] Resize<T>(
		this T[,] array,
		int newWidth,
		int newHeight,
		HorizontalClamp xClamp,
		VerticalClamp yClamp)
	{
		// get the current width and height of the array
		int width = array.GetLength(0);
		int height = array.GetLength(1);

		// start/end from the old array
		int xStart = 0, xEnd = Math.Min(width, newWidth);
		int yStart = 0, yEnd = Math.Min(height, newHeight);

		// start/end for new array
		int targetX = 0;
		int targetY = 0;

		// figure out start, end, and target coordinates.
		// no check for left or top; those are defaults.

		if (xClamp == HorizontalClamp.Right)
		{
			xStart = Math.Max(width - newWidth, 0);
			xEnd = xStart + Math.Min(width, newWidth);
			targetX = newWidth - (width - xStart);
		}
		else if (xClamp == HorizontalClamp.Center)
		{
			xStart = Math.Max(width / 2 - newWidth / 2, 0);
			xEnd = xStart + Math.Min(width, newWidth);
			targetX = Math.Max(newWidth / 2 - width / 2, 0);
		}

		if (yClamp == VerticalClamp.Bottom)
		{
			yStart = Math.Max(height - newHeight, 0);
			yEnd = yStart + Math.Min(height, newHeight);
			targetY = newHeight - (height - yStart);
		}
		else if (yClamp == VerticalClamp.Center)
		{
			yStart = Math.Max(height / 2 - newHeight / 2, 0);
			yEnd = xStart + Math.Min(height, newHeight);
			targetY = Math.Max(newHeight / 2 - height / 2, 0);
		}

		// create our return value
		T[,] newArray = new T[newWidth, newHeight];

		// copy over the values from the old array to the new array
		for (int x1 = targetX, x2 = xStart; x2 < xEnd; x1++, x2++)
		{
			for (int y1 = targetY, y2 = yStart; y2 < yEnd; y1++, y2++)
			{
				newArray[x1, y1] = array[x2, y2];
			}
		}

		return newArray;
	}
}

Possibly Related Posts

(Automatically Generated)
Further extending C# arrays
Shader Toy – Parameters and Annotations
How Not To Write A Game – Everything Changes
How Not To Write A Game – The Reports of the Xbox 360 GC Are Greatly Exaggerated
Bloc on the Market

February 28th, 2010 | 0 comments

Well that didn’t take long. :)

I’ve already updated my MP3 plugin to use a new Silverlight player. I found a pretty nice one on CodePlex that I went ahead and modified a bit. First I took in parameters for the URL and title from the HTML rather than hardcoding (so I can reuse a single XAP for all my media needs). Then I got rid of the opening and closing animation when you hit play and pause and simplified it so that it animates open and stays there. I also tweaked the display a bit to never say “Buffering…” because that annoyed me.

Once I did all that, I was left with this nice XAP which I’m sharing with you. Feel free to upload it to your server and use it to play your MP3s.

So when I went and updated my plugin, I needed to change the output quite a bit. Here’s what the new code looks like:

add_filter('the_content', 'insert_audio');

function insert_audio($content)
{
  $pattern = '/\[audio:(.+?)\](.+?)\[\/audio\]/i';
  $replacement =
    '<center><object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="260" height="25">
    <param name="source" value="/silverlight/Mp3Player.xap"/>
    <param name="background" value="white" />
    <param name="minRuntimeVersion" value="3.0.40818.0" />
    <param name="autoUpgrade" value="true" />
    <param name="InitParams" value="url=http://blog.nickgravelyn.com/music/$1,name=$2" />
    <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=3.0.40818.0" style="text-decoration:none">
    <img src="http://go.microsoft.com/fwlink/?LinkId=108181" alt="Get Microsoft Silverlight" style="border-style:none"/>
    </a>
    </object>
    <p><a href="http://blog.nickgravelyn.com/music/$1">Download $2</a></p></center>';

  return preg_replace($pattern, $replacement, $content);
}

Isn’t that something? Most of it is just standard for embedding Silverlight, but you can see I centered it, added a download link, and then we use the InitParams parameter to pass in our values. Also of note is that I modified my expectation of the url parameter to be a single filename which my plugin assumes to be in my music folder. You’ll want to change that if you use the plugin.

Anyway, this took me about an hour to do which goes to show how quickly you can find and leverage existing code to make something you like. That and Silverlight is pretty awesome for using C#. :D


Possibly Related Posts

(Automatically Generated)
Extending Wordpress for audio tags
Making noise
OpenID Support
Indexing Xbox LIVE Community Games
Spaceships galore

February 28th, 2010 | 0 comments

Since I’m hoping to do more music, I decided to make myself a nice plugin for my audio embedding/linking. Partly because I can type less in each post, but also so I can change that plugin and know that every post with embedded audio will update to look and act the same. So if I don’t like the current player, I can change to something else and every instance is updated in one go.

So for my audio, I decided to make life easy. Just put something like this:

[ audio:/path/to/file.mp3 ]Name Of Song[ /audio ]
(without the spaces in the audio tags)

And it converts that to the following HTML5 code:

<p><audio src="/path/to/file.mp3" controls="controls"></audio></p>
<p><a href="/path/to/file.mp3">Name Of Song</a></p>

At least for now, that is. I like the Chrome HTML5 audio player a lot and decided to go with it. I tried a Flash based player but it crashed IE for some reason. IE doesn’t support the audio tag yet and Firefox only supports OGG and WAV, so this isn’t probably the “best” approach, but since I also link the MP3 directly, those users still have a way to listen to it while the rest of us can use Chrome and see an awesome inline audio player.

Anyway, with that introduction out of the way, here’s the entire source to my plugin to not only let you use it, but show how easy it can be to do some quick and dirty regex replacements as a Wordpress plugin, allowing you to make more interesting plugins for your own site:

add_filter('the_content', 'insert_audio');

function insert_audio($content)
{
  $pattern = '/\[audio:(.+?)\](.+?)\[\/audio\]/i';
  $replacement = '<p><audio src="$1" controls="controls"></audio></p><p><a href="$1">$2</a></p>';

  return preg_replace($pattern, $replacement, $content);
}

Yep, that’s it. My file technically has a bunch of the standard comment stuff in it, but I didn’t want to paste that all in here.

Hopefully this helps someone out there; I know I like having these plugins to make life easy as well as allowing me to format all posts retroactively at any point with one edit. Do you have any cool plugins on your Wordpress that you’ve found or written? I’m always up for more plugins. :)


Possibly Related Posts

(Automatically Generated)
Playing MP3s with Silverlight
Paint.NET plugin for premultiplied alpha
Paint.NET animation strip plugin
Making noise
New syntax highlighter

February 27th, 2010 | 2 comments

Today I decided to try out the demo of ACID Music Studio since I really want to get back into making music. I miss GarageBand, but given that I don’t have a Mac, that’s not really an option. Thankfully ACID seems to not be much harder to learn and seems to be an overall superior product. After an hour or two of plinking in notes with their on-screen MIDI tools, I came up with my first ACID produced music track:

Get Microsoft Silverlight

Download Actiony

It’s not much (and not terribly good), but it’s something. Now that I have this software, I guess I have an excuse to go buy one of those nice digital pianos so I can make some music that isn’t awful. :)


Possibly Related Posts

(Automatically Generated)
Existence Progress
Sammy the Snake: Making a Zune Game
Playing MP3s with Silverlight

February 27th, 2010 | 1 comment

Today I checked in the first update to Sprite Sheet Packer in a few months. Inspired by a discussion post I somehow didn’t see for a few months and my own realization of the usefulness, I extracted the build process of the tool into a command line application and made the UI tool simply a wrapper around it. This enables many more scenarios for integration.

First let’s do the techie thing and just look at the arguments of the tool:

C:\Users\Nick\Desktop>sspack
Missing required argument '/image'.
Missing required argument '/map'.
/image:<string>  Output file name for the image.
/map:<string>    Output file name for the map.
/mw:<int>        Maximum ouput width. Default:'4096'
/mh:<int>        Maximum ouput height. Default:'4096'
/pad:<int>       Padding between images. Default:'1'
/pow2            Ensures output dimensions are powers of two.
/sqr             Ensures output is square.
/r               Searches subdirectories of any input directories.
/il:<string>     Path(s) to file(s) listing the images to build.
<input>          Images to pack.

Those first two lines are unfortunately a bit misleading but the library I used for parsing command line arguments didn’t have complex logic. You technically are required to have image and map but you also must have something for either il or the input images. Most of the arguments make sense but the last few may trip people up. First the /r. If you have that flag, your searches for input will be recursive. So you could invoke this:

sspack /image:test.png /map:test.txt C:\Users\Nick\Desktop\MyImages\*.png

And it would find all PNG images in the MyImages folder. Note that the wildcard is really primitive and likely to break if you try to do anything with it in the middle of the word; it’s mainly there for finding a bunch of images in one folder. Anyway, if you were to add in the /r flag, it would find any PNG image in the MyImages folder and any subdirectories. That’s it.

Next the il flag. Since you may want to pack lots and lots of images (like the tool requires), you can make a file like this:

C:\Users\Nick\Desktop\MyImages\1.png
C:\Users\Nick\Desktop\MyImages\2.png
C:\Users\Nick\Desktop\MyImages\3.png
C:\Users\Nick\Desktop\MyImages\4.png

And invoke sspack with that file which it uses to find the files:

sspack /image:test.png /map:test.txt C:\Users\Nick\Desktop\ImagesToPack.txt

This is really nice because you could make any other tool to generate that file and kick off the build. This is actually all that the UI tool does. It simply builds up that list (which it saves in %AppData%\Sprite Sheet Packer) and uses all the UI to simply build up the command to launch a Process to run sspack. Now you can make your own UI tool or integrate sprite sheet packing into your build.

If you have any suggestions, feel free to let me know, but no promises. As you can see, I don’t really do rapid development on this project. Also feel free to submit patches on CodePlex if you have fixes for bugs or enhancements. That really helps since I can do a quick code review and put it up for everyone else to use.


Possibly Related Posts

(Automatically Generated)
Sprite Sheet Packer Tool
Expanding animated Gif images
Sprite Sheet Packer Tool – XNA GS Example
Creating Your Own XNB Files
Visual Studio 2010, XNA, and you

February 27th, 2010 | 1 comment

A number of the built in types you load through ContentManager in XNA have a Name property. Most (all?) don’t actually set this at any point; it’s just there for you to use. I like to use these names for various things and I’m sick of setting them all manually. So I started out to make my own ContentManager that does this for me.

It started off with something like this:

public class MyContentManager : ContentManager
{
	public MyContentManager(IServiceProvider services)
		: base(services, "Content")
	{
	}

	public override T Load<T>(string assetName)
	{
		T content = base.Load<T>(assetName);

		if (content is GraphicsResource)
		{
			(content as GraphicsResource).Name = assetName;
		}
		else if (content is SoundEffect)
		{
			(content as SoundEffect).Name = assetName;
		}

		return content;
	}
}

And that works. But what if I miss some content? What if I add my own custom type with a Name property? On my second go I decided to use a reflection based approach by just seeing if the object has a settable Name property:

public class MyContentManager : ContentManager
{
	public MyContentManager(IServiceProvider services)
		: base(services, "Content")
	{
	}

	public override T Load<T>(string assetName)
	{
		T content = base.Load<T>(assetName);

		PropertyInfo nameProperty = typeof(T).GetProperty("Name", typeof(string));
		if (nameProperty != null && nameProperty.CanWrite)
		{
			nameProperty.SetValue(content, assetName, null);
		}

		return content;
	}
}

And now any content that I load that has a Name property with a setter will get its name set. But I’m not quite done yet. Reflection isn’t the quickest thing in the world and I do like to use the ContentManager as a cache. This implementation will set the Name property each time the content is pulled from the ContentManager. While this is a good thing if you plan to change the name other places, it can be a performance hit. So I decided to add a dictionary to track what content has already been named and avoid naming things twice:

public class MyContentManager : ContentManager
{
	private readonly Dictionary<string, bool> namedContent = new Dictionary<string, bool>();

	public MyContentManager(IServiceProvider services)
		: base(services, "Content")
	{
	}

	public override T Load<T>(string assetName)
	{
		T content = base.Load<T>(assetName);

		bool named = false;
		if (!namedContent.TryGetValue(assetName, out named) || !named)
		{
			PropertyInfo nameProperty = typeof(T).GetProperty("Name", typeof(string));
			if (nameProperty != null && nameProperty.CanWrite)
			{
				nameProperty.SetValue(content, assetName, null);
			}
			namedContent.Add(assetName, true);
		}

		return content;
	}
}

And that’s where I’m at now. I fully realize that reflection is not going to be as fast as doing those casts, but since I’m also doing this caching of what items have been named, I’m only going to see that performance hit the first time I load an object and generally loading the object takes enough time that the extra cost of the reflection isn’t likely to be noticeable or an issue.

I’d be interested in hearing what others are doing to extend this class. Anyone else using a custom ContentManager for anything?


Possibly Related Posts

(Automatically Generated)
IDictionary + XmlSerializer = Epic FAIL
Exception handling and GamerServicesComponent
Generic UI for parameter editing
My Singleton Base Class
XmlSerializer Misconceptions Part 1