<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Jesper Niedermann's .NET Blog - XNA</title>
    <link>http://www.niedermann.dk/</link>
    <description>about .NET and related technologies</description>
    <language>en-us</language>
    <copyright>Jesper Niedermann</copyright>
    <lastBuildDate>Wed, 12 May 2010 20:38:51 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.2.8279.16125</generator>
    <managingEditor>jesper@niedermann.dk</managingEditor>
    <webMaster>jesper@niedermann.dk</webMaster>
    <item>
      <trackback:ping>http://www.niedermann.dk/Trackback.aspx?guid=91776158-a7f1-490d-a36f-dd9def7cf9ee</trackback:ping>
      <pingback:server>http://www.niedermann.dk/pingback.aspx</pingback:server>
      <pingback:target>http://www.niedermann.dk/PermaLink,guid,91776158-a7f1-490d-a36f-dd9def7cf9ee.aspx</pingback:target>
      <dc:creator>Jesper Niedermann</dc:creator>
      <wfw:comment>http://www.niedermann.dk/CommentView,guid,91776158-a7f1-490d-a36f-dd9def7cf9ee.aspx</wfw:comment>
      <wfw:commentRss>http://www.niedermann.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=91776158-a7f1-490d-a36f-dd9def7cf9ee</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Windows developers who are used to click events in WinForms, WPF or Silverlight might
miss click and double click events, but because of the game loop where everything
is drawn and updated every few milliseconds an event based approach is probably not
a good idea in most cases. Not so much because of the performance of an event based
approach, but more because the complexity is overwhelming. If several users clicks
and double clicks several keys on the keyboard simultaneously, how would you decide
which of these are clicked and in which order, and further more it is not obvious
to subscribers of the events that they are in the game loop, so they might do code
which performs inadequately.
</p>
        <p>
I have made a few generic classes that expands the MouseState, GamePadState and KeyboardState
in order to make click “events” available. But of course I utilize the standard polling
mechanism in XNA which is to call GetState() on each device.
</p>
        <p>
The approach is that I call my own version of GetState() in the main game loop. My
GetState() method first enqueues the state in a Queue, and then dequeues all states
older than 500 ms, before the state is returned. In this way a historical map of user
interactions is maintained at all times.
</p>
        <p>
Now I can simply check if a key or button was clicked by checking if the key was pressed
and then released “historically”. Similarly I can check for double click by checking
if the key or button was pressed, then released, then pressed again and then released
again.
</p>
        <p>
Now you probably realize why I go back 500 ms. It is because this is the standard
time in which a double click should be executed.
</p>
        <p>
I have used this approach in the game Protect the Carrot at <a href="http://ptc.codeplex.com">http://ptc.codeplex.com</a> and
it works like a charm (The url for the game does not work today, since the game will
only be published in a few weeks).
</p>
        <p>
Here is the implementation of the MouseExtended class which uses this approach:
</p>
        <pre class="c#" name="code">using System;<br />
using System.Collections.Generic;<br />
using System.Linq;<br />
using System.Text;<br />
using Microsoft.Xna.Framework.Input;<br />
using Microsoft.Xna.Framework;<br /><br />
namespace PTC.Input<br />
{<br />
public class MouseExtended : InputDeviceExtended&lt;MouseState&gt;<br />
{<br />
private static MouseExtended m_Current;<br />
public static MouseExtended Current<br />
{<br />
get<br />
{<br />
if (m_Current == null)<br />
{<br />
m_Current = new MouseExtended();<br />
}<br />
return m_Current;<br />
}<br />
}<br /><br />
public MouseState GetState(GameTime currentTime)<br />
{<br />
DequeueOldStates(currentTime);<br />
MouseState state = Mouse.GetState();<br />
EnqueueNewState(currentTime, state);<br />
return state;<br />
}<br /><br />
private bool ClickCount(MouseButton checkButton, int requiredCount)<br />
{<br />
ButtonState found = ButtonState.Released;<br />
int count = 0;<br />
foreach (InputStateExtended&lt;MouseState&gt; stateExt in RecordedStates)<br />
{<br />
if (found == ButtonState.Pressed &amp;&amp; 
<br />
ButtonStateToCheck(stateExt.State, checkButton) == ButtonState.Released)<br />
{<br />
count++;<br />
if (count &gt;= requiredCount)<br />
return true;<br />
}<br />
found = ButtonStateToCheck(stateExt.State, checkButton);<br />
}<br />
return false;<br />
}<br /><br />
private ButtonState ButtonStateToCheck(MouseState state, MouseButton checkButton)<br />
{<br />
switch (checkButton)<br />
{<br />
case MouseButton.Left:<br />
return state.LeftButton;<br />
case MouseButton.Middle:<br />
return state.MiddleButton;<br />
case MouseButton.Right:<br />
return state.RightButton;<br />
case MouseButton.XButton1:<br />
return state.XButton1;<br />
case MouseButton.XButton2:<br />
return state.XButton2;<br />
default:<br />
return state.LeftButton;<br />
}<br />
}<br /><br />
public bool WasSingleClick(MouseButton checkButton)<br />
{<br />
return(ClickCount(checkButton, 1));<br />
}<br /><br />
public bool WasDoubleClick(MouseButton checkButton)<br />
{<br />
return (ClickCount(checkButton, 2));<br />
}<br /><br />
}<br />
}</pre>
        <p>
