Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to avoid casting from interface to class
    primarykey
    data
    text
    <p>In trying to design a collision detection component for a game, I came up with the following solution. I define an interface ICollideable that looks something like:</p> <pre><code>interface ICollideable { Sprite Sprite { get; } int Damage { get; } void HandleCollision(ICollideable collidedWith); } </code></pre> <p>Basically, any game objects that want to participate in collision detection have to implement this interface, then register themselves with the detector, which maintains a list of ICollideables. When it detects a collision, it calls the HandleCollision method on the object and passes in a reference to the object it collided with.</p> <p>I like this, because it lets me keep all my collision algorithms in one place, and lets the game objects themselves decide how to handle the collision. But because of the latter, I find I am having to check the underlying object type. For example, I don't want Players to collide with each other, so in the Player class there might be something like:</p> <pre><code>void HandleCollision(ICollideable collidedWith) { if (!(collidedWith is Player)) { // do stuff } } </code></pre> <p>and so on, and I am wondering if this is telling me that I have a bad design and what the alternatives might be.</p> <p>Second question, further along the lines of the first. For scoring purposes, if an Enemy is destroyed by a Projectile, someone needs to know the "Owning Player" member of the Projectile class. However, none of my other collideables have or need this property, so I find myself wanting to do (in the Enemy HandleCollision):</p> <pre><code>void HandleCollision(ICollideable collidedWith) { if (collidedWith is Projectile) { Health -= collidedWith.Damage; if (Health &lt;= 0) { Player whoDestroyedMe = (collidedWith as Projectile).FiredBy // ... } } } </code></pre> <p>I haven't a clue as to how to handle this with a better design. Any insights would be appreciated.</p> <p><em>EDIT:</em> I wanted to pull focus towards the second question, because my gut tells me a way of handling this will solve the first question. As for the first question, I thought of a way to abstract this behavior. I could define an enum:</p> <pre><code>enum Team { Player, Enemy, Neither } </code></pre> <p>and have ICollideables implement this property. Then the collision detector simply doesn't register collisions between collideables on the same "Team". So, Player and Player Projectiles would be on one team, Enemy and Enemy Projectiles on the other, and the environment (which can damage both) can be on neither. It doesn't have to be an enum, could be an int or a string or anything, with the idea that objects with the <em>same value</em> for this property do not collide with each other.</p> <p>I like this idea of modeling behavior with a simple attribute. For instance, if I want to turn "allow friendly fire" on, all I have to do is create Projectiles with a Team value other than the Player's Team value. However, I <em>still</em> may have cases where this is not enough. For example, a Player may have shields that are temporarily impervious to projectiles but will not protect against a direct collision with an enemy, and so on.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload