<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>Solid Collision &quot;Sliding&quot; (Man, I&#39;m bad at explaining things)</title>
		<link>http://www.allegro.cc/forums/view/612101</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Sun, 24 Feb 2013 10:43:29 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hello. I&#39;ve been working towards achieving an effect in which, should a player hit a solid object, they can slide passed it, despite them pressing more than one arrow key. For example, say you&#39;re going up to the right and you hit a solid object from the bottom; well, stop moving up and begin just sliding to the right instead. A lot of top-down video games have this functionality, but I am having difficulties achieving it.</p><p>I have two integers: dirX and dirY; each of which corresponds to the player&#39;s X and Y positions (dirX = 1 is right; dirX = -1 is left; dirX = 0 is no x movement; dirY = 1 is down; dirY = -1 is up; dirY = 0 is no Y movement). Here&#39;s my current code for what to do upon hitting a solid object:</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">void</span> Player::hitSolid<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  2</span>
<span class="number">  3</span>  <span class="k1">if</span> <span class="k2">(</span>dirX <span class="k3">=</span><span class="k3">=</span> <span class="k3">-</span><span class="n">1</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  4</span>
<span class="number">  5</span>    x <span class="k3">+</span><span class="k3">=</span> speed<span class="k2">;</span>
<span class="number">  6</span>  <span class="k2">}</span>
<span class="number">  7</span>  <span class="k1">else</span> <span class="k1">if</span> <span class="k2">(</span>dirX <span class="k3">=</span><span class="k3">=</span> <span class="n">1</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  8</span>
<span class="number">  9</span>    x <span class="k3">-</span><span class="k3">=</span> speed<span class="k2">;</span>
<span class="number"> 10</span>  <span class="k2">}</span>
<span class="number"> 11</span>
<span class="number"> 12</span>  <span class="k1">if</span> <span class="k2">(</span>dirY <span class="k3">=</span><span class="k3">=</span> <span class="n">1</span> <span class="k3">&amp;</span><span class="k3">&amp;</span> dirX <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 13</span>
<span class="number"> 14</span>    y <span class="k3">-</span><span class="k3">=</span> speed<span class="k2">;</span>
<span class="number"> 15</span>  <span class="k2">}</span>
<span class="number"> 16</span>  <span class="k1">else</span> <span class="k1">if</span> <span class="k2">(</span>dirY <span class="k3">=</span><span class="k3">=</span> <span class="k3">-</span><span class="n">1</span> <span class="k3">&amp;</span><span class="k3">&amp;</span> dirX <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 17</span>
<span class="number"> 18</span>    y <span class="k3">+</span><span class="k3">=</span> speed<span class="k2">;</span>
<span class="number"> 19</span>  <span class="k2">}</span>
<span class="number"> 20</span>
<span class="number"> 21</span><span class="k2">}</span>
</div></div><p>

The main issue with this is that it will not allow you to slide around objects as mentioned above. Instead, if you collide, it locks up until you release the key that is holding you back. I did find a partial solution however...</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span><span class="k1">void</span> Player::hitSolid<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  2</span>
<span class="number">  3</span>  <span class="k1">if</span> <span class="k2">(</span>dirY <span class="k3">=</span><span class="k3">=</span> <span class="n">1</span> <span class="k3">&amp;</span><span class="k3">&amp;</span> dirX <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  4</span>
<span class="number">  5</span>    y <span class="k3">-</span><span class="k3">=</span> speed<span class="k2">;</span>
<span class="number">  6</span>  <span class="k2">}</span>
<span class="number">  7</span>  <span class="k1">else</span> <span class="k1">if</span> <span class="k2">(</span>dirY <span class="k3">=</span><span class="k3">=</span> <span class="k3">-</span><span class="n">1</span> <span class="k3">&amp;</span><span class="k3">&amp;</span> dirX <span class="k3">=</span><span class="k3">=</span> <span class="n">0</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number">  8</span>
<span class="number">  9</span>    y <span class="k3">+</span><span class="k3">=</span> speed<span class="k2">;</span>
<span class="number"> 10</span>  <span class="k2">}</span>
<span class="number"> 11</span>
<span class="number"> 12</span>  <span class="k1">if</span> <span class="k2">(</span>dirX <span class="k3">=</span><span class="k3">=</span> <span class="k3">-</span><span class="n">1</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 13</span>
<span class="number"> 14</span>    x <span class="k3">+</span><span class="k3">=</span> speed<span class="k2">;</span>
<span class="number"> 15</span>  <span class="k2">}</span>
<span class="number"> 16</span>  <span class="k1">else</span> <span class="k1">if</span> <span class="k2">(</span>dirX <span class="k3">=</span><span class="k3">=</span> <span class="n">1</span><span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 17</span>
<span class="number"> 18</span>    x <span class="k3">-</span><span class="k3">=</span> speed<span class="k2">;</span>
<span class="number"> 19</span>  <span class="k2">}</span>
<span class="number"> 20</span>
<span class="number"> 21</span><span class="k2">}</span>
</div></div><p>

