<?xml version="1.0"?>
<rss version="2.0">
	<channel>
		<title>collision handling</title>
		<link>http://www.allegro.cc/forums/view/589914</link>
		<description>Allegro.cc Forum Thread</description>
		<webMaster>matthew@allegro.cc (Matthew Leverton)</webMaster>
		<lastBuildDate>Sun, 18 Feb 2007 15:24:38 +0000</lastBuildDate>
	</channel>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Hi Allegators!</p><p>I have a problem on how to implement the collision handling in my game in a good style. Let&#39;s say I have a class CObject, a class CCollidingObject and furthermore the classes CShip, CPowerup, and CBullet. I think the names are pretty self-explanatory. Anyway the class hierarchy is like this:</p><p>CObject<br />   |<br />CCollidingObject<br />   |<br />CBullet, CShip, CPowerup</p><p>Now, I have a singleton-class which stores a list to all CCollidingObjects. The collision-detection is not the problem. What I need help with is where to respond on a collision. I have thought up two different approaches:</p><p>1.) Every CCollidingObject has a virtual method called &quot;collided_with(CCollidingObject* object)&quot; where the collision is handled. My problem with this is, that I will probably need to make downcasts to the specific classes. For example, if the player&#39;s ship collides with a power-up, the method needs to downcast to see if the object is a CPowerup and if it is, do the correct thing (gain hull energy or health, give more ammo, ...) I really don&#39;t like this approach because of the downcasts and I will most probably run into include-loops. <img src="http://www.allegro.cc/forums/smileys/sad.gif" alt=":(" /></p><p>2.) The collisions are handled somewhere global in one place. The downside with this is, that I will also need downcasts to call the specific methods (like decrease_health(), destroy() or the like) and I would also need to make all these methods public. <img src="http://www.allegro.cc/forums/smileys/sad.gif" alt=":(" /></p><p>I would like you to give me advice on how to resolve this. Is there a cleaner way (without downcasts at best) to do this? How would you do this?</p><p>Thank you for your time!
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (imaxcs)</author>
		<pubDate>Mon, 05 Feb 2007 21:14:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I&#39;m not an expert in OOP... yet... but I think if you want to stay fully OOP compliant, you may be stuck with having to downcast.</p><p>Though my approach with my game engine was to reduce collision detection to a process only some objects can initiate and which only the base class information is distributed in the process. The base class objects store enough basic information that knowing specifics about any particular derived class would be unnecessary. When the two objects collide, each object should primarily affect its OWN status, not each other&#39;s, beyond the basics.</p><p>Thus the level within the class hierarchy that the collision takes place at should not have anything critical to the collision further derived. IE: If two objects distribute kinetic energy by mass on an impact with each other, you wouldn&#39;t store the mass of the object in a derived class above the collision object, you would store it below or in the collision object itself.</p><p>So if you need to know whether something which hits a ship is a powerup or not and what kind of powerup it is, that information needs to be stored at the collision level, or closer to the base level, and then the ship, not the powerup, would process it.</p><p>...If that makes any sense at all. I&#39;m still figuring all this OOP stuff out so I could be way off my rocker there... <img src="http://www.allegro.cc/forums/smileys/huh.gif" alt="???" /></p><p>--- Kris Asick (Gemini)<br />--- <a href="http://www.pixelships.com">http://www.pixelships.com</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Mon, 05 Feb 2007 21:53:32 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Collision is probably irrelevent for :<br />CBullet - CBullet<br />CBullet - CBonus<br />CBonus  - CBonus</p><p>Which leaves you CShip - everything else (including CShip)<br />Now you only need to derive the<span class="source-code"><span class="k1">virtual</span> CollidingObject::handle_collision_with <span class="k2">(</span>CShip <span class="k3">&amp;</span> ship<span class="k2">)</span></span><br />for all 3 classes.<br />Does it suit your needs?</p><p>edit: after further research, in the general case what you need is multiple polymorphism, which doesn&#39;t seem to be available in C++.<br />It would consist of a &quot;method&quot; </p><pre>virtual collision(CollidingObject &amp;a,CollidingObject &amp;b)</pre><p>
that you would derive for all 3x3 combinations, and at run-time it would select which one to use depending on a and b.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Audric)</author>
		<pubDate>Mon, 05 Feb 2007 21:58:08 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>One way would be to have a map from two type IDs to a function pointer.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Fladimir da Gorf)</author>
		<pubDate>Mon, 05 Feb 2007 22:12:51 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thanks for your suggestions so far but I am not satisfied.</p><p>Kris Asick: If I would put all the necessary informations that I need to fully handle every collision into the CCollidingObject-class or even higher in the tree, it would defeat one of the most basic OOP-features. Why should a CCollidingObject have a member which stores the shield energy, as a ship would have? I really don&#39;t like that!</p><p>Audric: well, if for example a bullet collides with a ship, who would then destroy the bullet? Should the ship destroy the bullet? IMHO, when they collide the ship AND the bullet should both handle the collision, the ship should decrease it&#39;s health/shield energy, and the bullet should set some flag, so that it gets destroyed in the next frame. (I already figured out that having objects being destroyed at a global place is by far the best method)<br />Furthermore, consider I only have a linked list of all CCollidingObjects, so even calling your function would require me to do a down-cast. Apart from that, it would work for your scenario, but I also want objects like asteroids and other stuff which should also collide with ships and bullets. So, all in all it doesn&#39;t suit my needs! <img src="http://www.allegro.cc/forums/smileys/sad.gif" alt=":(" /></p><p>edit:</p><p>Audric: that&#39;s a feature I miss in C++ since I have started using it! <img src="http://www.allegro.cc/forums/smileys/undecided.gif" alt=":-/" /></p><p>Flad: care to elaborate a bit more? I am not quite sure I did understand.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (imaxcs)</author>
		<pubDate>Mon, 05 Feb 2007 22:20:49 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>First of all, divide the collision problem into two sub-problems: collision DETECTION and collision RESPONSE.<br />Only objects that MOVE require collision detection, all other objects are static and should only be a &quot;passive&quot; partner in any collision. This alone can drastically reduce the amount of computing needed for collision detection (e.g. by maintaining two separate lists for dynamic and static objects, or by sorting your list so that dynamic objects come first, allowing you to stop iterating when you hit a static object). Objects that trigger no collision response at all (backgrounds and decorative sprites, as well as particle effects and scores popping up when you kill an enemy) can be skipped for both the &quot;active&quot; (outer loop) and the &quot;passive&quot; (inner loop) iteration, so putting them at the very end of the list makes sense too.<br />Abstract collision detection behavior into a class hierarchy of its own:
