Creating a game on Google Android game with Flixel – Adding a player

Google+ Pinterest LinkedIn Tumblr +

DOWNLOAD THE SOURCE CODE

SEE A VIDEO OF THE DEMO

RETURN TO THE TUTORIAL INDEX

The last article showed you how to get a minimal Flixel game running on Android. Here we will add a player controlled character that will run and jump on the screen.

First we need a way to move from the MenuState to a new state called GameState. To do this we override the update function in the MenuState class and watch for a keypress which we will use as a trigger to swap to the GameState.

Most of the Flixel classes have an update function, and it is in this function that an object can update itself, usually by modifying the underlying physics properties like acceleration and velocity and (as is the case here) watching for input.

For those not familiar with Flixel, FlxG is a kind of utility class that contains a number of static functions and properties giving the developer easy access to things like state changes, keyboard input and more.

MenuState.java

package org.myname.flixeldemo;

import org.flixel.*;

import android.view.KeyEvent;

public class MenuState extends FlxState 
{
 public MenuState()
 {
  super();
  add(new FlxText(10, 10, 250, "Press the center DPad key to continue."));
 }
 
 public void update()
 {
  super.update();
  if (FlxG.keys.justPressed(KeyEvent.KEYCODE_DPAD_CENTER))
   FlxG.switchState(GameState.class);
 }
}

Obviously we now need a state called GameState to switch to.

GameState.java

package org.myname.flixeldemo;

import java.util.ArrayList;

import org.flixel.*;

Just like the MenuState, the GameState class extends the FlxState class.

public class GameState extends FlxState 
{
 protected ArrayList levelBlocks = new ArrayList();
 protected Player player = null;

 public GameState()
 {

The level is made up of FlxBlock objects, which are blocks that are placed in the level space. These blocks are used in collision detection to give the player a surface to walk on. Here we create a long horizontal block to serve as the ground, load the tech_tiles.png image to display the block, and then add the block to both to the state (all objects that need to be rendered and updated need to be added to the state) and a local collection called levelBlocks.

  FlxBlock ground = new FlxBlock(0, 640-16, 640, 16);
  ground.loadGraphic(R.drawable.tech_tiles);
  levelBlocks.add(this.add(ground));

We then create a new player object, which will be detailed later. We then ask Flixel to keep the player in front of the “camera” using the FlxG follow function. The followAdjust function makes the camera lag behind the movement of the player slightly, while the followBounds function defines the limit of the cameras movement across the level.

  player = new Player();
  this.add(player);
  FlxG.follow(player, 2.5f);
  FlxG.followAdjust(0.5f, 0.0f);
  FlxG.followBounds(0, 0, 640, 640);

Finally we play some background music.

  FlxG.playMusic(R.raw.mode);
 }

In the update function we need to check for a collision between the player and the blocks that make up the level. The collideArrayList function will test the players position against the level blocks (this is why we added the blocks to a local collection), and will push the player out of the blocks if there is a collision.

 public void update()
 {
  super.update();
  FlxG.collideArrayList(levelBlocks, player);
 }
}

The Player class represents the player on the screen.

Player.java

package org.myname.flixeldemo;

import java.util.ArrayList;
import java.util.Arrays;
import android.view.*;

import org.flixel.*;

We extend the FlxSprite class, which will allow us to draw a static or animated sprite on the screen.

public class Player extends FlxSprite
{
 protected static final int PLAYER_START_X = 300;
 protected static final int PLAYER_START_Y = 300;
 protected static final int PLAYER_RUN_SPEED = 80;
 protected static final float GRAVITY_ACCELERATION = 420;
 protected static final float JUMP_ACCELERATION = 200;
 
 public Player()
 {

We start by calling the underlying FlxSrpite constructor, passing in the initial position of the sprite, the image that will be used to display the sprite, and true to indicate that the sprite should be automatically reversed when it is facing left (by default the source images for all Flixel sprites should be drawn facing right).

  super(PLAYER_START_X, PLAYER_START_Y, R.drawable.spaceman, true);

The physics for the player are defined. The drag, maxVelocity and acceleration defines how the player will move and fall in the level.

  drag.x = PLAYER_RUN_SPEED * 8;
  acceleration.y = GRAVITY_ACCELERATION;
  maxVelocity.x = PLAYER_RUN_SPEED;
  maxVelocity.y = JUMP_ACCELERATION;

The final step is to define the animations and the frames that they will use from the source image that is used to display the sprite. You can see this image here.

As you can see this image is like a film strip. Each of these individual frames of animation are mapped to an animation like “run” or “fall”. The code to initialise a Java collection from an inline array is a little messy, but all we are doing is saying something like “map frames 0, 1, 2 to the animation called run”.

  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})));
 }

In the update function we use the keyboard input to modify the acceleration and velocity of the player, which will in turn be used to modify the position of the player on the screen.

 public void update()
 {
  acceleration.x = 0;
  if(FlxG.keys.pressed(KeyEvent.KEYCODE_DPAD_LEFT))
  {
   setFacing(LEFT);
   acceleration.x = -drag.x;
  }
  else if(FlxG.keys.pressed(KeyEvent.KEYCODE_DPAD_RIGHT))
  {
   setFacing(RIGHT);
   acceleration.x = drag.x;
  }
  if(FlxG.keys.justPressed(KeyEvent.KEYCODE_DPAD_UP) && velocity.y==0)
  {
   velocity.y = -JUMP_ACCELERATION;
  }

We then use the velocity of the player to determine which animation should be playing.

  if(velocity.y != 0)
  {
   play("jump");
  }
  else if(velocity.x == 0)
  {
   play("idle");
  }
  else
  {
   play("run");
  }
  
  super.update();
 }
}

Share.

About Author

Leave A Reply