<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Tile-based RPG woes.</title>
		<link>http://www.allegro.cc/forums/view/590745</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Wed, 28 Mar 2007 23:27:33 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;m creating a tile-based RPG, it&#39;s 16*16 and I originally had it so that the caracter moved two pixels every time the D*pad was pressed. but I ran into a few problems with that,namely walking through items because it hadn&#39;t registered that the character was over it yet.  But I was wondering if anyone had any sugestions as to how I can get the carachter to still move in this way but move over 1 tile.  Just turn on your gameboy and pop in pokemon, you&#39;ll understand what I mean.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Taiko Keiji)</author>
		<pubDate>Tue, 27 Mar 2007 23:44:50 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>It&#39;s simple, character x and y position would represent map indicies instead of real coordinates.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (OICW)</author>
		<pubDate>Tue, 27 Mar 2007 23:56:26 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You just need to know how many pixels a tile is... Then you move in whatever direction that many pixels. You can either hard code it or get it directly from your BITMAP if a tile is exactly sized.</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">int</span> main<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span></td></tr><tr><td class="number">2</td><td><span class="k2">{</span></td></tr><tr><td class="number">3</td><td>    <span class="k1">int</span> intStep, x, y<span class="k2">;</span></td></tr><tr><td class="number">4</td><td>    <a href="http://www.allegro.cc/manual/BITMAP" target="_blank"><span class="a">BITMAP</span></a> <span class="k3">*</span>objTileBitmap <span class="k3">=</span> NULL<span class="k2">;</span></td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td>...</td></tr><tr><td class="number">7</td><td>&#160;</td></tr><tr><td class="number">8</td><td>    objTileBitmap <span class="k3">=</span> <a href="http://www.allegro.cc/manual/load_bitmap" target="_blank"><span class="a">load_bitmap</span></a><span class="k2">(</span><span class="s">"tile.bmp"</span>, NULL<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">9</td><td>&#160;</td></tr><tr><td class="number">10</td><td>...</td></tr><tr><td class="number">11</td><td>&#160;</td></tr><tr><td class="number">12</td><td>    intStep <span class="k3">=</span> objTileBitmap-&gt;w<span class="k2">;</span> <span class="c">// or -&gt;h or hard code it</span></td></tr><tr><td class="number">13</td><td>&#160;</td></tr><tr><td class="number">14</td><td>...</td></tr><tr><td class="number">15</td><td>&#160;</td></tr><tr><td class="number">16</td><td>    <span class="k1">while</span><span class="k2">(</span><span class="k3">!</span>keys<span class="k2">[</span>KEY_ESC<span class="k2">]</span><span class="k2">)</span></td></tr><tr><td class="number">17</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">18</td><td>       <span class="c">// Check input. Depending on which direction they input you increment</span></td></tr><tr><td class="number">19</td><td>       <span class="c">// or decrement x or y by intStep, which is the width or height of a</span></td></tr><tr><td class="number">20</td><td>       <span class="c">//tile.</span></td></tr><tr><td class="number">21</td><td>...</td></tr><tr><td class="number">22</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">23</td><td>&#160;</td></tr><tr><td class="number">24</td><td>...</td></tr><tr><td class="number">25</td><td>&#160;</td></tr><tr><td class="number">26</td><td>    <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">27</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

Keep in mind it&#39;s easier and cleaner if your character BITMAP is size of a tile also, even if there is magic pink whitespace around the outside.</p><p>Keep in mind this was a very messy example. I usually use objects to represent game objects so it&#39;s easier to keep track of relationships, etc.</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">class</span> PLAYER</td></tr><tr><td class="number">2</td><td><span class="k2">{</span></td></tr><tr><td class="number">3</td><td>private:</td></tr><tr><td class="number">4</td><td>    <span class="k1">int</span> mintX, mintY<span class="k2">;</span></td></tr><tr><td class="number">5</td><td>    <span class="k1">int</span> mintStep<span class="k2">;</span></td></tr><tr><td class="number">6</td><td>...</td></tr><tr><td class="number">7</td><td>&#160;</td></tr><tr><td class="number">8</td><td>public:</td></tr><tr><td class="number">9</td><td>&#160;</td></tr><tr><td class="number">10</td><td>...</td></tr><tr><td class="number">11</td><td>&#160;</td></tr><tr><td class="number">12</td><td>    <span class="k1">void</span> MoveRight<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span></td></tr><tr><td class="number">13</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">14</td><td>        mintX <span class="k3">+</span><span class="k3">=</span> mintStep<span class="k2">;</span></td></tr><tr><td class="number">15</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">16</td><td>&#160;</td></tr><tr><td class="number">17</td><td>...</td></tr><tr><td class="number">18</td><td>&#160;</td></tr><tr><td class="number">19</td><td><span class="k2">}</span><span class="k2">;</span></td></tr></tbody></table></div></div><p>

