Creating a game on Google Android game with Flixel - Enemies

Jan 5th, 2010 by mcasperson

In this tutorial we add some enemies for the player to avoid.

DOWNLOAD THE SOURCE CODE

VIEW THE VIDEO

RETURN TO THE TUTORIAL INDEX

For this demo we will create a few platforms for the enemies to move along. To do this we simply create more FlxBlock objects in the GameState constructor, just like we did with the ground. We will also create a new Enemy object with each of these platforms. Notice that the new Enemy objects are added to their own collection called enemies. This is so we can test for collisions between the enemies and the player as a group.

GameState.java

 public GameState()
 {
  levelBlocks.add(this.add(new FlxBlock(0, 640-16, 640, 16)
    .loadGraphic(R.drawable.tech_tiles)));
  levelBlocks.add(this.add(new FlxBlock(0, 0, 640, 16)
    .loadGraphic(R.drawable.tech_tiles)));
  levelBlocks.add(this.add(new FlxBlock(0, 16, 16, 640-32)
    .loadGraphic(R.drawable.tech_tiles)));
  levelBlocks.add(this.add(new FlxBlock(640-16, 16, 16, 640-32)
    .loadGraphic(R.drawable.tech_tiles)));
  
  for (int i = 0; i < 4; ++i)
  {
   levelBlocks.add(this.add(new FlxBlock(
    320 - 48 - 32*i, 
    640 - 48 - 48*i, 
    320, 16)
    .loadGraphic(R.drawable.tech_tiles)));
   enemies.add(this.add(new Enemy(
    320 - 48 - 32*i, 
    640 - 48 - 48*i, 
    320)));
  }
   
  player = new Player();
  this.add(player);
  FlxG.follow(player, 2.5f);
  FlxG.followAdjust(0.5f, 0.0f);
  FlxG.followBounds(0, 0, 640, 640);
  
  FlxG.playMusic(R.raw.mode);
 }

In the update function we test for collisions between the player and the enemies in much the same way as we did between the player and the blocks. The big difference is that the collideArrayList function will prevent two objects from colliding my moving one colliding object out of the other. The overlapArrayList allows us to implement our own collision response. In the original ActionScript you would supply a function that would be called in the event of a collision. In Java we use an anonymous inline class that implements the FlxCollideListener interface. In the Collide function we use the players kill function to signal that the player should be killed, and fade the screen out by calling the FlxG fade function. Again we use an anonymous inline class, this time implementing the FlxFadeListener interface, to drop us back to the MenuState when the screen has completely faded out.

 public void update()
 {
  super.update();
  FlxG.collideArrayList(levelBlocks, player);
  FlxG.overlapArrayList(enemies, player, new FlxCollideListener(){
    public void Collide(FlxCore object1, FlxCore object2)
    {
     player.kill();
     FlxG.fade(0xffd8eba2,3, new FlxFadeListener()
      {
       public void fadeComplete()
       {
        FlxG.switchState(MenuState.class);
       }
      }
     );
    }
   }  
  );
 }

When the player dies it will release a shower of gibs. This effect is created using the FlxEmitter class. In the Player class constructor we create a new FlxEmitter, which will sit dormant until we fire it up.

Player.java

 public Player()
 {
  super(PLAYER_START_X, PLAYER_START_Y, R.drawable.spaceman, true);
  
  drag.x = PLAYER_RUN_SPEED * 8;
  acceleration.y = GRAVITY_ACCELERATION;
  maxVelocity.x = PLAYER_RUN_SPEED;
  maxVelocity.y = JUMP_ACCELERATION;
  
  addAnimation("idle", new ArrayList(Arrays.asList(new Integer[] {0})));
  addAnimation("run",  new ArrayList(Arrays.asList(new Integer[] {1, 2, 3, 0})), 12);
  addAnimation("jump",  new ArrayList(Arrays.asList(new Integer[] {4})));
  addAnimation("idle_up",  new ArrayList(Arrays.asList(new Integer[] {5})));
  addAnimation("run_up",  new ArrayList(Arrays.asList(new Integer[] {6, 7, 8, 5})), 12);
  addAnimation("jump_up",  new ArrayList(Arrays.asList(new Integer[] {9})));
  addAnimation("jump_down",  new ArrayList(Arrays.asList(new Integer[] {10})));
  
  this.gibs = FlxG.state.add(
   new FlxEmitter(0, 0, -1.5f)
    .setXVelocity(-150.0f, 150.0f)
    .setYVelocity(-200.0f, 0.0f)
    .setRotation(-720, 720)
    .setGravity(400)
    .createSprites(R.drawable.enemygibs));
 }

In the Player class we now override the kill function. It is here that we reposition the FlxEmitter to the players current position and start it by calling the restart function. The >> operator is a bit shift, which has the effect of halving a integers value, so width>>1 returns half of width.

 public void kill()
 {
  super.kill();
  
  this.gibs.x = this.x + (this.width>>1);
  this.gibs.y = this.y + (this.height>>1);
  this.gibs.restart();
 }

The Enemy class represents the enemies on the screen. Most of the code in the Enemy class is similar to the Player class: it extends the FlxSprite, sets up the physics of the object and defines and plays some animations.

Enemy.java

package org.myname.flixeldemo;

import java.util.ArrayList;
import java.util.Arrays;

import org.flixel.FlxSprite;

public class Enemy extends FlxSprite 
{
 protected static final float VELOCITY = 150;
 protected int maxXMovement = 0;
 protected int startX = 0;
 
 public Enemy(int x, int y, int maxXMovement)
 {
  super(x, y, R.drawable.enemy, true);
  
  this.y -= this.height;
  this.maxXMovement = maxXMovement - this.width;
  this.startX = x;
  this.velocity.x = VELOCITY;
    
  addAnimation("idle", new ArrayList(Arrays.asList(new Integer[] {0, 1})), 12);
  
  play("idle");
 }

The update function is used to move the enemies horizontally on the screen, reversing direction when they reach the end of the underlying platform.

 public void update()
 {
  super.update();
  
  if (this.x - startX >= maxXMovement ||
   this.x  <= startX)
  {
   this.velocity.x = -this.velocity.x;
  }
 }
}
mcasperson

Written by mcasperson

Rate this Article:

Rating: 5.0/5 (3 votes cast)

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