And here is the generic InputDeviceExtended class which MouseExtended inherits:
</p>
        <pre class="c#" name="code">using System;<br />
using System.Collections.Generic;<br />
using System.Linq;<br />
using Microsoft.Xna.Framework;<br />
using Microsoft.Xna.Framework.Audio;<br />
using Microsoft.Xna.Framework.Content;<br />
using Microsoft.Xna.Framework.GamerServices;<br />
using Microsoft.Xna.Framework.Graphics;<br />
using Microsoft.Xna.Framework.Input;<br />
using Microsoft.Xna.Framework.Media;<br />
using Microsoft.Xna.Framework.Net;<br />
using Microsoft.Xna.Framework.Storage;<br /><br />
namespace PTC.Input<br />
{<br />
public class InputDeviceExtended&lt;S&gt; where S : struct<br />
{<br />
private Queue&lt;InputStateExtended&lt;S&gt;&gt; m_RecordedStates = new Queue&lt;InputStateExtended&lt;S&gt;&gt;();<br /><br />
public Queue&lt;InputStateExtended&lt;S&gt;&gt; RecordedStates<br />
{<br />
get { return m_RecordedStates; }<br />
}<br /><br />
private Stack&lt;InputStateExtended&lt;S&gt;&gt; m_StatesForReuse = new Stack&lt;InputStateExtended&lt;S&gt;&gt;();<br /><br />
protected void EnqueueNewState(GameTime time, S state)<br />
{<br />
if (!state.Equals(m_CurrentState))<br />
{<br />
m_CurrentState = state;<br />
m_RecordedStates.Enqueue(CreateState(time, state));<br />
}<br />
}<br /><br />
private S m_CurrentState;<br />
public S CurrentState<br />
{<br />
get { return m_CurrentState; }<br />
}<br /><br />
protected void DequeueOldStates(GameTime currentTime)<br />
{<br />
InputStateExtended&lt;S&gt; state = null;<br />
if (m_RecordedStates.Count &gt; 0)<br />
{<br />
state = m_RecordedStates.Peek();<br />
}<br />
if (state != null &amp;&amp; state.StateTime &lt; currentTime.TotalRealTime.Subtract(new
TimeSpan(0, 0, 0, 0, InputDeviceConstants.ClickCountTimeMS)))<br />
{<br />
m_StatesForReuse.Push(m_RecordedStates.Dequeue());<br />
DequeueOldStates(currentTime);<br />
}<br />
}<br /><br />
private InputStateExtended&lt;S&gt; CreateState(GameTime time, S state)<br />
{<br />
if (m_StatesForReuse.Count &gt; 0)<br />
{<br />
//Reuses the object to fight of the GC<br />
InputStateExtended&lt;S&gt; stateExt = m_StatesForReuse.Pop();<br />
stateExt.StateTime = time.TotalRealTime;<br />
stateExt.State = state;<br />
return stateExt;<br />
}<br />
else<br />
{<br />
return new InputStateExtended&lt;S&gt;(time, state);<br />
}<br />
}<br />
}<br />
}</pre>
        <p>
Notice that the Recorded States are reused. When dequeued from the queue the are added
to a reuse stack. This is a standard trick to fight of the Garbage Collector, by always
keeping a reference to objects on the heap they never become garbage + they are reused
so the memory use will not explode.
</p>
        <p>
I have also implemented the necessary extended classes for the Keyboard and the gamepad.
I have included them in the attachment to this post. I have not tested the GamepadExtended
class since I do not own a Gamepad, but it is implemented exactly as the keyboard
and mouse classes and ought to work. 
</p>
        <p>