</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">int</span> main<span class="k2">(</span><span class="k1">void</span><span class="k2">)</span>
<span class="k2">{</span>
    PLAYER <span class="k3">*</span>objPlayer <span class="k3">=</span> <span class="k1">new</span> PLAYER<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>

...

        <span class="k1">if</span><span class="k2">(</span>keys<span class="k2">[</span>KEY_RIGHT<span class="k2">]</span><span class="k2">)</span>
        <span class="k2">{</span>
            objPlayer.MoveRight<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
        <span class="k2">}</span>

...

    <span class="k1">return</span> <span class="n">0</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Tue, 27 Mar 2007 23:59:26 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Yes but I dont want it to be so jerky, I dont want it to &quot;jump&quot; from one tile to the next. It should look like he&#39;s walking to the next tile.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Taiko Keiji)</author>
		<pubDate>Wed, 28 Mar 2007 00:03:12 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Oh, but you didn&#39;t say that.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (OICW)</author>
		<pubDate>Wed, 28 Mar 2007 00:08:26 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I imagine the easiest way to do it would be to calculate the distance (in pixels) to the next tile. Once you&#39;ve got that, just make the player move x pixels in a series of small increments.</p><p>Figure out which tile the player is currently on (the map coordinates). Then, if the player were moving right, figure out the map coordinates for the tile to the right of the player (x+1). Get the actual pixel location for that tile. Subtract the players location from that value, to give you the distance. Then simply move the player in small increments, to cover that distance.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ngiacomelli)</author>
		<pubDate>Wed, 28 Mar 2007 00:11:54 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>For this you&#39;ll need to keep track of what he&#39;s doing so in each frame you can animate and move him a bit. When he reaches the next tile you unset a variable so he stops walking.
</p><div class="quote_container"><div class="title">Taiko Keiji said:</div><div class="quote"><p>
But I was wondering if anyone had any sugestions as to how I can get the carachter to still move in this way but move over 1 tile.
</p></div></div><p>

What did you mean then? If he&#39;s still walking normally what does it matter if the map is tile based or not? Unless you mean detecting which tile he&#39;s on...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Wed, 28 Mar 2007 00:12:13 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I couldn&#39;t figure out a way for him to move 16 pixels across the screen when a button was pressed, I wanted him to walk over to the next tile when you press the key much like in pokemon when to little character moves.<br />I found a way to do it also. It&#39;s just like you said. Keep track of his screen coordinates then edit his map coordinates and move him only if his screen position isn&#39;t equal to his map position.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Taiko Keiji)</author>
		<pubDate>Wed, 28 Mar 2007 00:19:44 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If you switch your engine to something like that described in Game Coding Complete, this is easy. Basically, you should set up your actions as cooperative multitasking.</p><p>Make an interface class called Process that will add itself to a list of Processes that will be run every iteration of the loop. This makes it easy to derive from the class and implement a MoveCharacterProcess class that locks movement input while it&#39;s running and moves the character from tile to tile.</p><p>That&#39;s a neat and clean way of doing it, however it may force you to change the way you think about engine design. Regardless, you should buy that book I mentioned because it&#39;s a great resource. It&#39;s being republished again soon since demand has gotten high enough for another round of books.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kibiz0r)</author>
		<pubDate>Wed, 28 Mar 2007 00:35:41 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>If you know the distance he is supposed to travel you should also be able to just set a destination distance and decrement from it every frame. Or, for example, knowing the distance of a tile and the distance covered in a &quot;footstep&quot; (i.e. one frame) you can determine the number of footsteps required and track the distance remaining:</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td>...</td></tr><tr><td class="number">2</td><td>&#160;</td></tr><tr><td class="number">3</td><td><span class="k1">int</span> <span class="k3">*</span>intAxis<span class="k2">;</span></td></tr><tr><td class="number">4</td><td><span class="k1">int</span> intDirection<span class="k2">;</span></td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td>...</td></tr><tr><td class="number">7</td><td>&#160;</td></tr><tr><td class="number">8</td><td><span class="c">// Determine which axis you are moving and which direction on that axis.</span></td></tr><tr><td class="number">9</td><td><span class="k1">switch</span><span class="k2">(</span><span class="k1">true</span><span class="k2">)</span></td></tr><tr><td class="number">10</td><td><span class="k2">{</span></td></tr><tr><td class="number">11</td><td><span class="k1">case</span> mblnUp:</td></tr><tr><td class="number">12</td><td>    intAxis <span class="k3">=</span> <span class="k3">&amp;</span>mintY<span class="k2">;</span></td></tr><tr><td class="number">13</td><td>    intDirection <span class="k3">=</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">14</td><td>    <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">15</td><td><span class="k1">case</span> mblnLeft:</td></tr><tr><td class="number">16</td><td>    intAxis <span class="k3">=</span> <span class="k3">&amp;</span>mintX<span class="k2">;</span></td></tr><tr><td class="number">17</td><td>    intDirection <span class="k3">=</span> <span class="k3">-</span><span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">18</td><td>    <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">19</td><td><span class="k1">case</span> mblnRight:</td></tr><tr><td class="number">20</td><td>    intAxis <span class="k3">=</span> <span class="k3">&amp;</span>mintX<span class="k2">;</span></td></tr><tr><td class="number">21</td><td>    intDirection <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">22</td><td>    <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">23</td><td><span class="k1">case</span> mblnDown:</td></tr><tr><td class="number">24</td><td>    intAxis <span class="k3">=</span> <span class="k3">&amp;</span>mintY<span class="k2">;</span></td></tr><tr><td class="number">25</td><td>    intDirection <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span></td></tr><tr><td class="number">26</td><td>    <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">27</td><td><span class="k2">}</span></td></tr><tr><td class="number">28</td><td>&#160;</td></tr><tr><td class="number">29</td><td>...</td></tr><tr><td class="number">30</td><td>&#160;</td></tr><tr><td class="number">31</td><td><span class="k1">if</span><span class="k2">(</span>mintRemainingFootsteps <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span></td></tr><tr><td class="number">32</td><td><span class="k2">{</span></td></tr><tr><td class="number">33</td><td>    <span class="c">/*</span></td></tr><tr><td class="number">34</td><td><span class="c">     *  Increment/decrement x or y every frame. intAxis should point to</span></td></tr><tr><td class="number">35</td><td><span class="c">     *  x or y, depending on which axis you are moving.</span></td></tr><tr><td class="number">36</td><td><span class="c">     */</span></td></tr><tr><td class="number">37</td><td>    <span class="k3">*</span>intAxis <span class="k3">+</span><span class="k3">=</span> <span class="k2">(</span>intDirection <span class="k3">*</span> mintFootstep<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">38</td><td>&#160;</td></tr><tr><td class="number">39</td><td>    <span class="c">// Subtract a footstep every frame.</span></td></tr><tr><td class="number">40</td><td>    mintRemainingFootsteps--<span class="k2">;</span></td></tr><tr><td class="number">41</td><td><span class="k2">}</span></td></tr><tr><td class="number">42</td><td>&#160;</td></tr><tr><td class="number">43</td><td>...</td></tr></tbody></table></div></div><p>

I don&#39;t really have time to run over that... But I think it should work if it&#39;s clear enough to understand...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (bamccaig)</author>
		<pubDate>Wed, 28 Mar 2007 00:47:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>That&#39;s basically what I did.</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td><span class="k1">if</span><span class="k2">(</span><span class="k3">!</span>Moving<span class="k2">)</span><span class="c">//this tells it to only take keypresses if it isn't transitioning from</span></td></tr><tr><td class="number">2</td><td>           <span class="c">//one tile to the next.</span></td></tr><tr><td class="number">3</td><td><span class="k2">{</span></td></tr><tr><td class="number">4</td><td>   <span class="k1">if</span><span class="k2">(</span><a href="http://www.allegro.cc/manual/key" target="_blank"><span class="a">key</span></a><span class="k2">[</span>KEY_UP<span class="k2">]</span><span class="k2">)</span></td></tr><tr><td class="number">5</td><td>   <span class="k2">{</span></td></tr><tr><td class="number">6</td><td>      Direction<span class="k3">=</span>Up<span class="k2">;</span></td></tr><tr><td class="number">7</td><td>      <span class="c">//so long as the next tile isn't blocked.</span></td></tr><tr><td class="number">8</td><td>      MapPosy--<span class="k2">;</span></td></tr><tr><td class="number">9</td><td>      Moving<span class="k3">=</span><span class="k1">true</span><span class="k2">;</span></td></tr><tr><td class="number">10</td><td>   <span class="k2">}</span></td></tr><tr><td class="number">11</td><td>   <span class="k1">if</span><span class="k2">(</span><a href="http://www.allegro.cc/manual/key" target="_blank"><span class="a">key</span></a><span class="k2">[</span>KEY_LEFT<span class="k2">]</span><span class="k2">)</span></td></tr><tr><td class="number">12</td><td>   <span class="k2">{</span></td></tr><tr><td class="number">13</td><td>      Direction<span class="k3">=</span>Left<span class="k2">;</span></td></tr><tr><td class="number">14</td><td>      <span class="c">//same thing</span></td></tr><tr><td class="number">15</td><td>      MapPosx--<span class="k2">;</span></td></tr><tr><td class="number">16</td><td>      Moving<span class="k3">=</span><span class="k1">true</span><span class="k2">;</span></td></tr><tr><td class="number">17</td><td>   <span class="k2">}</span></td></tr><tr><td class="number">18</td><td>   <span class="c">//you get it by now</span></td></tr><tr><td class="number">19</td><td><span class="k2">}</span></td></tr><tr><td class="number">20</td><td><span class="k1">if</span><span class="k2">(</span>Moving<span class="k2">)</span></td></tr><tr><td class="number">21</td><td><span class="k2">{</span></td></tr><tr><td class="number">22</td><td>   <span class="k1">if</span><span class="k2">(</span>ScreenPosx&gt;MapPosx<span class="k2">)</span></td></tr><tr><td class="number">23</td><td>      ScreenPosx--<span class="k2">;</span></td></tr><tr><td class="number">24</td><td>   <span class="k1">if</span><span class="k2">(</span>ScreenPosx<span class="k3">&lt;</span>MapPosx<span class="k2">)</span></td></tr><tr><td class="number">25</td><td>      ScreenPosx<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span></td></tr><tr><td class="number">26</td><td>   <span class="k1">if</span><span class="k2">(</span>ScreenPosy&gt;MapPosy<span class="k2">)</span></td></tr><tr><td class="number">27</td><td>      ScreenPosy--<span class="k2">;</span></td></tr><tr><td class="number">28</td><td>   <span class="k1">if</span><span class="k2">(</span>ScreenPosy<span class="k3">&lt;</span>MapPosy<span class="k2">)</span></td></tr><tr><td class="number">29</td><td>      ScreenPosy<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span></td></tr><tr><td class="number">30</td><td>   <span class="k1">if</span><span class="k2">(</span>anim<span class="k3">!</span><span class="k3">=</span>AnimationTiemr<span class="k2">)</span></td></tr><tr><td class="number">31</td><td>   <span class="k2">{</span></td></tr><tr><td class="number">32</td><td>      CurFrame<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span></td></tr><tr><td class="number">33</td><td>      <span class="k1">if</span><span class="k2">(</span>CurFrame&gt;<span class="k3">=</span>NumFrames<span class="k2">)</span></td></tr><tr><td class="number">34</td><td>         Reset_Frame<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">35</td><td>      anim<span class="k3">=</span>AnimationTimer<span class="k2">;</span></td></tr><tr><td class="number">36</td><td>   <span class="k2">}</span></td></tr><tr><td class="number">37</td><td>   <span class="k1">if</span><span class="k2">(</span>ScreenPosx<span class="k3">=</span><span class="k3">=</span>MapPosx<span class="k3">&amp;</span><span class="k3">&amp;</span>ScreenPosy<span class="k3">=</span><span class="k3">=</span>MapPosy<span class="k2">)</span></td></tr><tr><td class="number">38</td><td>      Moving<span class="k3">=</span><span class="k1">false</span><span class="k2">;</span></td></tr><tr><td class="number">39</td><td><span class="k2">}</span></td></tr><tr><td class="number">40</td><td>GameEngine1.Draw_Screen<span class="k2">(</span>buffer<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">41</td><td><span class="c">//goes back to the main game loop.</span></td></tr></tbody></table></div></div><p>

obviously this isn&#39;t the actual code but it works the same way.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Taiko Keiji)</author>
		<pubDate>Wed, 28 Mar 2007 23:27:33 +0000</pubDate>
	</item>
</rss>