This would allow me to slide on the left and right sides of the collided object (the function is called after confirming a collision of a specific tile, mind you). I haven&#39;t yet had any luck getting it to allow the player to slide on the top and bottom sides of the object though. Do you have any input? Thank you.</p><p>PS: This is for a top-down game, so there is no velocity involved.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Eric Johnson)</author>
		<pubDate>Sat, 23 Feb 2013 12:19:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I see no difference between those examples; they are the same equations, simply reordered.</p><p>Just for clarification, is this what you&#39;re seeing, and trying to remedy?</p><p>So if I have this object:
</p><div class="source-code snippet"><div class="inner"><pre>    xxxxx
    xxxxx
    xxxxx
</pre></div></div><p>
and my colliding object is calculated to be here:
</p><div class="source-code snippet"><div class="inner"><pre>    xxxxx
    xxxxx
    xxxxx

    <span class="n">0</span>
</pre></div></div><p>
then I first try to move <b>up</b>:
</p><div class="source-code snippet"><div class="inner"><pre>    xxxxx
    xxxxx
    xxxxx
    <span class="n">0</span>      <span class="k3">&lt;</span><span class="k3">-</span><span class="k3">-</span> success
</pre></div></div><p>
Next, I try to move <b>right</b>:
</p><div class="source-code snippet"><div class="inner"><pre>    xxxxx
    xxxxx
    xxxxx
     <span class="n">0</span>     <span class="k3">&lt;</span><span class="k3">-</span><span class="k3">-</span> success
</pre></div></div><p>
Now I&#39;m on my next update loop. I am at this:
</p><div class="source-code snippet"><div class="inner"><pre>    xxxxx
    xxxxx
    xxxxx
     <span class="n">0</span>
</pre></div></div><p>
and try to move <b>up</b>. Since I can&#39;t, I stay there:
</p><div class="source-code snippet"><div class="inner"><pre>    xxxxx
    xxxxx
    xxxxx
     <span class="n">0</span>     <span class="k3">&lt;</span><span class="k3">-</span><span class="k3">-</span> failed, still in <span class="k1">this</span> position
</pre></div></div><p>
Then I try to move <b>right</b>:
</p><div class="source-code snippet"><div class="inner"><pre>    xxxxx
    xxxxx
    xxxxx
      <span class="n">0</span>    <span class="k3">&lt;</span><span class="k3">-</span><span class="k3">-</span> success
</pre></div></div><p>
If I repeat those last 2 moves, I am now here:
</p><div class="source-code snippet"><div class="inner"><pre>    xxxxx
    xxxxx
    xxxxx
        <span class="n">0</span>  <span class="k3">&lt;</span><span class="k3">-</span><span class="k3">-</span> here now
</pre></div></div><p>
What you&#39;re probably seeing is that on the next round, where you would expect my character to be able to move from:
</p><div class="source-code snippet"><div class="inner"><pre>    xxxxx
    xxxxx
    xxxxx
        <span class="n">0</span>  <span class="k3">&lt;</span><span class="k3">-</span><span class="k3">-</span> here
</pre></div></div><p>
to
</p><div class="source-code snippet"><div class="inner"><pre>    xxxxx
    xxxxx
    xxxxx0 <span class="k3">&lt;</span><span class="k3">-</span><span class="k3">-</span> here
