<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Nick Gravelyn</title>
	<atom:link href="http://blog.nickgravelyn.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.nickgravelyn.com</link>
	<description></description>
	<lastBuildDate>Sat, 06 Mar 2010 21:04:11 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Know when to be lazy</title>
		<link>http://blog.nickgravelyn.com/2010/03/know-when-to-be-lazy/</link>
		<comments>http://blog.nickgravelyn.com/2010/03/know-when-to-be-lazy/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 21:04:11 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.nickgravelyn.com/?p=1511</guid>
		<description><![CDATA[There are times when making a game that you absolutely can&#8217;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&#8217;ve started working on a new [...]]]></description>
			<content:encoded><![CDATA[<p>There are times when making a game that you absolutely can&#8217;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.</p>
<p>I&#8217;ve started working on a new ninja game that was going to use largely tile based maps. I first started down the <a href="/2009/09/pixel-man-post-mortem-2/">same road</a> 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 <a href="/2010/03/resizing-2d-arrays/">resizing 2D arrays</a> was so I could support the editor as I went. I never got very far into making an editor because, frankly, it&#8217;s a lot of work.</p>
<p>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&#8217;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.</p>
<p>During some random searches, I found a nice tile editor called <a href="http://mapeditor.org/">Tiled</a>. 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&#8217;s really quite nice. Here&#8217;s one of my test levels in Tiled:</p>
<p><center><a href="/wp-content/uploads/2010/03/demolevel.png"><img src="http://blog.nickgravelyn.com/wp-content/uploads/2010/03/demolevel-300x164.png" alt="Test Level in Tiled" title="Test Level in Tiled" width="300" height="164" class="alignnone size-medium wp-image-1512" /></a></center></p>
<p>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).</p>
<p>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&#8217;s not a whole lot of work to parse them and use them.  Since I was on a streak of using other people&#8217;s work, I went out in search of XNA GS code to use the level files.</p>
<p>My search started at the <a href="http://sourceforge.net/apps/mediawiki/tiled/index.php?title=Main_Page">Tiled wiki</a> which lead me to Kevin Gadd&#8217;s <a href="http://www.luminance.org/code/2009/06/17/tiled-map-loader-for-xna">excellent website</a> which pointed me to Stephen Belanger&#8217;s <a href="http://www.stephenbelanger.com/2009/07/14/tiled-maps-for-xna-full-support-for-the-tiled-map-xml-specification/">blog post</a> expanding on Kevin&#8217;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&#8217;t quite agree with. So I decided that this is something to take into my own hands.</p>
<p>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&#8217;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#&#8217;s &#8216;internal&#8217; keyword, I&#8217;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).</p>
<p>The extensions are nice and minimal in what they require of you. Just drop a TMX file into your content project and you&#8217;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&#8217;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 &#8220;TileSets&#8221;.</p>
<p>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&#8217;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&#8217;ve yet to see any of those three things, so I think we&#8217;re good.</p>
<p>Enough blabbing. Links:</p>
<p><a href="http://opensource.org/licenses/ms-pl.html">License</a><br />
<a href='http://blog.nickgravelyn.com/wp-content/uploads/2010/03/TiledDemo.zip'>Libraries and Demo Project</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nickgravelyn.com/2010/03/know-when-to-be-lazy/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Further extending C# arrays</title>
		<link>http://blog.nickgravelyn.com/2010/03/further-extending-c-arrays/</link>
		<comments>http://blog.nickgravelyn.com/2010/03/further-extending-c-arrays/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 00:44:33 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.nickgravelyn.com/?p=1508</guid>
		<description><![CDATA[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&#8217;m sick of iterating over arrays to fill them in or alter values. Fill looks like this:
public static [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="/2010/03/resizing-2d-arrays/">last post</a>, 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.</p>
<p>Fill is an extension method I wrote because I&#8217;m sick of iterating over arrays to fill them in or alter values. Fill looks like this:</p>
<pre class="brush: csharp;">public static void Fill&lt;T&gt;(this T[,] array, Func&lt;int, int, T, T&gt; fill)
{
	int width = array.GetLength(0);
	int height = array.GetLength(1);

	for (int x = 0; x &lt; width; x++)
	{
		for (int y = 0; y &lt; height; y++)
		{
			array[x, y] = fill(x, y, array[x, y]);
		}
	}
}</pre>
<p>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&#8217;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:</p>
<pre class="brush: csharp;">myArray.Fill((x, y, existing) =&gt; existing ?? new MyObject());</pre>
<p>How&#8217;s that for succinct? It&#8217;s also useful for new arrays that you want to populate:</p>
<pre class="brush: csharp;">int[,] myArray = new int[10, 10];
myArray.Fill((x, y, existing) =&gt; x * y);</pre>
<p>So you can easily ignore the existing value and simply return a value to replace the current one.</p>
<p>I have a blast making extension methods even if they aren&#8217;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?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nickgravelyn.com/2010/03/further-extending-c-arrays/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Resizing 2D arrays</title>
		<link>http://blog.nickgravelyn.com/2010/03/resizing-2d-arrays/</link>
		<comments>http://blog.nickgravelyn.com/2010/03/resizing-2d-arrays/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 15:39:56 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.nickgravelyn.com/?p=1497</guid>
		<description><![CDATA[I started working on a new tile system and editor for my ninja game and realized I&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>I started working on a new tile system and editor for my ninja game and realized I&#8217;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.</p>
<p><center><img src="http://blog.nickgravelyn.com/wp-content/uploads/2010/03/anchor.png" alt="Paint.NET Anchor Selection" title="Paint.NET Anchor Selection" width="378" height="541" class="alignnone size-full wp-image-1500" /></center></p>
<p>Anyway, here&#8217;s the method. Hope this can save someone else some time. Also if you spot anything wrong about this let me know.</p>
<pre class="brush: csharp;">public enum HorizontalClamp
{
	Left,
	Right,
	Center
}

public enum VerticalClamp
{
	Top,
	Bottom,
	Center
}

public static class ArrayExtensions
{
	public static T[,] Resize&lt;T&gt;(
		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 &lt; xEnd; x1++, x2++)
		{
			for (int y1 = targetY, y2 = yStart; y2 &lt; yEnd; y1++, y2++)
			{
				newArray[x1, y1] = array[x2, y2];
			}
		}

		return newArray;
	}
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.nickgravelyn.com/2010/03/resizing-2d-arrays/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Playing MP3s with Silverlight</title>
		<link>http://blog.nickgravelyn.com/2010/02/playing-mp3s-with-silverlight/</link>
		<comments>http://blog.nickgravelyn.com/2010/02/playing-mp3s-with-silverlight/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 17:13:38 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.nickgravelyn.com/?p=1488</guid>
		<description><![CDATA[Well that didn&#8217;t take long.  
I&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>Well that didn&#8217;t take long. <img src='http://blog.nickgravelyn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I&#8217;ve already updated my MP3 plugin to use a new Silverlight player. I found a <a href="http://slmp3player.codeplex.com/">pretty nice one on CodePlex</a> 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 &#8220;Buffering&#8230;&#8221; because that annoyed me.</p>
<p>Once I did all that, I was left with <a href="/silverlight/Mp3Player.xap">this nice XAP</a> which I&#8217;m sharing with you. Feel free to upload it to your server and use it to play your MP3s.</p>
<p>So when I went and updated my plugin, I needed to change the output quite a bit. Here&#8217;s what the new code looks like:</p>
<pre class="brush: php;">add_filter('the_content', 'insert_audio');

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

  return preg_replace($pattern, $replacement, $content);
}</pre>
<p>Isn&#8217;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&#8217;ll want to change that if you use the plugin.</p>
<p>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#. <img src='http://blog.nickgravelyn.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nickgravelyn.com/2010/02/playing-mp3s-with-silverlight/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extending Wordpress for audio tags</title>
		<link>http://blog.nickgravelyn.com/2010/02/extending-wordpress-for-audio-tags/</link>
		<comments>http://blog.nickgravelyn.com/2010/02/extending-wordpress-for-audio-tags/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 16:01:47 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.nickgravelyn.com/?p=1481</guid>
		<description><![CDATA[Since I&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>Since I&#8217;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&#8217;t like the current player, I can change to something else and every instance is updated in one go.</p>
<p>So for my audio, I decided to make life easy. Just put something like this:</p>
<p>[ audio:/path/to/file.mp3 ]Name Of Song[ /audio ]<br />
(without the spaces in the audio tags)</p>
<p>And it converts that to the following HTML5 code:</p>
<pre class="brush: xml;">&lt;p&gt;&lt;audio src=&quot;/path/to/file.mp3&quot; controls=&quot;controls&quot;&gt;&lt;/audio&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/path/to/file.mp3&quot;&gt;Name Of Song&lt;/a&gt;&lt;/p&gt;</pre>
<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&#8217;t support the audio tag yet and Firefox only supports OGG and WAV, so this isn&#8217;t probably the &#8220;best&#8221; 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.</p>
<p>Anyway, with that introduction out of the way, here&#8217;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:</p>
<pre class="brush: php;">add_filter('the_content', 'insert_audio');

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

  return preg_replace($pattern, $replacement, $content);
}</pre>
<p>Yep, that&#8217;s it. <a href="/wp-content/uploads/2010/02/nicks-audio-plugin.php_.txt">My file</a> technically has a bunch of the standard comment stuff in it, but I didn&#8217;t want to paste that all in here.</p>
<p>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&#8217;ve found or written? I&#8217;m always up for more plugins. <img src='http://blog.nickgravelyn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nickgravelyn.com/2010/02/extending-wordpress-for-audio-tags/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making noise</title>
		<link>http://blog.nickgravelyn.com/2010/02/making-noise/</link>
		<comments>http://blog.nickgravelyn.com/2010/02/making-noise/#comments</comments>
		<pubDate>Sun, 28 Feb 2010 07:44:47 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.nickgravelyn.com/?p=1446</guid>
		<description><![CDATA[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&#8217;t have a Mac, that&#8217;s not really an option. Thankfully ACID seems to not be much harder to learn and seems to be an overall superior [...]]]></description>
			<content:encoded><![CDATA[<p>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&#8217;t have a Mac, that&#8217;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:</p>
<p><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://nickgravelyn.com/music/Actiony.mp3,name=Actiony" />
    <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://nickgravelyn.com/music/Actiony.mp3">Download Actiony</a></p></center></p>
<p>It&#8217;s not much (and not terribly good), but it&#8217;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&#8217;t awful. <img src='http://blog.nickgravelyn.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nickgravelyn.com/2010/02/making-noise/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>sspack your images</title>
		<link>http://blog.nickgravelyn.com/2010/02/sspack-your-images/</link>
		<comments>http://blog.nickgravelyn.com/2010/02/sspack-your-images/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 20:14:32 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.nickgravelyn.com/?p=1442</guid>
		<description><![CDATA[Today I checked in the first update to Sprite Sheet Packer in a few months. Inspired by a discussion post I somehow didn&#8217;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 [...]]]></description>
			<content:encoded><![CDATA[<p>Today I checked in the first update to <a href="http://spritesheetpacker.codeplex.com/">Sprite Sheet Packer</a> in a few months. Inspired by a discussion post I somehow didn&#8217;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.</p>
<p>First let&#8217;s do the techie thing and just look at the arguments of the tool:</p>
<pre class="brush: plain;">C:\Users\Nick\Desktop&gt;sspack
Missing required argument '/image'.
Missing required argument '/map'.
/image:&lt;string&gt;  Output file name for the image.
/map:&lt;string&gt;    Output file name for the map.
/mw:&lt;int&gt;        Maximum ouput width. Default:'4096'
/mh:&lt;int&gt;        Maximum ouput height. Default:'4096'
/pad:&lt;int&gt;       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:&lt;string&gt;     Path(s) to file(s) listing the images to build.
&lt;input&gt;          Images to pack.</pre>
<p>Those first two lines are unfortunately a bit misleading but the library I used for parsing command line arguments didn&#8217;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:</p>
<pre class="brush: plain;">sspack /image:test.png /map:test.txt C:\Users\Nick\Desktop\MyImages\*.png</pre>
<p>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&#8217;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&#8217;s it.</p>
<p>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:</p>
<pre class="brush: plain;">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</pre>
<p>And invoke sspack with that file which it uses to find the files:</p>
<pre class="brush: plain;">sspack /image:test.png /map:test.txt C:\Users\Nick\Desktop\ImagesToPack.txt</pre>
<p>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.</p>
<p>If you have any suggestions, feel free to let me know, but no promises. As you can see, I don&#8217;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.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nickgravelyn.com/2010/02/sspack-your-images/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Naming your content</title>
		<link>http://blog.nickgravelyn.com/2010/02/naming-your-content/</link>
		<comments>http://blog.nickgravelyn.com/2010/02/naming-your-content/#comments</comments>
		<pubDate>Sat, 27 Feb 2010 15:35:58 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.nickgravelyn.com/?p=1439</guid>
		<description><![CDATA[A number of the built in types you load through ContentManager in XNA have a Name property. Most (all?) don&#8217;t actually set this at any point; it&#8217;s just there for you to use. I like to use these names for various things and I&#8217;m sick of setting them all manually. So I started out to [...]]]></description>
			<content:encoded><![CDATA[<p>A number of the built in types you load through ContentManager in XNA have a Name property. Most (all?) don&#8217;t actually set this at any point; it&#8217;s just there for you to use. I like to use these names for various things and I&#8217;m sick of setting them all manually. So I started out to make my own ContentManager that does this for me.</p>
<p>It started off with something like this:</p>
<pre class="brush: csharp;">public class MyContentManager : ContentManager
{
	public MyContentManager(IServiceProvider services)
		: base(services, &quot;Content&quot;)
	{
	}

	public override T Load&lt;T&gt;(string assetName)
	{
		T content = base.Load&lt;T&gt;(assetName);

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

		return content;
	}
}</pre>
<p>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:</p>
<pre class="brush: csharp;">public class MyContentManager : ContentManager
{
	public MyContentManager(IServiceProvider services)
		: base(services, &quot;Content&quot;)
	{
	}

	public override T Load&lt;T&gt;(string assetName)
	{
		T content = base.Load&lt;T&gt;(assetName);

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

		return content;
	}
}</pre>
<p>And now any content that I load that has a Name property with a setter will get its name set. But I&#8217;m not quite done yet. Reflection isn&#8217;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:</p>
<pre class="brush: csharp;">public class MyContentManager : ContentManager
{
	private readonly Dictionary&lt;string, bool&gt; namedContent = new Dictionary&lt;string, bool&gt;();

	public MyContentManager(IServiceProvider services)
		: base(services, &quot;Content&quot;)
	{
	}

	public override T Load&lt;T&gt;(string assetName)
	{
		T content = base.Load&lt;T&gt;(assetName);

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

		return content;
	}
}</pre>
<p>And that&#8217;s where I&#8217;m at now. I fully realize that reflection is not going to be as fast as doing those casts, but since I&#8217;m also doing this caching of what items have been named, I&#8217;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&#8217;t likely to be noticeable or an issue.</p>
<p>I&#8217;d be interested in hearing what others are doing to extend this class. Anyone else using a custom ContentManager for anything?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nickgravelyn.com/2010/02/naming-your-content/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Expanding animated Gif images</title>
		<link>http://blog.nickgravelyn.com/2010/02/expanding-animated-gif-images/</link>
		<comments>http://blog.nickgravelyn.com/2010/02/expanding-animated-gif-images/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 06:37:23 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.nickgravelyn.com/?p=1426</guid>
		<description><![CDATA[I like my little Paint.NET plugin. It&#8217;s nifty. But honestly it&#8217;s a pain sometimes to rename a file to .agif, open Paint.NET, open the file, and then get what I want. It&#8217;s ok for saving, but for loading it&#8217;s just a pain. It also leverages this NGif library that I&#8217;m learning isn&#8217;t really needed at [...]]]></description>
			<content:encoded><![CDATA[<p>I like my little <a href="/2009/12/paint-net-animation-strip-plugin/">Paint.NET plugin</a>. It&#8217;s nifty. But honestly it&#8217;s a pain sometimes to rename a file to .agif, open Paint.NET, open the file, and then get what I want. It&#8217;s ok for saving, but for loading it&#8217;s just a pain. It also leverages this NGif library that I&#8217;m learning isn&#8217;t really needed at all.</p>
<p>So tonight I fixed that by making a new app. This new app acts as a command line tool (or drag-and-drop as I use it) that simply takes a GIF file and builds a PNG laying out each frame in a horizontal line. Best part? You can have this tool, too. Here&#8217;s the whopping 27 lines of code it takes:</p>
<pre class="brush: csharp;">static void Main(string[] args)
{
	if (args.Length != 1)
		return;

	Bitmap image = null;
	try { image = Bitmap.FromFile(args[0]) as Bitmap; }
	catch { return; }

	FrameDimension dimension = new FrameDimension(image.FrameDimensionsList[0]);
	int numFrames = image.GetFrameCount(dimension);
	Bitmap result = new Bitmap(image.Width * numFrames, image.Height);

	for (int i = 0; i &lt; numFrames; i++)
	{
		image.SelectActiveFrame(dimension, i);

		for (int x = 0; x &lt; image.Width; x++)
		{
			for (int y = 0; y &lt; image.Height; y++)
			{
				result.SetPixel(i * image.Width + x, y, image.GetPixel(x, y));
			}
		}
	}

	result.Save(args[0].Remove(args[0].Length - 3) + &quot;png&quot;, ImageFormat.Png);
}</pre>
<p>Just drop that in on a console project (make sure you add a reference to System.Drawing) and you&#8217;re good to go. First test was to take this:</p>
<p><img src="http://blog.nickgravelyn.com/wp-content/uploads/2010/02/ninja-running.gif" alt="Ninja Running (GIF)" title="Ninja Running (GIF)" width="64" height="64" class="alignnone size-full wp-image-1427" /></p>
<p>and make it into this:</p>
<p><img src="http://blog.nickgravelyn.com/wp-content/uploads/2010/02/ninja-running.png" alt="Ninja Running (PNG)" title="Ninja Running (PNG)" width="256" height="64" class="alignnone size-full wp-image-1428" /></p>
<p>Good stuff.</p>
<p>I was going to then make a content importer for this, but I found out that without having to make a new type and custom content pipeline for it, I couldn&#8217;t get the frame count or frame size to the game. I wanted to just have this be an importer or processor, but near as I can tell there is no such way to just attach that data to the TextureContent and have it end up on the Texture2D I load up. If you find a quick (read: hacky) way to do this, feel free to let me know in the comments.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nickgravelyn.com/2010/02/expanding-animated-gif-images/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using GamerServicesDispatcher to fix up exception handling</title>
		<link>http://blog.nickgravelyn.com/2010/02/using-gamerservicesdispatcher-to-fix-up-exception-handling/</link>
		<comments>http://blog.nickgravelyn.com/2010/02/using-gamerservicesdispatcher-to-fix-up-exception-handling/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 17:22:25 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.nickgravelyn.com/?p=1417</guid>
		<description><![CDATA[Since my last update to my exception handling code that showed how to handle using GamerServices in the exception game after the first game uses it, I&#8217;ve found out a much, much better way to handle this scenario. The key here: don&#8217;t use the GamerServicesComponent.
The GamerServicesComponent is a very minimal wrapper on top of the [...]]]></description>
			<content:encoded><![CDATA[<p>Since <a href="/2009/11/exception-handling-and-gamerservicescomponent/">my last update</a> to my <a href="/2009/07/a-more-robust-exception-system/">exception handling code</a> that showed how to handle using GamerServices in the exception game after the first game uses it, I&#8217;ve found out a much, much better way to handle this scenario. The key here: don&#8217;t use the GamerServicesComponent.</p>
<p>The GamerServicesComponent is a very minimal wrapper on top of the GamerServicesDispatcher. If we avoid using the GamerServicesComponent in both games, we&#8217;ll be fine. I&#8217;m personally moving away from using the component entirely, but you can keep using it in the real game and just use the dispatcher directly in the second.</p>
<p>Basically what you&#8217;ll do in your exception game is simply initialize the dispatcher directly if it needs to by calling Initialize and setting the window handle.</p>
<pre class="brush: csharp;">protected override void Initialize()
{
	if (!GamerServicesDispatcher.IsInitialized)
	{
		GamerServicesDispatcher.Initialize(Services);
	}
	GamerServicesDispatcher.WindowHandle = Window.Handle;
	base.Initialize();
}</pre>
<p>And then just remember to Update the dispatcher each frame:</p>
<pre class="brush: csharp;">protected override void Update(GameTime gameTime)
{
	GamerServicesDispatcher.Update();
	// update other stuff
	base.Update(gameTime);
}</pre>
<p>And there you go. No more need to make your GamerServicesComponent a static property or rely on that bug in the Game class. Much better.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.nickgravelyn.com/2010/02/using-gamerservicesdispatcher-to-fix-up-exception-handling/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