</p><pre>
cBoundingObject (pure virtual)
|
+- cBoundingSphere
|
+- cBoundingBox
|
+- cBoundingPoint
|
+- cBoundingLine
|
+- cWhateverBoundingThingy
</pre><p>
Whether the actual collision check should be a member function or a global function is a matter of taste. If all your objects use the same bounding type, there is no need for an entire class hierarchy and virtual functions, but it&#39;s still a good idea to encapsulate the collision detection.</p><p>When it comes to collision response, you should group all possible sorts of collision responses into groups, such as:<br />- bounce<br />- deal damage<br />- explode<br />- be picked up and apply powerup<br />- ...<br />The class should have a set of member functions or variables to indicate the desired collision response. Since many of the responses require access to 2 objects, as well as object insertion / deletion, it is a good idea to keep the actual response code in the main game class (I usually call it cScene); it is not very OOP to have objects manipulate the main object list. Also, this is far more flexible, and usually faster, than the downcasting approach, since you can re-use the collision response code for totally unrelated types of objects, provided it is handled in the main game class. For example, a generic bullet could use linear non-accelerated movement, and no bouncing, while a missile class derived from it might use the same damage dealing, but &quot;inherit&quot; its bouncing code from the ship class.</p><p>--- EDIT ---<br />Your examples:<br />- not every class needs a shield, but the cCollisionObject should have a member function get_shield(), returning either cShield* (defaulting to NULL), or a number indicating the current shield load. I recommend encapsulating the shield code into its own dedicated structure, this allows you to put a shield on anything you want quite easily. This does NOT mean that cCollisionObject should have a member van cShield* shield; only classes where this makes sense should. Conversely, cCollisionObject() should have a member function take_damage(float), which will reduce shield / hull / ... or whatever is available, and marking the object as &quot;dead&quot; if necessary. For an indestructible object, this obviously does nothing.<br />- &quot;dead&quot; flags are a good idea, since they allow you to remove all dead objects in one go, and clear all references to dead objects before removing them. It is not a good idea to have individual objects messing around with the global list.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Mon, 05 Feb 2007 22:55:31 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>edit: I didn&#39;t precise below, this is about collision RESPONSE</p><p>Personnally, I use a very Actor-oriented model:</p><p>What does a bonus do when it touches something ?<br />It <b>informs</b> it that a bonus wants to hug him - if the target acknowledges, the bonus dies.</p><p>What does a enemy bullet do when it touches something ?<br />It <b>informs</b> it that it has come in contact. If target acknowledges a positive hit, the missile becomes a hit flash, then later dies.</p><p>etc.</p><p>The messaging is simply done by calling for example: <span class="source-code"><span class="k1">bool</span> actor::hit_by_missile<span class="k2">(</span>missile <span class="k3">*</span> <span class="k1">this</span><span class="k2">)</span></span><br />Each class derives its own, the default code for all interaction is simply<br /><span class="source-code"><span class="k2">{</span> <span class="k1">return</span> FALSE<span class="k2">;</span> <span class="k2">}</span> <span class="c">// I don't care</span></span><br />Also, to reduce the number of checks, at the base class level I do a simple<span class="source-code"><span class="k1">if</span> <span class="k2">(</span>active_actor-&gt;active_flags <span class="k3">&amp;</span> passive_actor-&gt;passive_flags<span class="k2">)</span></span>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Audric)</author>
		<pubDate>Mon, 05 Feb 2007 23:55:26 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I prefer having the scene inform the objects involved that they are touching, and decide what to do with them according to their stats.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Tue, 06 Feb 2007 00:45:20 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>The common practice is for CCollidingObject to handle it on movement.  If any sub-class of CCollidingObject ever wants to move it must call a movement function implemented by CCollidingObject.  That function checks if the new position collides with any other CCollidingObjects.</p><p>Pretty simple really.</p><p>No down-up or any casting at all.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Tue, 06 Feb 2007 01:44:22 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You assume that only movement can cause a collision.<br />Don&#39;t forget &quot;growing&quot; and &quot;state changing&quot; (ie: from invis/invulnerable to vulnerable)<br />I&#39;m thinking of growing especially for (dangerous/damaging) explosions.</p><p>Well, anyway, do what&#39;s most suited for the game at hand. A classic shoot&#39;em up will typically have 70% objects on screen as player projectiles, so better &quot;optimize&quot; for this situation.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Audric)</author>
		<pubDate>Tue, 06 Feb 2007 02:50:12 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>All the events that can trigger a collision must be implemented in CCollideObject.  It is the OOP way.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Tue, 06 Feb 2007 02:53:24 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
If I would put all the necessary informations that I need to fully handle every collision into the CCollidingObject-class or even higher in the tree, it would defeat one of the most basic OOP-features. Why should a CCollidingObject have a member which stores the shield energy, as a ship would have? I really don&#39;t like that!
</p></div></div><p>

Why do you need that much information to be accessible?</p><p>In the case of a weapon hitting a ship, the weapon has a damage value, the ship has its shields. A collision is detected by the system and both objects run their collision routines.</p><p>Ship Collision:<br />Is target object a weapon? Yes<br />Call target object function GetDamageVal().<br />Decrease shields by damage value retrieved from target object.</p><p>Weapon Collision:<br />Is target object a weapon? No<br />Is target object a ship? Yes<br />Queue self to be destroyed after collision detection is over.</p><p>You never have to send the damage or shield data through the collision class since the ship class has its own method of handling collisions and so does the weapon class.</p><p>Does that make more sense?</p><p>--- Kris Asick (Gemini)<br />--- <a href="http://www.pixelships.com">http://www.pixelships.com</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Kris Asick)</author>
		<pubDate>Tue, 06 Feb 2007 06:37:04 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="source-code snippet"><div class="inner"><pre><span class="k1">class</span> Collidable <span class="k2">{</span>
 <span class="k1">void</span> moveTo<span class="k2">(</span><span class="k1">int</span> x, <span class="k1">int</span> y<span class="k2">)</span>
 <span class="k2">{</span>
  <span class="k1">if</span><span class="k2">(</span>.. collision ..<span class="k2">)</span>
   this-&gt;onCollision<span class="k2">(</span>otherCollidablePointer<span class="k2">)</span><span class="k2">;</span>
 <span class="k2">}</span>
 <span class="k1">virtual</span> <span class="k1">void</span> onCollision<span class="k2">(</span>Collidable<span class="k3">*</span><span class="k2">)</span> <span class="k2">{</span><span class="k2">}</span>
<span class="k2">}</span><span class="k2">;</span>
</pre></div></div><p>
</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">class</span> Ship <span class="k2">:</span> <span class="k1">public</span> Collidable <span class="k2">{</span>
 ...
<span class="k2">}</span><span class="k2">;</span>
<span class="k1">class</span> Missle <span class="k2">:</span> <span class="k1">public</span> Collidable <span class="k2">{</span>
 <span class="k1">virtual</span> <span class="k1">void</span> onCollision<span class="k2">(</span>Collidable <span class="k3">*</span>c<span class="k2">)</span>
 <span class="k2">{</span>
  Ship <span class="k3">*</span>s <span class="k3">=</span> <span class="k1">dynamic_cast</span><span class="k3">&lt;</span>Ship<span class="k3">*</span><span class="k3">&gt;</span><span class="k2">(</span>c<span class="k2">)</span><span class="k2">;</span>

  <span class="k1">if</span><span class="k2">(</span>s<span class="k2">)</span>
   s-&gt;inflictDamage<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>

  dienow<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
 <span class="k2">}</span>
<span class="k2">}</span><span class="k2">;</span>
</pre></div></div><p>
This is the proper OOP style.  If you&#39;re going to do differen&#39;t go for it but know that you are not doing OOP style.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Tue, 06 Feb 2007 07:45:47 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
This is the proper OOP style. If you&#39;re going to do differen&#39;t go for it but know that you are not doing OOP style.
</p></div></div><p>
no comments...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Audric)</author>
		<pubDate>Tue, 06 Feb 2007 07:48:10 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Here is a perhaps easier way to handle the problem (If only C++ had multimethods!): have a base class CCollision with a virtual method &#39;execute&#39;:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">class</span> CCollision <span class="k2">{</span>
public:
    <span class="k1">virtual</span> <span class="k1">void</span> execute<span class="k2">(</span><span class="k2">)</span> <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span>
<span class="k2">}</span><span class="k2">;</span>
</pre></div></div><p>

Then have a template subclass with two types, one for each type of object; this class acts as a container of the two types:</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">template</span> <span class="k3">&lt;</span> <span class="k1">class</span> T1, <span class="k1">class</span> T2 <span class="k3">&gt;</span> <span class="k1">class</span> CBinaryCollision <span class="k2">{</span></td></tr><tr><td class="number">2</td><td>public:</td></tr><tr><td class="number">3</td><td>    CBinaryCollision<span class="k2">(</span>T1 <span class="k3">*</span>firstObject, T2 <span class="k3">*</span>secondObject<span class="k2">)</span> <span class="k2">:</span> m_firstObject<span class="k2">(</span>firstObject<span class="k2">)</span>, m_secondObject<span class="k2">(</span>secondObject<span class="k2">)</span> <span class="k2">{</span></td></tr><tr><td class="number">4</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">5</td><td>&#160;</td></tr><tr><td class="number">6</td><td>    T1 <span class="k3">*</span>getFirstObject<span class="k2">(</span><span class="k2">)</span> <span class="k1">const</span> <span class="k2">{</span></td></tr><tr><td class="number">7</td><td>        <span class="k1">return</span> m_firstObject<span class="k2">;</span></td></tr><tr><td class="number">8</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">9</td><td>&#160;</td></tr><tr><td class="number">10</td><td>    T2 <span class="k3">*</span>getSecondObject<span class="k2">(</span><span class="k2">)</span> <span class="k1">const</span> <span class="k2">{</span></td></tr><tr><td class="number">11</td><td>        <span class="k1">return</span> m_secondObject<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>&#160;</td></tr><tr><td class="number">14</td><td>private:</td></tr><tr><td class="number">15</td><td>    T1 <span class="k3">*</span>m_firstObject<span class="k2">;</span></td></tr><tr><td class="number">16</td><td>    T2 <span class="k3">*</span>m_secondObject<span class="k2">;</span></td></tr><tr><td class="number">17</td><td><span class="k2">}</span><span class="k2">;</span></td></tr></tbody></table></div></div><p>

