<?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>luminance &#187; enums</title>
	<atom:link href="http://www.luminance.org/tag/enums/feed" rel="self" type="application/rss+xml" />
	<link>http://www.luminance.org/blog</link>
	<description>Programming and Game Development - Kevin Gadd&#039;s Blog</description>
	<lastBuildDate>Sun, 02 Oct 2011 00:15:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Animation markers and triggers</title>
		<link>http://www.luminance.org/blog/gruedorf/2009/05/22/animation-markers-and-triggers</link>
		<comments>http://www.luminance.org/blog/gruedorf/2009/05/22/animation-markers-and-triggers#comments</comments>
		<pubDate>Sat, 23 May 2009 04:14:42 +0000</pubDate>
		<dc:creator>Kael</dc:creator>
				<category><![CDATA[Gruedorf]]></category>
		<category><![CDATA[animation]]></category>
		<category><![CDATA[csharp]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[enums]]></category>
		<category><![CDATA[platformer]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[xna]]></category>

		<guid isPermaLink="false">http://www.luminance.org/?p=394</guid>
		<description><![CDATA[One of the first things I did this week was implement support for scripted animation markers. Markers let me attach names to various parts of a sprite so that I can use them in animation and collision detection &#8211; for example, lining up a weapon with a character&#8217;s hand, or doing hit detection against a [...]]]></description>
			<content:encoded><![CDATA[<p>One of the first things I did this week was implement support for scripted animation markers. Markers let me attach names to various parts of a sprite so that I can use them in animation and collision detection &#8211; for example, lining up a weapon with a character&#8217;s hand, or doing hit detection against a character&#8217;s hand instead of his entire hitbox.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube-nocookie.com/v/3-0tu2X40z0&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x2b405b&amp;color2=0x6b8ab6&amp;hd=1" /><embed type="application/x-shockwave-flash" width="640" height="385" src="http://www.youtube-nocookie.com/v/3-0tu2X40z0&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x2b405b&amp;color2=0x6b8ab6&amp;hd=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>Once I had some simple markers for the player&#8217;s feet added to his animation script, to test them out more thoroughly, I implemented support for attaching simple script triggers to a combination of a marker and a given animation frame, like this:</p>
<pre>    &lt;SpriteMarker typeId="2"&gt;
        &lt;Name&gt;Left Foot&lt;/Name&gt;
        &lt;Groups&gt;
            ...
            &lt;Group name="run"&gt;
                &lt;Frames&gt;
                    &lt;Frame anchor="tl" x="80"  y="170" index="0" /&gt;
                    &lt;Frame anchor="tl" x="61"  y="169" index="1" /&gt;
                    ...
                    &lt;Frame anchor="tl" x="132" y="143" index="6" /&gt;
                    &lt;Frame anchor="tl" x="99"  y="173" index="7" trigger="Footstep" /&gt;
                &lt;/Frames&gt;
            &lt;/Group&gt;
        &lt;/Groups&gt;
    &lt;/SpriteMarker&gt;</pre>
<p>Using the combination of markers and triggers, I was able to write a simple bit of C# to go with the animation script and spawn small puffs of smoke every time the player&#8217;s feet land on the ground during his run animation:</p>
<pre>    public void Footstep (string foot) {
        if (Jumping &amp;&amp; !JumpLanded)
            return;

        var pos = ResolveMarker(foot);
        if (!pos.HasValue)
            return;
        Game.SpawnSmokePuff(Position + pos.Value - GetDrawOrigin(Animator.Frame), 10, 0.5f);
    }</pre>
<p>The real motivation behind the marker system, however, was syncing animations with the game world &#8211; I wanted the player&#8217;s grappling hook to extend from his hand, have his melee attacks actually sync up with his animation frames, and have his collision detection change realistically while crouched.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube-nocookie.com/v/_h20KUxmMXs&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x2b405b&amp;color2=0x6b8ab6&amp;hd=1" /><embed type="application/x-shockwave-flash" width="640" height="385" src="http://www.youtube-nocookie.com/v/_h20KUxmMXs&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x2b405b&amp;color2=0x6b8ab6&amp;hd=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>Essentially, where before I used hard-coded coordinates and percentages, now I &#8216;resolve&#8217; one of the player&#8217;s named markers. Resolving a marker either returns coordinates (relative to the top left of the frame) or null, which allows me to determine whether a given frame has a particular marker attached to it. Once I have coordinates for a marker, I compute the player&#8217;s origin (used for positioning his animation frames) and use that to compute the on-screen or in-world coordinates for the marker, based on the frame-relative coordinate I already have. Given that, I can sync up things like a grappling hook or a potion with the player&#8217;s hand:</p>
<pre>    public Vector2 GrappleFrom {
        get {
            var handPos = ResolveMarker("Right Hand");
            return Position + handPos.GetValueOrDefault(
                new Vector2(0, Obstruction.Y * -0.5f)
            ) - GetDrawOrigin(Animator.Frame);
        }
    }</pre>
<p>After using this technique to make the player&#8217;s bounding box change while crouching, I realized that by uncrouching, the player could become stuck in a ceiling. The solution to this ended up being a bit of a hack &#8211; before increasing the size of the player&#8217;s bounding box, do a quick collision check to see if the player&#8217;s <strong>current</strong> bounding box is able to move upward by that same amount. If the check fails, I now know exactly how far the player&#8217;s current bounding box would have been able to move, and I can constrain the growth of the bounding box to avoid making the player become stuck.</p>
<p>Once the player is out of a tight space, I can grow the bounding box to its full height, restoring sanity. It&#8217;s not perfect (and looks kind of stupid since it allows the player&#8217;s head to stick through ceilings), but it was relatively simple to implement. I suspect I&#8217;ll end up with a different solution in the final game &#8211; perhaps forcing the player to stay crouched if he can&#8217;t stand up in his current position.</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="385" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube-nocookie.com/v/1zL721akH3o&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x2b405b&amp;color2=0x6b8ab6&amp;hd=1" /><embed type="application/x-shockwave-flash" width="640" height="385" src="http://www.youtube-nocookie.com/v/1zL721akH3o&amp;hl=en&amp;fs=1&amp;rel=0&amp;color1=0x2b405b&amp;color2=0x6b8ab6&amp;hd=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>During the process of rigging up the player&#8217;s animations, I spent a lot of time fine-tuning things and working out issues. To make things move quicker, I ended up adding a couple new features to my engine:</p>
<p>First, I added support for reloading sprites and tiles at runtime. My existing game code already was designed in such a way that this wasn&#8217;t too difficult, but I still had to do some work in order to get the rest of the way. One of the biggest changes was that I had to change entities to store a sprite&#8217;s Name instead of storing the sprite itself, so that I could replace a given sprite instance at runtime after reloading it from disk. As a result, where before I had:</p>
<pre>    this.Sprite.Animations["Walk"].Run(this.SpriteContext);</pre>
<p>Now, I have something like this:</p>
<pre>    Game.Sprites[this.SpriteName].Animations["Walk"].Run(this.SpriteContext);</pre>
<p>A bit more verbose, but easy to abstract out using properties and helper methods &#8211; such that actual game code can just use convenience methods, like so:</p>
<pre>    this.PlayAnimation("Walk");</pre>
<p>And everything happens behind the scenes.</p>
<p>The other change I made was to overhaul my rendering model in order to make it easier to add debugging overlays, user interface graphics, and special effects without having to change the Game&#8217;s Draw function. First, I changed the signature of most of my objects&#8217; Draw methods, such that they now take an extra parameter:</p>
<pre>    public override void Draw (DrawFlags flags) {</pre>
<p>Then, the game code can pass a combination of flags to an object to specify which types of rendering to perform:</p>
<pre>    if (ShowHUD) {
        var flags = DrawFlags.HUD | (GlobalDrawFlags &amp; DrawFlags.DebugHUD);
        RenderGeometry(flags);
        RenderEntities(flags);
    }</pre>
<p>As a result, I have the ability to easily toggle off sections of an individual object&#8217;s painting code, without having to directly hook the logic into the Game object itself. This also nicely simplifies a lot of the code in my editor, since I can now do editor-related painting (like drawing bounding boxes, selection highlights, etc) in the Draw method of the object in question, instead of having to add a special function to the editor that draws those things manually, or having to add an &#8216;EditorDraw&#8217; method to the objects (like I had before in a few cases, unfortunately).</p>
<p>With the addition of a couple extension methods to simplify things, it wasn&#8217;t too hard to wire things up inside my game objects. For example, this is what SpriteEntity.Draw looks like:</p>
<pre>    public override void Draw (DrawFlags flags) {
        ...
        var drawPos = GetDrawPosition();
        var origin = GetDrawOrigin(Animator.Frame);

        if (flags.Check(DrawFlags.Entities))
            Draw(drawPos, origin, Scale, Color);

        if (flags.Check(DrawFlags.DebugEntities)) {
            Game.SetupRenderState(true);
            Game.DrawBox(this.Bounds, Color.White);
            Game.CleanupRenderState();
        }</pre>
<p>It simply checks for each of the draw flags it knows how to handle, and processes them accordingly, in a given order. This gives me the ability to do multiple draw passes at once, or do them individually if I want finer-grained control over draw order. A good example of this is the HUD pass &#8211; I want HUD elements to cover all the objects in the game world, so I draw them in a separate pass. But debugging overlays like entities&#8217; bounding boxes don&#8217;t need to cover everything, so I draw them in the same pass as the entities themselves.</p>
<p>For the curious, the extension methods I ended up writing look like this:</p>
<pre>    public static bool Check (this DrawFlags drawFlags, DrawFlags flag) {
        return (drawFlags &amp; flag) == flag;
    }

    public static DrawFlags Toggle (this DrawFlags drawFlags, DrawFlags flag) {
        return ((drawFlags ^ DrawFlags.All) &amp; flag) | (drawFlags &amp; (flag ^ DrawFlags.All));
    }</pre>
<p>They&#8217;re fairly simple, but having them tremendously simplifies the process of working with the DrawFlags enumeration. This is one thing that I wish C# had built-in support for, but it&#8217;s at least fairly easy to add with extension methods. Unfortunately, generic types and enums don&#8217;t get along, otherwise you could have generic forms of these functions instead of having to write them for each Flags enumeration in your game.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.luminance.org/blog/gruedorf/2009/05/22/animation-markers-and-triggers/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