</pre></div></div><p>
is that my character cannot move <b>up</b>, but it can move <b>right</b>:
</p><div class="source-code snippet"><div class="inner"><pre>    xxxxx
    xxxxx
    xxxxx
         <span class="n">0</span> <span class="k3">&lt;</span><span class="k3">-</span><span class="k3">-</span> here
</pre></div></div><p>
and it&#39;s not until the next update that I can start moving diagonally again:
</p><div class="source-code snippet"><div class="inner"><pre>    xxxxx
    xxxxx
    xxxxx <span class="n">0</span> <span class="k3">&lt;</span><span class="k3">-</span><span class="k3">-</span> probably one space further right than you anticipated
</pre></div></div><p>

Is that what you&#39;re seeing and trying to fix, or something else?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (OnlineCop)</author>
		<pubDate>Sat, 23 Feb 2013 13:01:46 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;m a little confused by the two code blocks you posted, since they&#39;re functionally the same (but apparently only the second one is supposed to work?). Originally I thought you were talking about rolling around corners (ie- holding left, player hits obstacle, automatically moves one tile up without having to press up, continues left past obstacle), but I&#39;m thinking now you&#39;re talking about not &quot;undoing&quot; both horizontal and vertical movement when hitting an object, only undoing the one that caused the collision.</p><p>The reason you aren&#39;t sliding from the top or bottom is because you are always undoing your horizontal movement, no matter what, when you call <span class="source-code">hitSolid</span>. Basically, instead of undoing all movements, you need to figure out whether you hit the obstacle horizontally or vertically and only undo the appropriate movement. Then you can hold up+left, hit something from the bottom, continue moving left but don&#39;t continue up until you&#39;re past the obstacle.</p><p>Ultimately your code should be something like:
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">void</span> Player::hitSolid<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span>
   <span class="c">///TODO figure out what side the hit was</span>

   <span class="k1">if</span> <span class="k2">(</span>CollisionFromTop <span class="k3">|</span><span class="k3">|</span> CollisionFromBottom<span class="k2">)</span> <span class="k2">{</span>
      y <span class="k3">+</span><span class="k3">=</span> <span class="k3">-</span>dirY<span class="k3">*</span>speed<span class="k2">;</span> <span class="c">// undo vert movement</span>
   <span class="k2">}</span>
   <span class="c">// if you want to block corner collisions rather than just going a direction,</span>
   <span class="c">// these aren't mutually exclusive</span>
   <span class="k1">else</span> <span class="k2">{</span>
      x <span class="k3">+</span><span class="k3">=</span> <span class="k3">-</span>dirX<span class="k3">*</span>speed<span class="k2">;</span> <span class="c">// undo horiz movement</span>
   <span class="k2">}</span>
<span class="k2">}</span>
</pre></div></div><p>

As for figuring out what side the collision was, it&#39;s trivial if you were only moving in one direction. Otherwise (if the speed is less than the player/obstacle&#39;s sizes), you can measure the differences of each object&#39;s corresponding edges (ie- player&#39;s left side to obstacles right side, player&#39;s top to obstacle&#39;s bottom), and the minimum magnitude difference is where the collision occurred. If a horizontal and vertical difference tie for minimum, then you hit a corner and you can either undo both movements, or just pick one direction to dominate the other.</p><p>I don&#39;t know how you&#39;re doing collision detection, but you may run into issues trying to slide across multiple adjacent tiles, getting false corner collisions...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Jeff Bernard)</author>
		<pubDate>Sat, 23 Feb 2013 13:20:18 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>OnlineCop, I&#39;m trying to do this: once you hit a solid object, you won&#39;t be able to go any further in the direction that you hit the object from. So if you&#39;re going up to the right and hit the bottom of an object, prevent the player from going up any further, but allow them to move to the left or the right, because nothing is blocking their path there.</p><p>Jeff Bernard, your code works well for being able to slide around the top and bottom of object, but I&#39;m still having difficulties with the left and right sides (it allows me to pass through them if I am holding a vertical arrow key as well as a horizontal one). I was having this issue before, where I could only achieve the effect on two of the four sides, but not all of them. Also, I am using bounding box collision.</p><p>I appreciate the responses guys. <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Eric Johnson)</author>
		<pubDate>Sat, 23 Feb 2013 22:58:03 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The only other suggestion I would have it to, instead of merely undoing the last movement, actually move the player to next to the obstacle.</p><p>That&#39;s what I do in my game, using the method of determining the side of a collision I described earlier and it works fine. For the interested here&#39;s the code (like yours, this function is only called once a collision, ie- overlapping bounding boxes, is detected). In this code I ignore collisions between mobile sprites (ie- if two objects can both move, they can move through each other), and only care about collisions between sprites that can and can&#39;t move (ie- a moving sprite can&#39;t move through a stationary wall), so <span class="source-code">objI</span> would correspond to your obstacle and <span class="source-code">objJ</span> would correspond to your player:</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">   1</span><span class="k1">void</span> CollisionHandler::check<span class="k2">(</span>lp::Object<span class="k3">*</span> objI, lp::Object<span class="k3">*</span> objJ<span class="k2">)</span>