Then have a specific subclass which handles specific types. For example, to manage the collision between the ship and the powerup, you can do the following:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">class</span> CShipPowerUpCollision <span class="k2">:</span> <span class="k1">public</span> CBinaryCollision<span class="k3">&lt;</span>CShip, CPowerUp&gt; <span class="k2">{</span>
public:
    CShipPowerUpCollision<span class="k2">(</span>CShip <span class="k3">*</span>ship, CPowerUp <span class="k3">*</span>powerUp<span class="k2">)</span> <span class="k2">:</span> CBinaryCollision<span class="k3">&lt;</span>CShip, CPowerUp&gt;<span class="k2">(</span>ship, powerUp<span class="k2">)</span> <span class="k2">{</span>
    <span class="k2">}</span>

    <span class="k1">virtual</span> <span class="k1">void</span> execute<span class="k2">(</span><span class="k2">)</span> <span class="k2">{</span>
        CShip <span class="k3">*</span>ship <span class="k3">=</span> getFirstObject<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
        CPowerUp <span class="k3">*</span>powerUp <span class="k3">=</span> getSecondObject<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
        <span class="k1">if</span> <span class="k2">(</span>ship-&gt;collidesWith<span class="k2">(</span>powerUp<span class="k2">)</span><span class="k2">)</span> <span class="k2">{</span>
            ship-&gt;power<span class="k3">+</span><span class="k3">+</span><span class="k2">;</span>
        <span class="k2">}</span>
    <span class="k2">}</span>
<span class="k2">}</span><span class="k2">;</span>
</pre></div></div><p>

