Making a Space Invaders clone with PushButton – Killing the Player

Google+ Pinterest LinkedIn Tumblr +

PLAY THE DEMO

DOWNLOAD THE SOURCE CODE

RETURN TO THE TUTORIAL INDEX

Thanks to the physics engine when the player and an enemy collide the enemy will push the player out of the way. In space invaders the game should end when the enemy and player collide, so we need to add a component that will cause both the player and the enemy to explode on contact.

This is slightly different to the health system used in the collision between an enemy and the players bullets. In that scenario the bullet will subtract some health from the enemy, and should the enemies health reach 0 the HealthComponent will then destroy the enemy entity and dispatch an event to let other components know that the entity has died. At this point the enemy has 1 unit of heath, and the bullets subtract 1 unit of health, so the end result is that the enemies will die with one shot. But in future we may want to add enemies that take two or more shots, and thanks to the HealthComponent that can be done by modifying one XML element.

By contrast a collision between a player and an enemy should always result in both being destroyed. To implement this a new component called DeathOnContactComponent is created.

DeathOnContactComponent.as

public class DeathOnContactComponent extends EntityComponent
{

The deathCollisionTypes collection holds the names of the entities that will cause this entity to be destroyed when they collide with it.

 public var deathCollisionTypes:Array;

 public function DeathOnContactComponent()
 {
  super();
 }
 
 protected override function onAdd():void
 {
  super.onAdd();
  
  owner.eventDispatcher.addEventListener(CollisionEvent.COLLISION_EVENT, OnCollision);
 }
 
 protected override function onRemove():void
 {
  super.onRemove();
  
  owner.eventDispatcher.removeEventListener(CollisionEvent.COLLISION_EVENT, OnCollision);
 }
 

In the onCollision function we find the Box2DSpatialComponent of the colliding entity (remember that you can’t assume that event.collidee or event.collider will consistently refer to the other entity), and then we find out if the other entity’s collision name is a match for one of those in the deathCollisionTypes collection.

 private function OnCollision(event:CollisionEvent):void
 {
  var mySpatial:Box2DSpatialComponent = owner.lookupComponentByType(Box2DSpatialComponent) as Box2DSpatialComponent;
  var other:Box2DSpatialComponent = event.collidee === mySpatial?event.collider:event.collidee;   
  
  for each (var collisionType:String in deathCollisionTypes)
  { 
   if (ObjectTypeManager.instance.doesTypeOverlap(other.collisionType, collisionType))
   {


If so we dispatch an event similar to what the HealthComponent would trigger if it were to kill an entity. In this way those components that watch for the entity to die, like the DeathHandlerComponent, will also work when the entity dies due to a collision.

    var healthEvent:HealthEvent = new HealthEvent(HealthComponent.DIED, 0, 0, other.owner);
    owner.eventDispatcher.dispatchEvent(healthEvent);

And of course the entity is destroyed.

    owner.destroy();
    break;  
   }    
  }       
 } 

The DeathHandlerComponent gets a new variable called entityToCreateOnDeath that allows us to specify what entity will be created when an entity dies. This will allow us to create different explosions for the enemies and the player (since the player is a bigger sprite).

DeathHandlerComponent.as

public class DeathHandlerComponent extends EntityComponent
{
 public var PositionReference:PropertyReference = null;
 public var entityToCreateOnDeath:String;
 
 public function DeathHandlerComponent()
 {
  super();
 }
 
 protected override function onAdd():void
 {
  super.onAdd();
  
  owner.eventDispatcher.addEventListener(HealthComponent.DIED, onDied);
 }
 
 protected override function onRemove():void
 {
  super.onRemove();
  owner.eventDispatcher.removeEventListener(HealthComponent.DIED, onDied);
 }
 
 protected function onDied(event:Event):void
 {
  var position:Point = owner.getProperty(PositionReference);
  var entity:IEntity = TemplateManager.instance.instantiateEntity(entityToCreateOnDeath);
  if (entity != null)
  {
   var spatial:Box2DSpatialComponent = 
    entity.lookupComponentByType(Box2DSpatialComponent) as Box2DSpatialComponent;
   var simpleSpatial:SimpleSpatialComponent = 
    entity.lookupComponentByType(SimpleSpatialComponent) as SimpleSpatialComponent;
    
   if (spatial != null)
   {
    spatial.position = new Point(position.x, position.y);
   }
   else if (simpleSpatial != null)
   {
    simpleSpatial.position = new Point(position.x, position.y);
   }
  } 
 }
 
}

The enemy and the player templates both get the new DeathOnContactComponent component.

Code

The Player also gets the DeathHandlerComponent, which is set to create the new PlayerExplosion entity when the player dies (the PlayerExplosion template is exactly the same as the Explosion template, expect that it references a different SpriteSheet).

Code

Share.

About Author

Leave A Reply