<span class="number">   2</span><span class="k2">{</span>
<span class="number">   3</span>    <span class="c">// works well enough for simple games with few collidables</span>
<span class="number">   4</span>    <span class="c">///TODO profile with many collidable objects</span>
<span class="number">   5</span>    <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>objI-&gt;isMobile<span class="k2">(</span><span class="k2">)</span> <span class="k3">&amp;</span><span class="k3">&amp;</span> objJ-&gt;isMobile<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span> <span class="c">// only handle valid collisions</span>
<span class="number">   6</span>    <span class="k2">{</span>
<span class="number">   7</span>        <span class="k1">int</span> edge <span class="k3">=</span> FROM_TOP<span class="k2">;</span>
<span class="number">   8</span>
<span class="number">   9</span>        <span class="k1">float</span> xi <span class="k3">=</span> objI-&gt;getPosition<span class="k2">(</span><span class="k2">)</span>.getX<span class="k2">(</span><span class="k2">)</span><span class="k3">+</span>myl::Sprite::PADDING<span class="k2">;</span>
<span class="number">  10</span>        <span class="k1">float</span> yi <span class="k3">=</span> objI-&gt;getPosition<span class="k2">(</span><span class="k2">)</span>.getY<span class="k2">(</span><span class="k2">)</span><span class="k3">+</span>myl::Sprite::PADDING<span class="k2">;</span>
<span class="number">  11</span>        <span class="k1">float</span> xj <span class="k3">=</span> objJ-&gt;getPosition<span class="k2">(</span><span class="k2">)</span>.getX<span class="k2">(</span><span class="k2">)</span><span class="k3">+</span>myl::Sprite::PADDING<span class="k2">;</span>
<span class="number">  12</span>        <span class="k1">float</span> yj <span class="k3">=</span> objJ-&gt;getPosition<span class="k2">(</span><span class="k2">)</span>.getY<span class="k2">(</span><span class="k2">)</span><span class="k3">+</span>myl::Sprite::PADDING<span class="k2">;</span>
<span class="number">  13</span>
<span class="number">  14</span>        <span class="k1">int</span> wi <span class="k3">=</span> objI-&gt;getWidth<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span>myl::Sprite::PADDING<span class="k3">*</span><span class="n">2</span><span class="k2">;</span>
<span class="number">  15</span>        <span class="k1">int</span> hi <span class="k3">=</span> objI-&gt;getHeight<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span>myl::Sprite::PADDING<span class="k3">*</span><span class="n">2</span><span class="k2">;</span>
<span class="number">  16</span>        <span class="k1">int</span> wj <span class="k3">=</span> objJ-&gt;getWidth<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span>myl::Sprite::PADDING<span class="k3">*</span><span class="n">2</span><span class="k2">;</span>
<span class="number">  17</span>        <span class="k1">int</span> hj <span class="k3">=</span> objJ-&gt;getHeight<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span>myl::Sprite::PADDING<span class="k3">*</span><span class="n">2</span><span class="k2">;</span>
<span class="number">  18</span>
<span class="number">  19</span>        <span class="k1">float</span> left <span class="k3">=</span> xj<span class="k3">+</span>wj-xi<span class="k2">;</span>
<span class="number">  20</span>        <span class="k1">float</span> right <span class="k3">=</span> xi<span class="k3">+</span>wi-xj<span class="k2">;</span>
<span class="number">  21</span>        <span class="k1">float</span> top <span class="k3">=</span> yj<span class="k3">+</span>hj-yi<span class="k2">;</span>
<span class="number">  22</span>        <span class="k1">float</span> bottom <span class="k3">=</span> yi<span class="k3">+</span>hi-yj<span class="k2">;</span>
<span class="number">  23</span>
<span class="number">  24</span>        <span class="k1">bool</span> topOverBottom <span class="k3">=</span> top <span class="k3">&lt;</span> bottom<span class="k2">;</span>
<span class="number">  25</span>        <span class="k1">bool</span> rightOverLeft <span class="k3">=</span> right <span class="k3">&lt;</span> left<span class="k2">;</span>
<span class="number">  26</span>        <span class="k1">if</span> <span class="k2">(</span>topOverBottom<span class="k2">)</span>
<span class="number">  27</span>        <span class="k2">{</span>
<span class="number">  28</span>            <span class="k1">if</span> <span class="k2">(</span>rightOverLeft<span class="k2">)</span>
<span class="number">  29</span>            <span class="k2">{</span>
<span class="number">  30</span>                <span class="k1">if</span> <span class="k2">(</span>top <span class="k3">&lt;</span> right<span class="k2">)</span>
<span class="number">  31</span>                <span class="k2">{</span>
<span class="number">  32</span>                    edge <span class="k3">=</span> FROM_TOP<span class="k2">;</span>
<span class="number">  33</span>                <span class="k2">}</span>
<span class="number">  34</span>                <span class="k1">else</span>
<span class="number">  35</span>                <span class="k2">{</span>
<span class="number">  36</span>                    edge <span class="k3">=</span> FROM_RIGHT<span class="k2">;</span>
<span class="number">  37</span>                <span class="k2">}</span>
<span class="number">  38</span>            <span class="k2">}</span>
<span class="number">  39</span>            <span class="k1">else</span>
<span class="number">  40</span>            <span class="k2">{</span>
<span class="number">  41</span>                <span class="k1">if</span> <span class="k2">(</span>top <span class="k3">&lt;</span> left<span class="k2">)</span>
<span class="number">  42</span>                <span class="k2">{</span>
<span class="number">  43</span>                    edge <span class="k3">=</span> FROM_TOP<span class="k2">;</span>
<span class="number">  44</span>                <span class="k2">}</span>
<span class="number">  45</span>                <span class="k1">else</span>
<span class="number">  46</span>                <span class="k2">{</span>
<span class="number">  47</span>                    edge <span class="k3">=</span> FROM_LEFT<span class="k2">;</span>
<span class="number">  48</span>                <span class="k2">}</span>
<span class="number">  49</span>            <span class="k2">}</span>
<span class="number">  50</span>        <span class="k2">}</span>
<span class="number">  51</span>        <span class="k1">else</span>
<span class="number">  52</span>        <span class="k2">{</span>
<span class="number">  53</span>            <span class="k1">if</span> <span class="k2">(</span>rightOverLeft<span class="k2">)</span>
<span class="number">  54</span>            <span class="k2">{</span>
<span class="number">  55</span>                <span class="k1">if</span> <span class="k2">(</span>bottom <span class="k3">&lt;</span> right<span class="k2">)</span>
<span class="number">  56</span>                <span class="k2">{</span>
<span class="number">  57</span>                    edge <span class="k3">=</span> FROM_BOTTOM<span class="k2">;</span>
<span class="number">  58</span>                <span class="k2">}</span>
<span class="number">  59</span>                <span class="k1">else</span>
<span class="number">  60</span>                <span class="k2">{</span>
<span class="number">  61</span>                    edge <span class="k3">=</span> FROM_RIGHT<span class="k2">;</span>
<span class="number">  62</span>                <span class="k2">}</span>
<span class="number">  63</span>            <span class="k2">}</span>
<span class="number">  64</span>            <span class="k1">else</span>
<span class="number">  65</span>            <span class="k2">{</span>
<span class="number">  66</span>                <span class="k1">if</span> <span class="k2">(</span>bottom <span class="k3">&lt;</span> left<span class="k2">)</span>
<span class="number">  67</span>                <span class="k2">{</span>
<span class="number">  68</span>                    edge <span class="k3">=</span> FROM_BOTTOM<span class="k2">;</span>
<span class="number">  69</span>                <span class="k2">}</span>
<span class="number">  70</span>                <span class="k1">else</span>
<span class="number">  71</span>                <span class="k2">{</span>
<span class="number">  72</span>                    edge <span class="k3">=</span> FROM_LEFT<span class="k2">;</span>
<span class="number">  73</span>                <span class="k2">}</span>
<span class="number">  74</span>            <span class="k2">}</span>
<span class="number">  75</span>        <span class="k2">}</span>
<span class="number">  76</span>
<span class="number">  77</span>        <span class="c">// prevent actually passing through things</span>
<span class="number">  78</span>        <span class="c">// and use velocity to handle corner collisions</span>
<span class="number">  79</span>        <span class="c">///TODO don't create objects in game loop when you don't have to</span>
<span class="number">  80</span>        <span class="k1">switch</span> <span class="k2">(</span>edge<span class="k2">)</span>
<span class="number">  81</span>        <span class="k2">{</span>
<span class="number">  82</span>        <span class="k1">case</span> FROM_TOP:
<span class="number">  83</span>            <span class="k1">if</span> <span class="k2">(</span>objJ-&gt;getVelocity<span class="k2">(</span><span class="k2">)</span>.getY<span class="k2">(</span><span class="k2">)</span> <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span>
<span class="number">  84</span>            <span class="k2">{</span>
<span class="number">  85</span>                objJ-&gt;move<span class="k2">(</span>lp::Vector<span class="k2">(</span><span class="n">0</span>, yi-yj-hj-myl::Sprite::PADDING-1<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  86</span>            <span class="k2">}</span>
<span class="number">  87</span>            <span class="k1">break</span><span class="k2">;</span>
<span class="number">  88</span>        <span class="k1">case</span> FROM_BOTTOM:
<span class="number">  89</span>            <span class="k1">if</span> <span class="k2">(</span>objJ-&gt;getVelocity<span class="k2">(</span><span class="k2">)</span>.getY<span class="k2">(</span><span class="k2">)</span> <span class="k3">&lt;</span> <span class="n">0</span><span class="k2">)</span>
<span class="number">  90</span>            <span class="k2">{</span>
<span class="number">  91</span>                objJ-&gt;move<span class="k2">(</span>lp::Vector<span class="k2">(</span><span class="n">0</span>, yi<span class="k3">+</span>hi-yj<span class="k3">+</span><span class="n">1</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  92</span>            <span class="k2">}</span>
<span class="number">  93</span>            <span class="k1">break</span><span class="k2">;</span>
<span class="number">  94</span>        <span class="k1">case</span> FROM_LEFT:
<span class="number">  95</span>            <span class="k1">if</span> <span class="k2">(</span>objJ-&gt;getVelocity<span class="k2">(</span><span class="k2">)</span>.getX<span class="k2">(</span><span class="k2">)</span> <span class="k3">&gt;</span> <span class="n">0</span><span class="k2">)</span>
<span class="number">  96</span>            <span class="k2">{</span>
<span class="number">  97</span>                objJ-&gt;move<span class="k2">(</span>lp::Vector<span class="k2">(</span>xi-xj-wj-myl::Sprite::PADDING-1, <span class="n">0</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number">  98</span>            <span class="k2">}</span>
<span class="number">  99</span>            <span class="k1">break</span><span class="k2">;</span>
<span class="number"> 100</span>        <span class="k1">case</span> FROM_RIGHT:
<span class="number"> 101</span>            <span class="k1">if</span> <span class="k2">(</span>objJ-&gt;getVelocity<span class="k2">(</span><span class="k2">)</span>.getX<span class="k2">(</span><span class="k2">)</span> <span class="k3">&lt;</span> <span class="n">0</span><span class="k2">)</span>
<span class="number"> 102</span>            <span class="k2">{</span>
<span class="number"> 103</span>                objJ-&gt;move<span class="k2">(</span>lp::Vector<span class="k2">(</span>xi<span class="k3">+</span>wi-xj<span class="k3">+</span><span class="n">1</span>, <span class="n">0</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="number"> 104</span>            <span class="k2">}</span>
<span class="number"> 105</span>            <span class="k1">break</span><span class="k2">;</span>
<span class="number"> 106</span>        <span class="k2">}</span>
<span class="number"> 107</span>    <span class="k2">}</span>
<span class="number"> 108</span><span class="k2">}</span>
</div></div><p>
(Some clarification, my code assumes objects have bounding boxes, but my physics engine has no notion of bounding boxes, per se, rather bounding shapes are a collection of vertices and the separating axis thereon is used to determine collisions, so that&#39;s why I don&#39;t get the object&#39;s bounding box directly (you can&#39;t), instead I calculate it on the fly based on the conventions of my current game.)
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Jeff Bernard)</author>
		<pubDate>Sun, 24 Feb 2013 00:51:37 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You have to do intercept times and find out which edge collided first.<br />d = r*t (distance = rate * time)<br />t = d/r</p><p>1. Find relative velocity of one rectangle to another (leader, and collider).<br />2. Find leading edges of leader, and colliding edges of collider.<br />3. Find x-intercept times<br />4. Find y ranges of edges in 2 at times in 3.<br />5. If range overlaps, x-collision at that time.<br />6-8. Repeats steps for y-intercept times, x ranges, and y collision.<br />9. Find earliest positive, and possibly simultaneous, collision time(s), disregarding negative collision times as they happened in the past.<br />10. Advance time to that point, ceasing velocity in the direction of the collision, and placing the objects right next to each other along that edge. It will temporarily slow down the object but it should slide after that, like down a wall.</p><p>I won&#39;t write the code out for you, but this basic premise works. Also, you should only perform 10) after you have checked against each possible colliding object. Because the collision should stop after the earliest one.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Edgar Reynaldo)</author>
		<pubDate>Sun, 24 Feb 2013 09:51:25 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Assuming you&#39;re working with axis-aligned (non-rotated) rectangles, the solution is easy.</p><p>Pseudocode:
</p><div class="source-code"><div class="toolbar"><span class="button numbers"><b>#</b></span><span class="button select">Select</span><span class="button expand">Expand</span></div><div class="inner"><span class="number">  1</span>resolveCollision<span class="k2">(</span>object1, object2<span class="k2">)</span> <span class="k2">{</span>
<span class="number">  2</span>  <span class="k1">if</span> <span class="k2">(</span>object1.getRightEdge<span class="k2">(</span><span class="k2">)</span> <span class="k3">&lt;</span> object2.getLeftEdge<span class="k2">(</span><span class="k2">)</span> <span class="k3">|</span><span class="k3">|</span> object1.getLeftEdge<span class="k2">(</span><span class="k2">)</span> <span class="k3">&gt;</span> object2.getRightEdge<span class="k2">(</span><span class="k2">)</span> <span class="k3">|</span><span class="k3">|</span> object1.getTopEdge<span class="k2">(</span><span class="k2">)</span> <span class="k3">&gt;</span> object2.getBottomEdge<span class="k2">(</span><span class="k2">)</span> <span class="k3">|</span><span class="k3">|</span> object1.getBottomEdge<span class="k2">(</span><span class="k2">)</span> <span class="k3">&lt;</span> object2.getTopEdge<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span> <span class="k1">return</span><span class="k2">;</span> <span class="c">//objects are not colliding, so do nothing</span>
<span class="number">  3</span>  
<span class="number">  4</span>  dx <span class="k3">=</span> object2.x <span class="k3">-</span> object1.x
<span class="number">  5</span>  dy <span class="k3">=</span> object2.y <span class="k3">-</span> object1.y
<span class="number">  6</span>  
<span class="number">  7</span>  <span class="k1">if</span> <span class="k2">(</span>object1.can_move <span class="k3">&amp;</span><span class="k3">&amp;</span> <span class="k3">!</span>object2.can_move<span class="k2">)</span> <span class="k2">{</span>
<span class="number">  8</span>    <span class="c">//push object1 out of object2 in the distance of least penetration.</span>
<span class="number">  9</span>    <span class="k1">if</span> <span class="k2">(</span>dx <span class="k3">&lt;</span> dy<span class="k2">)</span> object1.x <span class="k3">+</span><span class="k3">=</span> dx
<span class="number"> 10</span>    <span class="k1">else</span> object1.y <span class="k3">+</span><span class="k3">=</span> dy
<span class="number"> 11</span>  <span class="k2">}</span>
<span class="number"> 12</span>  
<span class="number"> 13</span>  <span class="k1">if</span> <span class="k2">(</span><span class="k3">!</span>object1.can_move <span class="k3">&amp;</span><span class="k3">&amp;</span> object2.can_move<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 14</span>    <span class="c">//push object2 out of object1 in the distance of least penetration.</span>
<span class="number"> 15</span>    <span class="k1">if</span> <span class="k2">(</span>dx <span class="k3">&lt;</span> dy<span class="k2">)</span> object2.x <span class="k3">-</span><span class="k3">=</span> dx
<span class="number"> 16</span>    <span class="k1">else</span> object2.y <span class="k3">-</span><span class="k3">=</span> dy
<span class="number"> 17</span>  <span class="k2">}</span>
<span class="number"> 18</span>  
<span class="number"> 19</span>  <span class="k1">if</span> <span class="k2">(</span>object1.can_move <span class="k3">&amp;</span><span class="k3">&amp;</span> object2.can_move<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 20</span>    <span class="c">//push both objects out of each other in the distance of least penetration.</span>
<span class="number"> 21</span>    <span class="k1">if</span> <span class="k2">(</span>dx <span class="k3">&lt;</span> dy<span class="k2">)</span> <span class="k2">{</span>
<span class="number"> 22</span>      object1.x <span class="k3">+</span><span class="k3">=</span> dx <span class="k3">/</span> <span class="n">2</span>
<span class="number"> 23</span>      object2.x <span class="k3">-</span><span class="k3">=</span> dx <span class="k3">/</span> <span class="n">2</span>
<span class="number"> 24</span>    <span class="k2">}</span> <span class="k1">else</span> <span class="k2">{</span>
<span class="number"> 25</span>      object1.x <span class="k3">+</span><span class="k3">=</span> dx <span class="k3">/</span> <span class="n">2</span>
<span class="number"> 26</span>      object2.y <span class="k3">-</span><span class="k3">=</span> dy <span class="k3">/</span> <span class="n">2</span>
<span class="number"> 27</span>    <span class="k2">}</span>
<span class="number"> 28</span>  <span class="k2">}</span>
<span class="number"> 29</span><span class="k2">}</span>
</div></div><p>
Disclaimer: I&#39;m really tired, so I might have mixed the signs up or made some other typo. But the idea is there. It works because the rectangles can&#39;t possibly be colliding if one of those edges isn&#39;t past its opposite partner. So by ruling all those cases out, what&#39;s left is only rectangles that collide.</p><p>How you implement <span class="source-code">getLeftEdge</span>, <span class="source-code">getRightEdge</span>, <span class="source-code">getTopEdge</span>, and <span class="source-code">getBottomEdge</span> is up to you, but presumably it would be something like:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">float</span> Object::getLeftEdge<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span>
  <span class="k1">return</span> x <span class="k3">-</span> sprite_width <span class="k3">/</span> <span class="n">2</span><span class="k2">;</span>
<span class="k2">}</span>

<span class="c">//similar functions for other edges</span>
</pre></div></div><p>

In the end, code like this should allow &quot;sliding&quot; along walls.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Schyfis)</author>
		<pubDate>Sun, 24 Feb 2013 10:43:29 +0000</pubDate>
	</item>
</rss>