Then place all collision objects in a list which you frequently scan, invoking the &#39;execute&#39; method:</p><div class="source-code snippet"><div class="inner"><pre>std::list<span class="k3">&lt;</span>CCollision <span class="k3">*</span><span class="k3">&gt;</span> collisions<span class="k2">;</span>
collisions.push_back<span class="k2">(</span><span class="k1">new</span> CShipPowerUpCollision<span class="k2">(</span>myShip, myPowerUp<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="k1">while</span> <span class="k2">(</span>gameLoop<span class="k2">)</span> <span class="k2">{</span>
    ...
    <span class="k1">for</span><span class="k2">(</span>std::list<span class="k3">&lt;</span>CCollision <span class="k3">*</span><span class="k3">&gt;</span><span class="k2">:</span><span class="k2">:</span>iterator it <span class="k3">=</span> collisions.begin<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> it <span class="k3">!</span><span class="k3">=</span> collisions.end<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> <span class="k3">+</span><span class="k3">+</span>it<span class="k2">)</span> <span class="k2">{</span>
        CCollision <span class="k3">*</span>collision <span class="k3">=</span> <span class="k3">*</span>it<span class="k2">;</span>
        collision-&gt;execute<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    <span class="k2">}</span>
<span class="k2">}</span>
</pre></div></div><p>

EDIT:</p><p>If there are not many collisions to test, perhaps the procedural approach is best:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">while</span> <span class="k2">(</span>gameLoop<span class="k2">)</span> <span class="k2">{</span>
    ...
    testCollision<span class="k2">(</span>myShip, powerUps<span class="k2">)</span><span class="k2">;</span>
    testCollision<span class="k2">(</span>myShip, bullets<span class="k2">)</span><span class="k2">;</span>
    ...
<span class="k2">}</span>
</pre></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (axilmar)</author>
		<pubDate>Tue, 06 Feb 2007 17:26:10 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thank you again for your help!</p><p>It seems there is no 100 percent clean method to do this. But you all gave quite some cool stuff to make it at least come close. I especially like axilmar&#39;s idea! Thank you! <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" /></p><p>edit: ok, axilmar, I really like your approach but there is one thing I am still not fond of.<br />In your code:
</p><div class="source-code snippet"><div class="inner"><pre>std::list<span class="k3">&lt;</span>CCollision <span class="k3">*</span><span class="k3">&gt;</span> collisions<span class="k2">;</span>
collisions.push_back<span class="k2">(</span><span class="k1">new</span> CShipPowerUpCollision<span class="k2">(</span>myShip, myPowerUp<span class="k2">)</span><span class="k2">)</span><span class="k2">;</span>
<span class="k1">while</span> <span class="k2">(</span>gameLoop<span class="k2">)</span> <span class="k2">{</span>
    ...
    <span class="k1">for</span><span class="k2">(</span>std::list<span class="k3">&lt;</span>CCollision <span class="k3">*</span><span class="k3">&gt;</span><span class="k2">:</span><span class="k2">:</span>iterator it <span class="k3">=</span> collisions.begin<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> it <span class="k3">!</span><span class="k3">=</span> collisions.end<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span> <span class="k3">+</span><span class="k3">+</span>it<span class="k2">)</span> <span class="k2">{</span>
        CCollision <span class="k3">*</span>collision <span class="k3">=</span> <span class="k3">*</span>it<span class="k2">;</span>
        collision-&gt;execute<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>
    <span class="k2">}</span>
<span class="k2">}</span>
</pre></div></div><p>
How do I check, which collision has occured? How do I know it&#39;s a CShipPowerUpCollision and not something else?
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (imaxcs)</author>
		<pubDate>Tue, 06 Feb 2007 20:41:36 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
How do I check, which collision has occured? How do I know it&#39;s a CShipPowerUpCollision and not something else?
</p></div></div><p>
By checking the types of the colliding objects, duh.<br />Either dynamic_cast the objects (which is ugly), or give them virtual member functions that return some value with which you can recognize them.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Wed, 07 Feb 2007 23:43:44 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
How do I check, which collision has occured? How do I know it&#39;s a CShipPowerUpCollision and not something else?
</p></div></div><p>

You shouldn&#39;t do that! the whole point of putting the collision code into objects is that you don&#39;t have to do that. Put all the code that must be executed in a collision inside the CCollision subclass.</p><p>Here is a wikipedia article about multimethods:</p><p><a href="http://en.wikipedia.org/wiki/Multiple_dispatch">multimethods</a>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (axilmar)</author>
		<pubDate>Thu, 08 Feb 2007 21:44:16 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>You can use the &quot;CShipPowerUpCollision&quot; system if you want, but your project wont last more then a week when you realize how many utterly useless objects you&#39;ve created and what a pain in the <span class="cuss"><span>ass</span></span> it is.  Then your code will turn so ugly you&#39;ll give up on the project and start over <img src="http://www.allegro.cc/forums/smileys/cry.gif" alt=":&#39;(" /></p><p>But, some lessons have to be learned the hard way.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Sat, 10 Feb 2007 01:40:44 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>this works nice the script pointer hard coded id based.</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td>&#160;</td></tr><tr><td class="number">2</td><td>&#160;</td></tr><tr><td class="number">3</td><td><span class="k1">void</span> UnitList::setup_collision<span class="k2">(</span><a href="http://www.allegro.cc/manual/DATAFILE" target="_blank"><span class="a">DATAFILE</span></a> <span class="k3">*</span>music<span class="k2">)</span></td></tr><tr><td class="number">4</td><td><span class="k2">{</span></td></tr><tr><td class="number">5</td><td>  </td></tr><tr><td class="number">6</td><td>  textout<span class="k2">(</span><a href="http://www.allegro.cc/manual/screen" target="_blank"><span class="a">screen</span></a>,<a href="http://www.allegro.cc/manual/font" target="_blank"><span class="a">font</span></a>,<span class="s">"setup_collision called "</span>,<span class="n">100</span>,<span class="n">320</span>,<a href="http://www.allegro.cc/manual/makecol" target="_blank"><span class="a">makecol</span></a><span class="k2">(</span><span class="n">6</span>,<span class="n">255</span>,<span class="n">255</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">7</td><td>&#160;</td></tr><tr><td class="number">8</td><td>  </td></tr><tr><td class="number">9</td><td>  <span class="k1">int</span> i,j<span class="k2">;</span></td></tr><tr><td class="number">10</td><td>  </td></tr><tr><td class="number">11</td><td>  <span class="k1">for</span><span class="k2">(</span>  i <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> i <span class="k3">&lt;</span> numItems<span class="k2">;</span> i<span class="k3">+</span><span class="k3">+</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>   </td></tr><tr><td class="number">14</td><td>    <span class="k1">for</span><span class="k2">(</span>  j <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span> j <span class="k3">&lt;</span> numItems<span class="k2">;</span> j<span class="k3">+</span><span class="k3">+</span> <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>      <span class="k1">if</span><span class="k2">(</span>listofUnits<span class="k3">&lt;</span>i&gt;-&gt;get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>Get_inarea<span class="k2">(</span><span class="k2">)</span><span class="k3">=</span><span class="k3">=</span>listofUnits<span class="k2">[</span>j<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>Get_inarea<span class="k2">(</span><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="k1">if</span><span class="k2">(</span>listofUnits<span class="k3">&lt;</span>i&gt;-&gt;get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>is_collision<span class="k2">(</span>listofUnits<span class="k2">[</span>j<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span> <span class="k2">)</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>listofUnits<span class="k3">&lt;</span>i&gt;-&gt;get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>Get_id<span class="k2">(</span><span class="k2">)</span> <span class="k3">!</span><span class="k3">=</span> listofUnits<span class="k2">[</span>j<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>Get_id<span class="k2">(</span><span class="k2">)</span><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>            textout<span class="k2">(</span><a href="http://www.allegro.cc/manual/screen" target="_blank"><span class="a">screen</span></a>,<a href="http://www.allegro.cc/manual/font" target="_blank"><span class="a">font</span></a>,<span class="s">" collision detected "</span>,<span class="n">400</span>,<span class="n">320</span>,<a href="http://www.allegro.cc/manual/makecol" target="_blank"><span class="a">makecol</span></a><span class="k2">(</span><span class="n">6</span>,<span class="n">255</span>,<span class="n">255</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">23</td><td>&#160;</td></tr><tr><td class="number">24</td><td>            listofUnits<span class="k3">&lt;</span>i&gt;-&gt;get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>Set_collision<span class="k2">(</span><span class="k1">true</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">25</td><td>            listofUnits<span class="k2">[</span>j<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>Set_collision<span class="k2">(</span><span class="k1">true</span><span class="k2">)</span><span class="k2">;</span><span class="c">/// this has the sam bug from project 3 setting point useable</span></td></tr><tr><td class="number">26</td><td>&#160;</td></tr><tr><td class="number">27</td><td>            </td></tr><tr><td class="number">28</td><td><span class="k1">if</span><span class="k2">(</span>listofUnits<span class="k2">[</span>j<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>Get_id<span class="k2">(</span><span class="k2">)</span><span class="k3">!</span><span class="k3">=</span>computerId<span class="k2">)</span></td></tr><tr><td class="number">29</td><td><span class="k2">{</span></td></tr><tr><td class="number">30</td><td>  targget<span class="k3">=</span>listofUnits<span class="k2">[</span>j<span class="k2">]</span><span class="k3">-</span><span class="k3">&gt;</span>get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>Get_id<span class="k2">(</span><span class="k2">)</span><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><span class="k1">else</span></td></tr><tr><td class="number">33</td><td><span class="k2">{</span></td></tr><tr><td class="number">34</td><td>  targget<span class="k3">=</span>listofUnits<span class="k3">&lt;</span>i&gt;-&gt;get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>Get_id<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">35</td><td><span class="k2">}</span></td></tr><tr><td class="number">36</td><td>            </td></tr><tr><td class="number">37</td><td>&#160;</td></tr><tr><td class="number">38</td><td>            <span class="k1">if</span><span class="k2">(</span>listofUnits<span class="k3">&lt;</span>i&gt;-&gt;get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>type <span class="k3">=</span><span class="k3">=</span><span class="n">2</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>              listofUnits<span class="k3">&lt;</span>i&gt;-&gt;get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>triggered<span class="k3">=</span><span class="k1">true</span><span class="k2">;</span></td></tr><tr><td class="number">41</td><td>&#160;</td></tr><tr><td class="number">42</td><td><span class="k2">(</span><span class="k2">(</span>TriggerConfig<span class="k3">*</span><span class="k2">)</span>listofUnits<span class="k3">&lt;</span>i&gt;<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>TriggerObject.runScript<span class="k2">(</span><span class="k2">(</span><span class="k2">(</span>CharacterConfig<span class="k3">*</span><span class="k2">)</span>listofUnits<span class="k2">[</span>j<span class="k2">]</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_UnitObject<span class="k2">(</span><span class="k2">)</span>,music<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">43</td><td>            <span class="c">//listofUnits&lt;i&gt;-&gt;get_UnitObject()-&gt;set_onewhotiggeredme(*(listofUnits[j]-&gt;get_UnitObject()));</span></td></tr><tr><td class="number">44</td><td><span class="c">/*</span></td></tr><tr><td class="number">45</td><td><span class="c">if(listofUnits&lt;i&gt;-&gt;get_UnitObject()-&gt;scriptId==1)</span></td></tr><tr><td class="number">46</td><td><span class="c">{</span></td></tr><tr><td class="number">47</td><td><span class="c">  listofUnits[j]-&gt;get_UnitObject()-&gt;Set_inarea(1);//rig</span></td></tr><tr><td class="number">48</td><td><span class="c">  if(computerId==listofUnits[j]-&gt;get_UnitObject()-&gt;Get_id())</span></td></tr><tr><td class="number">49</td><td><span class="c">  {</span></td></tr><tr><td class="number">50</td><td><span class="c">    ch_current_area = 1;//rig</span></td></tr><tr><td class="number">51</td><td><span class="c">  }</span></td></tr><tr><td class="number">52</td><td><span class="c">}  </span></td></tr><tr><td class="number">53</td><td><span class="c">else if(listofUnits&lt;i&gt;-&gt;get_UnitObject()-&gt;scriptId==2)</span></td></tr><tr><td class="number">54</td><td><span class="c">{</span></td></tr><tr><td class="number">55</td><td><span class="c">  listofUnits[j]-&gt;get_UnitObject()-&gt;Set_inarea(2);//rig</span></td></tr><tr><td class="number">56</td><td><span class="c">  if(computerId==listofUnits[j]-&gt;get_UnitObject()-&gt;Get_id())</span></td></tr><tr><td class="number">57</td><td><span class="c">  {</span></td></tr><tr><td class="number">58</td><td><span class="c">    ch_current_area = 2;//rig</span></td></tr><tr><td class="number">59</td><td><span class="c">  }</span></td></tr><tr><td class="number">60</td><td><span class="c">}</span></td></tr><tr><td class="number">61</td><td><span class="c">else if(listofUnits&lt;i&gt;-&gt;get_UnitObject()-&gt;scriptId==3)</span></td></tr><tr><td class="number">62</td><td><span class="c">{</span></td></tr><tr><td class="number">63</td><td><span class="c">  listofUnits[j]-&gt;get_UnitObject()-&gt;Set_inarea(3);//rig</span></td></tr><tr><td class="number">64</td><td><span class="c">  if(computerId==listofUnits[j]-&gt;get_UnitObject()-&gt;Get_id())</span></td></tr><tr><td class="number">65</td><td><span class="c">  {</span></td></tr><tr><td class="number">66</td><td><span class="c">    ch_current_area = 3;//rig</span></td></tr><tr><td class="number">67</td><td><span class="c">  }</span></td></tr><tr><td class="number">68</td><td><span class="c">}</span></td></tr><tr><td class="number">69</td><td><span class="c"></span></td></tr><tr><td class="number">70</td><td><span class="c">else if(listofUnits&lt;i&gt;-&gt;get_UnitObject()-&gt;scriptId==4)</span></td></tr><tr><td class="number">71</td><td><span class="c">{</span></td></tr><tr><td class="number">72</td><td><span class="c">  listofUnits[j]-&gt;get_UnitObject()-&gt;Set_inarea(4);//rig</span></td></tr><tr><td class="number">73</td><td><span class="c">  if(computerId==listofUnits[j]-&gt;get_UnitObject()-&gt;Get_id())</span></td></tr><tr><td class="number">74</td><td><span class="c">  {</span></td></tr><tr><td class="number">75</td><td><span class="c">    ch_current_area = 4;//rig</span></td></tr><tr><td class="number">76</td><td><span class="c">  }</span></td></tr><tr><td class="number">77</td><td><span class="c">}</span></td></tr><tr><td class="number">78</td><td><span class="c">*/</span></td></tr><tr><td class="number">79</td><td>&#160;</td></tr><tr><td class="number">80</td><td>        </td></tr><tr><td class="number">81</td><td><span class="c">//  listofUnits&lt;i&gt;-&gt;get_UnitObject()-&gt;runScript();</span></td></tr><tr><td class="number">82</td><td>  listofUnits<span class="k3">&lt;</span>i&gt;-&gt;get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>triggered<span class="k3">=</span><span class="k1">false</span><span class="k2">;</span></td></tr><tr><td class="number">83</td><td>&#160;</td></tr><tr><td class="number">84</td><td>            <span class="c">//  listofUnits&lt;i&gt;-&gt;get_UnitObject()-&gt;set_onewhotiggeredme(NULL);</span></td></tr><tr><td class="number">85</td><td>            <span class="k2">}</span></td></tr><tr><td class="number">86</td><td>            <span class="k1">break</span><span class="k2">;</span><span class="c">//list of ele</span></td></tr><tr><td class="number">87</td><td>          <span class="k2">}</span></td></tr><tr><td class="number">88</td><td>          <span class="k1">else</span></td></tr><tr><td class="number">89</td><td>          <span class="k2">{</span></td></tr><tr><td class="number">90</td><td>            listofUnits<span class="k3">&lt;</span>i&gt;-&gt;get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>Set_collision<span class="k2">(</span><span class="k1">false</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">91</td><td>      </td></tr><tr><td class="number">92</td><td>          <span class="k2">}</span></td></tr><tr><td class="number">93</td><td>        <span class="k2">}</span></td></tr><tr><td class="number">94</td><td>        <span class="k1">else</span></td></tr><tr><td class="number">95</td><td>        <span class="k2">{</span></td></tr><tr><td class="number">96</td><td>          listofUnits<span class="k3">&lt;</span>i&gt;-&gt;get_UnitObject<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>Set_collision<span class="k2">(</span><span class="k1">false</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">97</td><td>&#160;</td></tr><tr><td class="number">98</td><td>        <span class="k2">}</span></td></tr><tr><td class="number">99</td><td>      <span class="k2">}</span></td></tr><tr><td class="number">100</td><td>    </td></tr><tr><td class="number">101</td><td>    <span class="k2">}</span>  </td></tr><tr><td class="number">102</td><td>  </td></tr><tr><td class="number">103</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">104</td><td>  textout<span class="k2">(</span><a href="http://www.allegro.cc/manual/screen" target="_blank"><span class="a">screen</span></a>,<a href="http://www.allegro.cc/manual/font" target="_blank"><span class="a">font</span></a>,<span class="s">"setup_collision done "</span>,<span class="n">100</span>,<span class="n">350</span>,<a href="http://www.allegro.cc/manual/makecol" target="_blank"><span class="a">makecol</span></a><span class="k2">(</span><span class="n">255</span>,<span class="n">6</span>,<span class="n">255</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">105</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>


one of the objects
</p><div class="source-code"><div class="toolbar"></div><div class="inner"><table width="100%"><tbody><tr><td class="number">1</td><td>&#160;</td></tr><tr><td class="number">2</td><td>&#160;</td></tr><tr><td class="number">3</td><td><span class="k1">void</span> Trigger::runScript<span class="k2">(</span>Unit <span class="k3">*</span>onewhotiggeredme,<a href="http://www.allegro.cc/manual/DATAFILE" target="_blank"><span class="a">DATAFILE</span></a> <span class="k3">*</span>music<span class="k2">)</span></td></tr><tr><td class="number">4</td><td><span class="k2">{</span></td></tr><tr><td class="number">5</td><td>  <span class="k1">if</span><span class="k2">(</span>triggered<span class="k3">=</span><span class="k3">=</span> <span class="k1">true</span><span class="k2">)</span></td></tr><tr><td class="number">6</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">7</td><td>&#160;</td></tr><tr><td class="number">8</td><td><span class="c">//if(attributess.attackstamana &gt;= 50) //each telaport takes 50</span></td></tr><tr><td class="number">9</td><td><span class="c">//{</span></td></tr><tr><td class="number">10</td><td><span class="c">//attributess.attackstamana = attributess.attackstamana - 50; //attack take 50 stamana points to do</span></td></tr><tr><td class="number">11</td><td><span class="c">//onewhotiggeredme-&gt;Set_inarea(2);</span></td></tr><tr><td class="number">12</td><td><span class="c">//if(attributess.attackstamana &lt; 0)</span></td></tr><tr><td class="number">13</td><td><span class="c">//{</span></td></tr><tr><td class="number">14</td><td><span class="c">//attributess.attackstamana=0;</span></td></tr><tr><td class="number">15</td><td><span class="c">//}</span></td></tr><tr><td class="number">16</td><td>&#160;</td></tr><tr><td class="number">17</td><td>    <span class="k1">switch</span><span class="k2">(</span>scriptId<span class="k2">)</span></td></tr><tr><td class="number">18</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">19</td><td>      <span class="k1">case</span> <span class="n">1</span><span class="k2">:</span></td></tr><tr><td class="number">20</td><td>        <span class="c">//do this</span></td></tr><tr><td class="number">21</td><td>        onewhotiggeredme-&gt;Set_inarea<span class="k2">(</span><span class="n">1</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">22</td><td><span class="k1">if</span><span class="k2">(</span>computerId<span class="k3">=</span><span class="k3">=</span>onewhotiggeredme-&gt;Get_id<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span></td></tr><tr><td class="number">23</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">24</td><td>    play_sound<span class="k2">(</span>SAMPLE_MAGIC,music<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">25</td><td>    ch_current_area <span class="k3">=</span> <span class="n">1</span><span class="k2">;</span><span class="c">//rig</span></td></tr><tr><td class="number">26</td><td>    stop_song<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">27</td><td>    play_song<span class="k2">(</span>MIDI_SPIKKO,music<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">28</td><td>&#160;</td></tr><tr><td class="number">29</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">30</td><td>        <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">31</td><td>      <span class="k1">case</span> <span class="n">2</span><span class="k2">:</span></td></tr><tr><td class="number">32</td><td>        <span class="c">//do this</span></td></tr><tr><td class="number">33</td><td>        onewhotiggeredme-&gt;Set_inarea<span class="k2">(</span><span class="n">2</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">34</td><td><span class="k1">if</span><span class="k2">(</span>computerId<span class="k3">=</span><span class="k3">=</span>onewhotiggeredme-&gt;Get_id<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span></td></tr><tr><td class="number">35</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">36</td><td>play_sound<span class="k2">(</span>SAMPLE_MAGIC,music<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">37</td><td>    ch_current_area <span class="k3">=</span> <span class="n">2</span><span class="k2">;</span><span class="c">//rig</span></td></tr><tr><td class="number">38</td><td>    stop_song<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">39</td><td>    play_song<span class="k2">(</span>MIDI_BATTLE,music<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">40</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">41</td><td>        <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">42</td><td>      <span class="k1">case</span> <span class="n">3</span><span class="k2">:</span></td></tr><tr><td class="number">43</td><td>        <span class="c">//do this</span></td></tr><tr><td class="number">44</td><td>        onewhotiggeredme-&gt;Set_inarea<span class="k2">(</span><span class="n">3</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">45</td><td><span class="k1">if</span><span class="k2">(</span>computerId<span class="k3">=</span><span class="k3">=</span>onewhotiggeredme-&gt;Get_id<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span></td></tr><tr><td class="number">46</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">47</td><td>play_sound<span class="k2">(</span>SAMPLE_MAGIC,music<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">48</td><td>    ch_current_area <span class="k3">=</span> <span class="n">3</span><span class="k2">;</span><span class="c">//rig</span></td></tr><tr><td class="number">49</td><td>    stop_song<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">50</td><td>    play_song<span class="k2">(</span>MIDI_FROG,music<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">51</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">52</td><td>&#160;</td></tr><tr><td class="number">53</td><td>        <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">54</td><td>      <span class="k1">case</span> <span class="n">4</span><span class="k2">:</span></td></tr><tr><td class="number">55</td><td>        <span class="c">//do this</span></td></tr><tr><td class="number">56</td><td>        onewhotiggeredme-&gt;Set_inarea<span class="k2">(</span><span class="n">4</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">57</td><td><span class="k1">if</span><span class="k2">(</span>computerId<span class="k3">=</span><span class="k3">=</span>onewhotiggeredme-&gt;Get_id<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span></td></tr><tr><td class="number">58</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">59</td><td>play_sound<span class="k2">(</span>SAMPLE_MAGIC,music<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">60</td><td>    ch_current_area <span class="k3">=</span> <span class="n">4</span><span class="k2">;</span><span class="c">//rig</span></td></tr><tr><td class="number">61</td><td>    stop_song<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">62</td><td>    play_song<span class="k2">(</span>MIDI_GOTA,music<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">63</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">64</td><td>        <span class="k1">break</span><span class="k2">;</span></td></tr><tr><td class="number">65</td><td>    <span class="k2">}</span>  </td></tr><tr><td class="number">66</td><td>&#160;</td></tr><tr><td class="number">67</td><td>&#160;</td></tr><tr><td class="number">68</td><td>&#160;</td></tr><tr><td class="number">69</td><td>&#160;</td></tr><tr><td class="number">70</td><td>&#160;</td></tr><tr><td class="number">71</td><td>&#160;</td></tr><tr><td class="number">72</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">73</td><td>&#160;</td></tr><tr><td class="number">74</td><td><span class="c">//  }</span></td></tr><tr><td class="number">75</td><td>  </td></tr><tr><td class="number">76</td><td>&#160;</td></tr><tr><td class="number">77</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (piccolo)</author>
		<pubDate>Sat, 10 Feb 2007 02:08:10 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
You can use the &quot;CShipPowerUpCollision&quot; system if you want, but your project wont last more then a week when you realize how many utterly useless objects you&#39;ve created and what a pain in the <span class="cuss"><span>ass</span></span> it is. Then your code will turn so ugly you&#39;ll give up on the project and start over <img src="http://www.allegro.cc/forums/smileys/cry.gif" alt=":&#39;(" /></p><p>But, some lessons have to be learned the hard way.
</p></div></div><p>

Hey, I couldn&#39;t agree more. That&#39;s why I wrote that if his collision detection needs are simple, the best approach is the procedural one.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (axilmar)</author>
		<pubDate>Sat, 10 Feb 2007 20:49:10 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Thanks for all your thoughts! Although I hope that your assumptions concerning my project failing are wrong. <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" /></p><p>I use a CCollisionHandler which&#39;s process-method currently looks like this:</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">void</span> CCollisionHandler::process<span class="k2">(</span><span class="k1">float</span> delta_time<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>  list<span class="k3">&lt;</span>CCollision<span class="k3">*</span><span class="k3">&gt;</span> collisions<span class="k2">;</span></td></tr><tr><td class="number">4</td><td>&#160;</td></tr><tr><td class="number">5</td><td>  <span class="c">// check for collisions</span></td></tr><tr><td class="number">6</td><td>  <span class="k1">for</span> <span class="k2">(</span>list<span class="k3">&lt;</span>CCollidingObject<span class="k3">*</span><span class="k3">&gt;</span><span class="k2">:</span><span class="k2">:</span>iterator it_outer <span class="k3">=</span> CObjectList::o<span class="k2">(</span><span class="k2">)</span>.begin_colliding<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>it_outer <span class="k3">!</span><span class="k3">=</span> CObjectList::o<span class="k2">(</span><span class="k2">)</span>.end_colliding<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>it_outer<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span></td></tr><tr><td class="number">7</td><td>    <span class="k1">for</span> <span class="k2">(</span>list<span class="k3">&lt;</span>CCollidingObject<span class="k3">*</span><span class="k3">&gt;</span><span class="k2">:</span><span class="k2">:</span>iterator it_inner <span class="k3">=</span> it_outer<span class="k2">;</span>it_inner <span class="k3">!</span><span class="k3">=</span> CObjectList::o<span class="k2">(</span><span class="k2">)</span>.end_colliding<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>it_inner<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span></td></tr><tr><td class="number">8</td><td>      <span class="k1">if</span> <span class="k2">(</span>it_inner <span class="k3">!</span><span class="k3">=</span> it_outer <span class="k3">&amp;</span><span class="k3">&amp;</span> <span class="k2">(</span><span class="k3">*</span>it_outer<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_attitude<span class="k2">(</span><span class="k2">)</span> <span class="k3">!</span><span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>it_inner<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_attitude<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span></td></tr><tr><td class="number">9</td><td>      <span class="k2">{</span></td></tr><tr><td class="number">10</td><td>        <span class="c">// first make a bounding-box-collision-detection</span></td></tr><tr><td class="number">11</td><td>        <span class="k1">float</span> outer_center_x <span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>it_outer<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_x<span class="k2">(</span><span class="k2">)</span> <span class="k3">+</span> <span class="k2">(</span><span class="k3">*</span>it_outer<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_w<span class="k2">(</span><span class="k2">)</span> <span class="k3">/</span> <span class="n">2</span><span class="k2">;</span></td></tr><tr><td class="number">12</td><td>        <span class="k1">float</span> outer_center_y <span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>it_outer<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_y<span class="k2">(</span><span class="k2">)</span> <span class="k3">+</span> <span class="k2">(</span><span class="k3">*</span>it_outer<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_h<span class="k2">(</span><span class="k2">)</span> <span class="k3">/</span> <span class="n">2</span><span class="k2">;</span></td></tr><tr><td class="number">13</td><td>        <span class="k1">float</span> outer_w <span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>it_outer<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_w<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">14</td><td>        <span class="k1">float</span> outer_h <span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>it_outer<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_h<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">15</td><td>&#160;</td></tr><tr><td class="number">16</td><td>        <span class="k1">float</span> inner_center_x <span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>it_inner<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_x<span class="k2">(</span><span class="k2">)</span> <span class="k3">+</span> <span class="k2">(</span><span class="k3">*</span>it_inner<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_w<span class="k2">(</span><span class="k2">)</span> <span class="k3">/</span> <span class="n">2</span><span class="k2">;</span></td></tr><tr><td class="number">17</td><td>        <span class="k1">float</span> inner_center_y <span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>it_inner<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_y<span class="k2">(</span><span class="k2">)</span> <span class="k3">+</span> <span class="k2">(</span><span class="k3">*</span>it_inner<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_h<span class="k2">(</span><span class="k2">)</span> <span class="k3">/</span> <span class="n">2</span><span class="k2">;</span></td></tr><tr><td class="number">18</td><td>        <span class="k1">float</span> inner_w <span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>it_inner<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_w<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">19</td><td>        <span class="k1">float</span> inner_h <span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>it_inner<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_h<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">20</td><td>&#160;</td></tr><tr><td class="number">21</td><td>        <span class="k1">if</span> <span class="k2">(</span><a href="http://www.delorie.com/djgpp/doc/libc/libc_303.html" target="_blank">fabs</a><span class="k2">(</span>outer_center_x <span class="k3">-</span> inner_center_x<span class="k2">)</span> <span class="k3">&lt;</span> <span class="k2">(</span>outer_w <span class="k3">+</span> inner_w<span class="k2">)</span> <span class="k3">/</span> <span class="n">2</span>.<span class="n">0f</span></td></tr><tr><td class="number">22</td><td>            <span class="k3">&amp;</span><span class="k3">&amp;</span> <a href="http://www.delorie.com/djgpp/doc/libc/libc_303.html" target="_blank">fabs</a><span class="k2">(</span>outer_center_y <span class="k3">-</span> inner_center_y<span class="k2">)</span> <span class="k3">&lt;</span> <span class="k2">(</span>outer_h <span class="k3">+</span> inner_h<span class="k2">)</span> <span class="k3">/</span> <span class="n">2</span>.<span class="n">0f</span><span class="k2">)</span></td></tr><tr><td class="number">23</td><td>        <span class="k2">{</span> <span class="c">// bounding-box hit detected</span></td></tr><tr><td class="number">24</td><td>          Collision collision <span class="k3">=</span> <span class="k2">(</span><span class="k3">*</span>it_outer<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_poly<span class="k2">(</span><span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>GetCollision<span class="k2">(</span><span class="k3">*</span><span class="k2">(</span><span class="k2">(</span><span class="k3">*</span>it_inner<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_poly<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span>, Placement<span class="k2">(</span>Vec2D<span class="k2">(</span><span class="k2">(</span><span class="k3">*</span>it_outer<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_x<span class="k2">(</span><span class="k2">)</span>, <span class="k2">(</span><span class="k3">*</span>it_outer<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_x<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">)</span>, Placement<span class="k2">(</span>Vec2D<span class="k2">(</span><span class="k2">(</span><span class="k3">*</span>it_inner<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_x<span class="k2">(</span><span class="k2">)</span>, <span class="k2">(</span><span class="k3">*</span>it_inner<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_x<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">25</td><td>          <span class="k1">if</span> <span class="k2">(</span>collision.IsCollision<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span></td></tr><tr><td class="number">26</td><td>          <span class="k2">{</span> <span class="c">// pixel-perfect hit detected</span></td></tr><tr><td class="number">27</td><td>            CCollision<span class="k3">*</span> collision <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">28</td><td>            <span class="k1">try</span></td></tr><tr><td class="number">29</td><td>            <span class="k2">{</span></td></tr><tr><td class="number">30</td><td>              collision <span class="k3">=</span> <span class="k1">new</span> CCollision<span class="k2">(</span><span class="k3">*</span>it_inner, <span class="k3">*</span>it_outer<span class="k2">)</span><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>            <span class="k1">catch</span> <span class="k2">(</span>CInvalidParameterException<span class="k3">&amp;</span> e<span class="k2">)</span></td></tr><tr><td class="number">33</td><td>            <span class="k2">{</span></td></tr><tr><td class="number">34</td><td>              CLog::write<span class="k2">(</span><span class="s">"Could not create collision: "</span> <span class="k3">+</span> e.get_message<span class="k2">(</span><span class="k2">)</span>, CLog::ERROR_<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">35</td><td>              <span class="k1">continue</span><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>&#160;</td></tr><tr><td class="number">38</td><td>            collisions.push_front<span class="k2">(</span>collision<span class="k2">)</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>        <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>  <span class="c">//CLog::write(collisions.size());</span></td></tr><tr><td class="number">44</td><td>&#160;</td></tr><tr><td class="number">45</td><td>  <span class="c">// process the collisions</span></td></tr><tr><td class="number">46</td><td>  <span class="k1">for</span> <span class="k2">(</span>list<span class="k3">&lt;</span>CCollision<span class="k3">*</span><span class="k3">&gt;</span><span class="k2">:</span><span class="k2">:</span>iterator it <span class="k3">=</span> collisions.begin<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>it <span class="k3">!</span><span class="k3">=</span> collisions.end<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span>it<span class="k3">+</span><span class="k3">+</span><span class="k2">)</span></td></tr><tr><td class="number">47</td><td>  <span class="k2">{</span></td></tr><tr><td class="number">48</td><td>    <span class="k1">if</span> <span class="k2">(</span><span class="k2">(</span><span class="k3">*</span>it<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_type<span class="k2">(</span><span class="k2">)</span> <span class="k3">=</span><span class="k3">=</span> CCollision::ENEMYSHIP_WITH_PLAYERBULLET<span class="k2">)</span></td></tr><tr><td class="number">49</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">50</td><td>      CShip<span class="k3">*</span> ship <span class="k3">=</span> <span class="k1">dynamic_cast</span><span class="k3">&lt;</span>CShip<span class="k3">*</span><span class="k3">&gt;</span><span class="k2">(</span><span class="k2">(</span><span class="k3">*</span>it<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_o1<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">51</td><td>      CBullet<span class="k3">*</span> bullet <span class="k3">=</span> <span class="k1">dynamic_cast</span><span class="k3">&lt;</span>CBullet<span class="k3">*</span><span class="k3">&gt;</span><span class="k2">(</span><span class="k2">(</span><span class="k3">*</span>it<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_o2<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">52</td><td>&#160;</td></tr><tr><td class="number">53</td><td>      ship-&gt;CHurtable::hurt<span class="k2">(</span>bullet-&gt;get_damage<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">54</td><td>      bullet-&gt;CDestroyable::set<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">55</td><td>&#160;</td></tr><tr><td class="number">56</td><td>      <span class="c">// explosion</span></td></tr><tr><td class="number">57</td><td>      CExplosion<span class="k3">*</span> explosion <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">58</td><td>      <span class="k1">try</span></td></tr><tr><td class="number">59</td><td>      <span class="k2">{</span></td></tr><tr><td class="number">60</td><td>        explosion <span class="k3">=</span> <span class="k1">new</span> CExplosion<span class="k2">(</span>bullet-&gt;get_explosion<span class="k2">(</span><span class="k2">)</span>, bullet-&gt;get_x<span class="k2">(</span><span class="k2">)</span>, bullet-&gt;get_y<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">61</td><td>      <span class="k2">}</span></td></tr><tr><td class="number">62</td><td>      <span class="k1">catch</span> <span class="k2">(</span>CInvalidParameterException<span class="k3">&amp;</span> e<span class="k2">)</span></td></tr><tr><td class="number">63</td><td>      <span class="k2">{</span></td></tr><tr><td class="number">64</td><td>        CLog::write<span class="k2">(</span><span class="s">"Failed to create new explosion: "</span> <span class="k3">+</span> e.get_message<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">65</td><td>      <span class="k2">}</span></td></tr><tr><td class="number">66</td><td>      CObjectList::o<span class="k2">(</span><span class="k2">)</span>.add<span class="k2">(</span>explosion<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">67</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">68</td><td>    <span class="k1">else</span> <span class="k1">if</span> <span class="k2">(</span><span class="k2">(</span><span class="k3">*</span>it<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_type<span class="k2">(</span><span class="k2">)</span> <span class="k3">=</span><span class="k3">=</span> CCollision::PLAYERSHIP_WITH_ENEMYBULLET<span class="k2">)</span></td></tr><tr><td class="number">69</td><td>    <span class="k2">{</span></td></tr><tr><td class="number">70</td><td>      CShip<span class="k3">*</span> ship <span class="k3">=</span> <span class="k1">dynamic_cast</span><span class="k3">&lt;</span>CShip<span class="k3">*</span><span class="k3">&gt;</span><span class="k2">(</span><span class="k2">(</span><span class="k3">*</span>it<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_o1<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">71</td><td>      CBullet<span class="k3">*</span> bullet <span class="k3">=</span> <span class="k1">dynamic_cast</span><span class="k3">&lt;</span>CBullet<span class="k3">*</span><span class="k3">&gt;</span><span class="k2">(</span><span class="k2">(</span><span class="k3">*</span>it<span class="k2">)</span><span class="k3">-</span><span class="k3">&gt;</span>get_o2<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">72</td><td>&#160;</td></tr><tr><td class="number">73</td><td>      ship-&gt;CHurtable::hurt<span class="k2">(</span>bullet-&gt;get_damage<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">74</td><td>      bullet-&gt;CDestroyable::set<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">75</td><td>&#160;</td></tr><tr><td class="number">76</td><td>      <span class="c">// explosion</span></td></tr><tr><td class="number">77</td><td>      CExplosion<span class="k3">*</span> explosion <span class="k3">=</span> <span class="n">0</span><span class="k2">;</span></td></tr><tr><td class="number">78</td><td>      <span class="k1">try</span></td></tr><tr><td class="number">79</td><td>      <span class="k2">{</span></td></tr><tr><td class="number">80</td><td>        explosion <span class="k3">=</span> <span class="k1">new</span> CExplosion<span class="k2">(</span>bullet-&gt;get_explosion<span class="k2">(</span><span class="k2">)</span>, bullet-&gt;get_x<span class="k2">(</span><span class="k2">)</span>, bullet-&gt;get_y<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">81</td><td>      <span class="k2">}</span></td></tr><tr><td class="number">82</td><td>      <span class="k1">catch</span> <span class="k2">(</span>CInvalidParameterException<span class="k3">&amp;</span> e<span class="k2">)</span></td></tr><tr><td class="number">83</td><td>      <span class="k2">{</span></td></tr><tr><td class="number">84</td><td>        CLog::write<span class="k2">(</span><span class="s">"Failed to create new explosion: "</span> <span class="k3">+</span> e.get_message<span class="k2">(</span><span class="k2">)</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">85</td><td>      <span class="k2">}</span></td></tr><tr><td class="number">86</td><td>      CObjectList::o<span class="k2">(</span><span class="k2">)</span>.add<span class="k2">(</span>explosion<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">87</td><td>    <span class="k2">}</span></td></tr><tr><td class="number">88</td><td>    <span class="k1">delete</span> <span class="k2">(</span><span class="k3">*</span>it<span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">89</td><td>  <span class="k2">}</span></td></tr><tr><td class="number">90</td><td>&#160;</td></tr><tr><td class="number">91</td><td>  collisions.clear<span class="k2">(</span><span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">92</td><td><span class="k2">}</span></td></tr></tbody></table></div></div><p>

In the first part, I check all objects for collisions and create CCollision-objects which are saved in a temporary list. In the second part, I handle all the collisions based on it&#39;s type.</p><p>Works quite nice, so I am pleased. <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" /></p><p>edit: damn, piccolo you are random!
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (imaxcs)</author>
		<pubDate>Sun, 11 Feb 2007 00:19:16 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>I suppose that could work, assuming all projectiles are implemented as &#39;bullets&#39;.  You&#39;ve sorted created your own OOP paradigm without using C++ syntax.</p><p>std::lists are quite bloated by the way, using them might hurt your fps.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Tue, 13 Feb 2007 01:26:40 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
std::lists are quite bloated by the way, using them might hurt your fps.
</p></div></div><p>
How so? A list uses some extra memory for the list structure (3 pointers per node plus 2 for the head and tail nodes IIRC, so 12n + 8 bytes of overhead for n objects on a typical 32 bit system), true. But it all depends on what you are doing.</p><p>Lots of random insertions / deletions? Lists are your friend. The time you save in memory reallocation due to vector resizing should easily compensate for the memory overhead, unless we&#39;re talking thousands and thousands of objects.<br />OTOH, if you can live without random insertion, and use &quot;dead&quot; flags for an en-bloq deletion (by copying the live objects to a new vector), a vector or some other type of dynamic array may be faster. A custom dynamic array can sometimes exploit some special properties of your objects, which allows for certain optimizations (e.g. short-circuiting some loops); this may or may not increase your performance. (If your custom dynamic array is badly sub-optimal, it might actually be slower than any STL container...)<br />I suggest you code in a way that allows for easy switching between the two container types, and let the profiler decide.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Tobias Dammers)</author>
		<pubDate>Tue, 13 Feb 2007 03:17:45 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>std::list goes out of the way to support a large number of features.  This bloat has a high cost.  If you can manage to make your list simpler and not require these advanced features you will be saving a lot of overhead.</p><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
How so? A list uses some extra memory for the list structure (3 pointers per node plus 2 for the head and tail nodes IIRC, so 12n + 8 bytes of overhead for n objects on a typical 32 bit system), true. But it all depends on what you are doing.
</p></div></div><p>
Yes there is some memory overhead and something tells me its larger then this (maybe some test-cast programs are in order?) but memory is not my main concern.</p><p>iterating a list is costly, with at the very least a pointer lookup per iteration.  A pointer lookup typically will cost you a whole cycle.  So the overhead is in actually <b>iterating</b> the list, not insertion and deletion.</p><p>If you must insert randomly and require deletes to happen instantly, then you will be forced to use std::list.  But an experienced coder will realize that most list uses can be achieved without these two requirements.</p><p>Lets take an example.  Say you had a particle engine.  Particle engines are always trying to cram more particles and more effects into the game without hurting the frame rate.  Every little bit of optimization counts.</p><p>In order to avoid having to resize your list, you can employ a simple trick of adding a flag to each particle object specifying if its alive or not.  Instead of actually removing the element and reallocating the whole array, you can simply flag the element as dead and re-use it when you have to create new particles later on.</p><p>This technique is used in a project I&#39;m working on currently.  I&#39;m going to report the FPS for level 1 during normal place as well as the particle count.  I&#39;m then going to switch over to a std::list type and report the same results.  (I&#39;ll put them in my next post / edit).</p><p>[edit]<br />Alright, using the as-is vector style:<br />58 particles on screen = 95 fps<br />Using list:<br />51 particles on screen = 91 fps</p><p>So the difference isn&#39;t amazingly large in this case, but the more particles the more dramatic the effect.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Wed, 14 Feb 2007 00:53:34 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>Ah, but if you had 1000 particles with only the last one flagged as on it would take 1000 iterations to get to it.  If you used a list where you removed dead particles it would take only one.  You can go in circles trying to figure which is better but it&#39;s &#39;Horses for courses&#39; in the end. </p><p>BTW.  My particle engine does the same as your&#39;s (uses flags) but I use what I call &#39;Particle Trees&#39; which are groups of particles (ie. explosion tree, snow tree).  When all the particles are dead the tree is killed.  Particle &#39;Trees&#39; are created in the Entity List (along with ememies, items etc) which is a linked list (beacause it changes a lot dynamically).  Best of both worlds. <img src="http://www.allegro.cc/forums/smileys/wink.gif" alt=";)" />
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matt Weir)</author>
		<pubDate>Wed, 14 Feb 2007 03:34:34 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><p>It&#39;s funny, but I had the same problem and with the same type of objects. Let&#39;s say it was something similar to Asteroids. Every object in the game was moving so every collision &quot;A with B&quot; is important. I partially solved the collision response problem without the dynamic_cast stuff. It should be faster. Here&#39;s what I&#39;ve got:</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> Object</td></tr><tr><td class="number">2</td><td><span class="k2">{</span></td></tr><tr><td class="number">3</td><td>public:</td></tr><tr><td class="number">4</td><td>  <span class="k1">virtual</span> <span class="k1">bool</span> Call<span class="k2">(</span> Object <span class="k3">*</span>that <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">5</td><td>  <span class="k1">virtual</span> <span class="k1">bool</span> Bounce<span class="k2">(</span> Object <span class="k3">*</span>that <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">6</td><td>  <span class="k1">virtual</span> <span class="k1">bool</span> Bounce<span class="k2">(</span> Bonus <span class="k3">*</span>that <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">7</td><td>  <span class="k1">virtual</span> <span class="k1">bool</span> Bounce<span class="k2">(</span> Bullet <span class="k3">*</span>that <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">8</td><td>  <span class="k1">virtual</span> <span class="k1">bool</span> Bounce<span class="k2">(</span> Ship <span class="k3">*</span>that <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">9</td><td><span class="k2">}</span><span class="k2">;</span></td></tr><tr><td class="number">10</td><td>&#160;</td></tr><tr><td class="number">11</td><td><span class="k1">class</span> Bullet: <span class="k1">public</span> Object</td></tr><tr><td class="number">12</td><td><span class="k2">{</span></td></tr><tr><td class="number">13</td><td>  <span class="k1">bool</span> Call<span class="k2">(</span> Object <span class="k3">*</span>that <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">14</td><td>  <span class="k1">bool</span> Bounce<span class="k2">(</span> Object <span class="k3">*</span>that <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">15</td><td>  <span class="k1">bool</span> Bounce<span class="k2">(</span> Bonus <span class="k3">*</span>that <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">16</td><td>  <span class="k1">bool</span> Bounce<span class="k2">(</span> Bullet <span class="k3">*</span>that <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">17</td><td>  <span class="k1">bool</span> Bounce<span class="k2">(</span> Ship <span class="k3">*</span>that <span class="k2">)</span><span class="k2">;</span></td></tr><tr><td class="number">18</td><td><span class="k2">}</span><span class="k2">;</span></td></tr><tr><td class="number">19</td><td>&#160;</td></tr><tr><td class="number">20</td><td><span class="c">// the same for other classes...</span></td></tr></tbody></table></div></div><p>

Than in the game:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">if</span><span class="k2">(</span> Collision<span class="k2">(</span>object1,object2<span class="k2">)</span> <span class="k2">)</span>
<span class="k2">{</span>
  <span class="c">// if both functions return true the physics response is applied</span>
  <span class="k1">if</span><span class="k2">(</span> object1-&gt;Call<span class="k2">(</span>object2<span class="k2">)</span> <span class="k3">&amp;</span><span class="k3">&amp;</span> object2-&gt;Call<span class="k2">(</span>object1<span class="k2">)</span> <span class="k2">)</span>
    Physics<span class="k2">(</span>object1,object2<span class="k2">)</span><span class="k2">;</span>
<span class="k2">}</span>
</pre></div></div><p>


And here&#39;s how it works. The Call function calls the Bounce function of the other object, i.e.:</p><div class="source-code snippet"><div class="inner"><pre><span class="k1">bool</span> Bullet::Call<span class="k2">(</span> Object <span class="k3">*</span>object <span class="k2">)</span>
<span class="k2">{</span>
  object-&gt;call<span class="k2">(</span><span class="k1">this</span><span class="k2">)</span><span class="k2">;</span>
  <span class="k1">return</span> <span class="k1">false</span><span class="k2">;</span> <span class="c">// the bullet dies so it doesn't need to bounce off</span>
<span class="k2">}</span>
</pre></div></div><p>

Since the functions are overloaded there is no need to check the object type. If the bullet::call was called and the object was a ship then the ship::bounce( *bullet ) function will be called. I hope it&#39;s quite clear.</p><p>The obvious drawback is that when you have X different objects you&#39;ll end up writing X^2 functions. I have some other solutions, but I have to think them over.
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (_lican)</author>
		<pubDate>Sat, 17 Feb 2007 05:19:08 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
Ah, but if you had 1000 particles with only the last one flagged as on it would take 1000 iterations to get to it.
</p></div></div><p>
This argument doesn&#39;t hold up because I loop every particle updating them every frame.  Things like making the particle move etc.  During that &#39;update&#39; I also check for dead and flag if necessary.</p><p>On top of that, iterating to the last element in a vector is two instructions: Adding and a pointer lookup.  A list lookup of the end is one instruction: a pointer lookup.</p><p>Since a pointer lookup will halt the branching, the time needed for these two operations is exactly the same. *</p><p>But no one ever needs to access particles in that fashion anyway.</p><ul><li><p>Corrected, although I still feel like I&#39;m wording this slightly wrong.
</p></li></ul></div>]]>
		</description>
		<author>no-reply@allegro.cc (ImLeftFooted)</author>
		<pubDate>Sat, 17 Feb 2007 07:13:13 +0000</pubDate>
	</item>
	<item>
		<description><![CDATA[<div class="mockup v2"><div class="quote_container"><div class="title">Quote:</div><div class="quote"><p>
This argument doesn&#39;t hold up because I loop every particle updating them every frame...
</p></div></div><p>

I apologise, I misinterperated exactly how you were doing it.  <img src="http://www.allegro.cc/forums/smileys/smiley.gif" alt=":)" />  I think we&#39;re both on the same track or very close anyway.  Carry on all...
</p></div>]]>
		</description>
		<author>no-reply@allegro.cc (Matt Weir)</author>
		<pubDate>Sun, 18 Feb 2007 15:24:38 +0000</pubDate>
	</item>
</rss>