To wire up the new classes you just add the relevant Getstate() calls to the Update
game loop like so:
</p>
        <pre class="c#" name="code">protected override void Update(GameTime gameTime)<br />
{<br />
KeyboardExtended.Current.GetState(gameTime);<br />
MouseExtended.Current.GetState(gameTime);<br />
base.Update(gameTime);<br />
}</pre>
        <p>
And then you can check for click and double click “events”. For instance you check
for double click of the left mouse button like this:
</p>
        <pre class="c#" name="code">if(MouseExtended.Current.WasDoubleClick(MouseButton.Left)))<br />
{<br />
//Do double click reaction<br />
}</pre>
        <p>
Hope you like the stuff.And look out for the amazing “Protect The Carrot” game within
the next month or so, at <a href="http://ptc.codeplex.com">http://ptc.codeplex.com</a></p>
        <p>
In InputDeviceExtended.zip I have included the code for all the InputDevice classes.
</p>
        <p>
        </p>
        <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:f7cf6f0f-1ed3-4885-8873-f8eaf969cb75" class="wlWriterEditableSmartContent">
          <p>
            <a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/ClickanddoubleclickinXNAGames_EF42/InputDeviceExtended.zip" target="_blank">InputDeviceExtended.zip</a>
          </p>
        </div>
        <img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=91776158-a7f1-490d-a36f-dd9def7cf9ee" />
      </body>
      <title>Click and double click in XNA Games</title>
      <guid isPermaLink="false">http://www.niedermann.dk/PermaLink,guid,91776158-a7f1-490d-a36f-dd9def7cf9ee.aspx</guid>
      <link>http://www.niedermann.dk/2010/05/12/ClickAndDoubleClickInXNAGames.aspx</link>
      <pubDate>Wed, 12 May 2010 20:38:51 GMT</pubDate>
      <description>&lt;p&gt;
