Making a Space Invaders clone with PushButton - Enemy Bullets

Jan 18th, 2010 by mcasperson

In this tutorial we give the enemies the ability to shoot.

PLAY THE DEMO

DOWNLOAD THE SOURCE CODE

RETURN TO THE TUTORIAL INDEX

In the last tutorial we added a component to allow entities to be destroyed on collision. This bypassed the HealthComponent used by the enemy entities, but now we come full circle and add a HealthComponent to the player so it can be damaged by enemy’s bullets. Here we add the HealthComponent, and specify that the play has an initial health of 5.

Code

For the player to be shot we need to create a new entity template. This is almost an exact copy of the EnemyBullet template, except the entity type and collision types are changed to identify it as a bullet shot by an enemy and colliding with the player.

Code

EnemyControllerComponent.as

Just like the PlayerControllerComponent, which creates a new PlayerBullet entity when the space bar has been pressed, the EnemyControllerComponent will randomly create a new EnemyBullet entity.

The timeToNextShot variable, used to control the amount of time in between each possible firing of a bullet, is counted down to 0.

public override function onTick(tickRate:Number):void
{
 // ...
 
 timeToNextShot -= tickRate;
 timeToNextShot = timeToNextShot<0?0:timeToNextShot;

Once timeToNextShot reaches 0 the enemy will have a chance to fire a bullet. The timeToNextShot is reset to start the count down again.

 if (timeToNextShot == 0)
 {
  timeToNextShot = timeBetweenShots;

We want these shots to be random, so we use the chanceOfShot variable with the random function to determine if a shot should be taken. The following if statement has a 1 in chanceOfShot chance of being true.

  if (Math.round(Math.random() * chanceOfShot) == 0)
  {

Should the if statement be true a new instance of the EnemyBullet template is created, positioned and the velocity set.

   var bullet:IEntity = TemplateManager.instance.instantiateEntity(bulletEntityName);
   if (bullet != null)
   {
    var spatial:Box2DSpatialComponent = 
     bullet.lookupComponentByType(Box2DSpatialComponent) as Box2DSpatialComponent;
     
    spatial.position = new Point(position.x, position.y);
    spatial.linearVelocity = new Point(0, bulletSpeed);
   }  
  }
 }
}

We have to make a small change to the PlayerControllerComponent to stop the enemy bullets knocking the player off the screen. When two objects collide in a physics system they don’t just stop dead – unless they collide head on with equal force one will invariably bump the other into a new position, like two billiard balls. That is a natural reaction, but in our case we don’t want the enemy’s bullets pushing the player off the screen. Although it is a bit of a hack, and easy way to do this is to set the players vertical velocity to 0 each frame, and to set its y position to the y position that it was created at.

PlayerControllerComponent.as

protected override function onAdd():void
{
 super.onAdd();
 originalPosition = owner.getProperty(positionReference);
}

public override function onTick(tickRate:Number):void
{
 super.onTick(tickRate);
 
 var velocity:Point = owner.getProperty(velocityReference);
 var position:Point = owner.getProperty(positionReference);
 
 if (velocity == null || 
  position == null)
  return;  
  
 velocity.x = 0;
 position.y = originalPosition.y;  
 
 // ...   
}
mcasperson

Written by mcasperson

Rate this Article:

Be the first to rate me.

Add new comment

* You must be logged in order to leave comments, please Sign in or join us.

Comments

No comments yet, be the first to comment on this article.

Related Content