Windows developers who are used to click events in WinForms, WPF or Silverlight might
miss click and double click events, but because of the game loop where everything
is drawn and updated every few milliseconds an event based approach is probably not
a good idea in most cases. Not so much because of the performance of an event based
approach, but more because the complexity is overwhelming. If several users clicks
and double clicks several keys on the keyboard simultaneously, how would you decide
which of these are clicked and in which order, and further more it is not obvious
to subscribers of the events that they are in the game loop, so they might do code
which performs inadequately.
&lt;/p&gt;
&lt;p&gt;
I have made a few generic classes that expands the MouseState, GamePadState and KeyboardState
in order to make click “events” available. But of course I utilize the standard polling
mechanism in XNA which is to call GetState() on each device.
&lt;/p&gt;
&lt;p&gt;
The approach is that I call my own version of GetState() in the main game loop. My
GetState() method first enqueues the state in a Queue, and then dequeues all states
older than 500 ms, before the state is returned. In this way a historical map of user
interactions is maintained at all times.
&lt;/p&gt;
&lt;p&gt;
Now I can simply check if a key or button was clicked by checking if the key was pressed
and then released “historically”. Similarly I can check for double click by checking
if the key or button was pressed, then released, then pressed again and then released
again.
&lt;/p&gt;
&lt;p&gt;
Now you probably realize why I go back 500 ms. It is because this is the standard
time in which a double click should be executed.
&lt;/p&gt;
&lt;p&gt;
I have used this approach in the game Protect the Carrot at &lt;a href="http://ptc.codeplex.com"&gt;http://ptc.codeplex.com&lt;/a&gt; and
it works like a charm (The url for the game does not work today, since the game will
only be published in a few weeks).
&lt;/p&gt;
&lt;p&gt;
Here is the implementation of the MouseExtended class which uses this approach:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;using System;&lt;br&gt;
using System.Collections.Generic;&lt;br&gt;
using System.Linq;&lt;br&gt;
using System.Text;&lt;br&gt;
using Microsoft.Xna.Framework.Input;&lt;br&gt;
using Microsoft.Xna.Framework;&lt;br&gt;
&lt;br&gt;
namespace PTC.Input&lt;br&gt;
{&lt;br&gt;
public class MouseExtended : InputDeviceExtended&amp;lt;MouseState&amp;gt;&lt;br&gt;
{&lt;br&gt;
private static MouseExtended m_Current;&lt;br&gt;
public static MouseExtended Current&lt;br&gt;
{&lt;br&gt;
get&lt;br&gt;
{&lt;br&gt;
if (m_Current == null)&lt;br&gt;
{&lt;br&gt;
m_Current = new MouseExtended();&lt;br&gt;
}&lt;br&gt;
return m_Current;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
public MouseState GetState(GameTime currentTime)&lt;br&gt;
{&lt;br&gt;
DequeueOldStates(currentTime);&lt;br&gt;
MouseState state = Mouse.GetState();&lt;br&gt;
EnqueueNewState(currentTime, state);&lt;br&gt;
return state;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private bool ClickCount(MouseButton checkButton, int requiredCount)&lt;br&gt;
{&lt;br&gt;
ButtonState found = ButtonState.Released;&lt;br&gt;
int count = 0;&lt;br&gt;
foreach (InputStateExtended&amp;lt;MouseState&amp;gt; stateExt in RecordedStates)&lt;br&gt;
{&lt;br&gt;
if (found == ButtonState.Pressed &amp;amp;&amp;amp; 
&lt;br&gt;
ButtonStateToCheck(stateExt.State, checkButton) == ButtonState.Released)&lt;br&gt;
{&lt;br&gt;
count++;&lt;br&gt;
if (count &amp;gt;= requiredCount)&lt;br&gt;
return true;&lt;br&gt;
}&lt;br&gt;
found = ButtonStateToCheck(stateExt.State, checkButton);&lt;br&gt;
}&lt;br&gt;
return false;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private ButtonState ButtonStateToCheck(MouseState state, MouseButton checkButton)&lt;br&gt;
{&lt;br&gt;
switch (checkButton)&lt;br&gt;
{&lt;br&gt;
case MouseButton.Left:&lt;br&gt;
return state.LeftButton;&lt;br&gt;
case MouseButton.Middle:&lt;br&gt;
return state.MiddleButton;&lt;br&gt;
case MouseButton.Right:&lt;br&gt;
return state.RightButton;&lt;br&gt;
case MouseButton.XButton1:&lt;br&gt;
return state.XButton1;&lt;br&gt;
case MouseButton.XButton2:&lt;br&gt;
return state.XButton2;&lt;br&gt;
default:&lt;br&gt;
return state.LeftButton;&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
public bool WasSingleClick(MouseButton checkButton)&lt;br&gt;
{&lt;br&gt;
return(ClickCount(checkButton, 1));&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
public bool WasDoubleClick(MouseButton checkButton)&lt;br&gt;
{&lt;br&gt;
return (ClickCount(checkButton, 2));&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
}&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
And here is the generic InputDeviceExtended class which MouseExtended inherits:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;using System;&lt;br&gt;
using System.Collections.Generic;&lt;br&gt;
using System.Linq;&lt;br&gt;
using Microsoft.Xna.Framework;&lt;br&gt;
using Microsoft.Xna.Framework.Audio;&lt;br&gt;
using Microsoft.Xna.Framework.Content;&lt;br&gt;
using Microsoft.Xna.Framework.GamerServices;&lt;br&gt;
using Microsoft.Xna.Framework.Graphics;&lt;br&gt;
using Microsoft.Xna.Framework.Input;&lt;br&gt;
using Microsoft.Xna.Framework.Media;&lt;br&gt;
using Microsoft.Xna.Framework.Net;&lt;br&gt;
using Microsoft.Xna.Framework.Storage;&lt;br&gt;
&lt;br&gt;
namespace PTC.Input&lt;br&gt;
{&lt;br&gt;
public class InputDeviceExtended&amp;lt;S&amp;gt; where S : struct&lt;br&gt;
{&lt;br&gt;
private Queue&amp;lt;InputStateExtended&amp;lt;S&amp;gt;&amp;gt; m_RecordedStates = new Queue&amp;lt;InputStateExtended&amp;lt;S&amp;gt;&amp;gt;();&lt;br&gt;
&lt;br&gt;
public Queue&amp;lt;InputStateExtended&amp;lt;S&amp;gt;&amp;gt; RecordedStates&lt;br&gt;
{&lt;br&gt;
get { return m_RecordedStates; }&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private Stack&amp;lt;InputStateExtended&amp;lt;S&amp;gt;&amp;gt; m_StatesForReuse = new Stack&amp;lt;InputStateExtended&amp;lt;S&amp;gt;&amp;gt;();&lt;br&gt;
&lt;br&gt;
protected void EnqueueNewState(GameTime time, S state)&lt;br&gt;
{&lt;br&gt;
if (!state.Equals(m_CurrentState))&lt;br&gt;
{&lt;br&gt;
m_CurrentState = state;&lt;br&gt;
m_RecordedStates.Enqueue(CreateState(time, state));&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private S m_CurrentState;&lt;br&gt;
public S CurrentState&lt;br&gt;
{&lt;br&gt;
get { return m_CurrentState; }&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
protected void DequeueOldStates(GameTime currentTime)&lt;br&gt;
{&lt;br&gt;
InputStateExtended&amp;lt;S&amp;gt; state = null;&lt;br&gt;
if (m_RecordedStates.Count &amp;gt; 0)&lt;br&gt;
{&lt;br&gt;
state = m_RecordedStates.Peek();&lt;br&gt;
}&lt;br&gt;
if (state != null &amp;amp;&amp;amp; state.StateTime &amp;lt; currentTime.TotalRealTime.Subtract(new
TimeSpan(0, 0, 0, 0, InputDeviceConstants.ClickCountTimeMS)))&lt;br&gt;
{&lt;br&gt;
m_StatesForReuse.Push(m_RecordedStates.Dequeue());&lt;br&gt;
DequeueOldStates(currentTime);&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
private InputStateExtended&amp;lt;S&amp;gt; CreateState(GameTime time, S state)&lt;br&gt;
{&lt;br&gt;
if (m_StatesForReuse.Count &amp;gt; 0)&lt;br&gt;
{&lt;br&gt;
//Reuses the object to fight of the GC&lt;br&gt;
InputStateExtended&amp;lt;S&amp;gt; stateExt = m_StatesForReuse.Pop();&lt;br&gt;
stateExt.StateTime = time.TotalRealTime;&lt;br&gt;
stateExt.State = state;&lt;br&gt;
return stateExt;&lt;br&gt;
}&lt;br&gt;
else&lt;br&gt;
{&lt;br&gt;
return new InputStateExtended&amp;lt;S&amp;gt;(time, state);&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
Notice that the Recorded States are reused. When dequeued from the queue the are added
to a reuse stack. This is a standard trick to fight of the Garbage Collector, by always
keeping a reference to objects on the heap they never become garbage + they are reused
so the memory use will not explode.
&lt;/p&gt;
&lt;p&gt;
I have also implemented the necessary extended classes for the Keyboard and the gamepad.
I have included them in the attachment to this post. I have not tested the GamepadExtended
class since I do not own a Gamepad, but it is implemented exactly as the keyboard
and mouse classes and ought to work. 
&lt;/p&gt;
&lt;p&gt;
To wire up the new classes you just add the relevant Getstate() calls to the Update
game loop like so:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;protected override void Update(GameTime gameTime)&lt;br&gt;
{&lt;br&gt;
KeyboardExtended.Current.GetState(gameTime);&lt;br&gt;
MouseExtended.Current.GetState(gameTime);&lt;br&gt;
base.Update(gameTime);&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
And then you can check for click and double click “events”. For instance you check
for double click of the left mouse button like this:
&lt;/p&gt;
&lt;pre class="c#" name="code"&gt;if(MouseExtended.Current.WasDoubleClick(MouseButton.Left)))&lt;br&gt;
{&lt;br&gt;
//Do double click reaction&lt;br&gt;
}&lt;/pre&gt;
&lt;p&gt;
Hope you like the stuff.And look out for the amazing “Protect The Carrot” game within
the next month or so, at &lt;a href="http://ptc.codeplex.com"&gt;http://ptc.codeplex.com&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
In InputDeviceExtended.zip I have included the code for all the InputDevice classes.
&lt;/p&gt;
&lt;p&gt;
&lt;div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:fb3a1972-4489-4e52-abe7-25a00bb07fdf:f7cf6f0f-1ed3-4885-8873-f8eaf969cb75" class="wlWriterEditableSmartContent"&gt;
&lt;p&gt;
&lt;a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/ClickanddoubleclickinXNAGames_EF42/InputDeviceExtended.zip" target="_blank"&gt;InputDeviceExtended.zip&lt;/a&gt;
&lt;/p&gt;
&lt;/div&gt;
&gt;
&lt;img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=91776158-a7f1-490d-a36f-dd9def7cf9ee" /&gt;</description>
      <comments>http://www.niedermann.dk/CommentView,guid,91776158-a7f1-490d-a36f-dd9def7cf9ee.aspx</comments>
      <category>.NET</category>
      <category>Tips &amp; Tricks</category>
      <category>XNA</category>
    </item>
    <item>
      <trackback:ping>http://www.niedermann.dk/Trackback.aspx?guid=d70452c9-013d-49b4-82cc-b5290ae51893</trackback:ping>
      <pingback:server>http://www.niedermann.dk/pingback.aspx</pingback:server>
      <pingback:target>http://www.niedermann.dk/PermaLink,guid,d70452c9-013d-49b4-82cc-b5290ae51893.aspx</pingback:target>
      <dc:creator>Jesper Niedermann</dc:creator>
      <wfw:comment>http://www.niedermann.dk/CommentView,guid,d70452c9-013d-49b4-82cc-b5290ae51893.aspx</wfw:comment>
      <wfw:commentRss>http://www.niedermann.dk/SyndicationService.asmx/GetEntryCommentsRss?guid=d70452c9-013d-49b4-82cc-b5290ae51893</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I am currently developing the game Klimakonflikt with 5 other guys. It is a Retro
arcade game, Pac-man style, with nice 2D Graphics and music. Here is a screenshot
from the game:
</p>
        <p>
          <a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/RetroXNAGameKlimakonfliktunderdevelopmen_1B4/klimakonflikt_screenshot_4.png">
            <img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="klimakonflikt_screenshot" border="0" alt="klimakonflikt_screenshot" src="http://www.niedermann.dk/content/binary/WindowsLiveWriter/RetroXNAGameKlimakonfliktunderdevelopmen_1B4/klimakonflikt_screenshot_thumb_1.png" width="415" height="295" />
          </a>
        </p>
        <p>
The current release, documentation and source code can be downloaded from here <a href="http://klimakonflikt.codeplex.com" target="_blank">http://klimakonflikt.codeplex.com</a> 
</p>
        <p>
The game is inherently for 2 players but we are working on the single player edition.
The AI in the current release is pretty daft, but in the next release it will be much
improved. Also we are working on a WPF leveleditor, powerups and other fun stuff.
</p>
        <p>
One of my co-developers Jakob has released a blog about the game and XNA development
in general at <a href="http://xnafan.net" target="_blank">http://xnafan.net</a></p>
        <img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=d70452c9-013d-49b4-82cc-b5290ae51893" />
      </body>
      <title>Retro XNA Game Klimakonflikt under development</title>
      <guid isPermaLink="false">http://www.niedermann.dk/PermaLink,guid,d70452c9-013d-49b4-82cc-b5290ae51893.aspx</guid>
      <link>http://www.niedermann.dk/2009/11/13/RetroXNAGameKlimakonfliktUnderDevelopment.aspx</link>
      <pubDate>Fri, 13 Nov 2009 23:11:29 GMT</pubDate>
      <description>&lt;p&gt;
I am currently developing the game Klimakonflikt with 5 other guys. It is a Retro
arcade game, Pac-man style, with nice 2D Graphics and music. Here is a screenshot
from the game:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.niedermann.dk/content/binary/WindowsLiveWriter/RetroXNAGameKlimakonfliktunderdevelopmen_1B4/klimakonflikt_screenshot_4.png"&gt;&lt;img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="klimakonflikt_screenshot" border="0" alt="klimakonflikt_screenshot" src="http://www.niedermann.dk/content/binary/WindowsLiveWriter/RetroXNAGameKlimakonfliktunderdevelopmen_1B4/klimakonflikt_screenshot_thumb_1.png" width="415" height="295"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
The current release, documentation and source code can be downloaded from here &lt;a href="http://klimakonflikt.codeplex.com" target="_blank"&gt;http://klimakonflikt.codeplex.com&lt;/a&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The game is inherently for 2 players but we are working on the single player edition.
The AI in the current release is pretty daft, but in the next release it will be much
improved. Also we are working on a WPF leveleditor, powerups and other fun stuff.
&lt;/p&gt;
&lt;p&gt;
One of my co-developers Jakob has released a blog about the game and XNA development
in general at &lt;a href="http://xnafan.net" target="_blank"&gt;http://xnafan.net&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.niedermann.dk/aggbug.ashx?id=d70452c9-013d-49b4-82cc-b5290ae51893" /&gt;</description>
      <comments>http://www.niedermann.dk/CommentView,guid,d70452c9-013d-49b4-82cc-b5290ae51893.aspx</comments>
      <category>.NET</category>
      <category>Games &amp; Puzzles</category>
      <category>WPF</category>
      <category>XNA</category>
    </item>
  </channel>
</rss>