AndEngine Tutorials
Contact me!
  • Blog
  • Tutorials
  • Devices Library
  • Newsletter
  • Download
  • Contact
  • My Work
  • About me

Part 12. Creating player.


In this part of my tutorial series, we will take care about creating our player code. As I mentioned in  previous article, I will not bother to create nice looking art, because this tutorial is created for code learning purposes only. This is art for player I will use:
Picture
It has only three tiles, but should be enough for sample run animation, in our game player will automatically run in right direction, player will control jump function.

1. Loading player resources:

Open our ResourcesManager class, create new variable for player texture  tiled region:
public ITiledTextureRegion player_region;
  • lets load this region, inside our loadGameGraphics() method:

player_region = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(gameTextureAtlas, activity, "player.png", 3, 1);

Do not forget to put players graphic inside assets/gfx/game directory. As you can see, we loaded players graphic, it has 3 columns, and 1 row.

2. Creaing Player code:


We created code responsible for loading player`s graphic, now lets take care about player`s class. Create new class called Player extended by AnimatedSprite. You will be forced by eclipse to add constructor. We will modify constructor little bit.

package com.matimdev.object;

import org.andengine.engine.camera.Camera;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.extension.physics.box2d.PhysicsWorld;
import org.andengine.opengl.vbo.VertexBufferObjectManager;

import com.matimdev.manager.ResourcesManager;

/**
 * @author Mateusz Mysliwiec
 * @author www.matim-dev.com
 * @version 1.0
 */
public abstract class Player extends AnimatedSprite
{
    // ---------------------------------------------
    // CONSTRUCTOR
    // ---------------------------------------------
    
    public Player(float pX, float pY, VertexBufferObjectManager vbo, Camera camera, PhysicsWorld physicsWorld)
    {
        super(pX, pY, ResourcesManager.getInstance().player_region, vbo);
    }
}

We made this class abstract, because we will create some abstract methods. 
As mentioned we modified constructor little bit, as a texture region, we used previously create texture region from our resources manager. We will need also some new parameters, such as camera and physics world.

  • create new field for our player body:

// ---------------------------------------------
// VARIABLES
// ---------------------------------------------
    
private Body body;

  • create new abstract method onDie() we will execute it when certain events will occur.

public abstract void onDie();

  • create new boolean to flag if player can jump (as I said, if player will firstly touch screen, we will make player run, and after that every next touch will make player jump) here`s method responsible for creating physics body for player:

private boolean canRun = false;


private void createPhysics(final Camera camera, PhysicsWorld physicsWorld)
{        
    body = PhysicsFactory.createBoxBody(physicsWorld, this, BodyType.DynamicBody, PhysicsFactory.createFixtureDef(0, 0, 0));

    body.setUserData("player");
    body.setFixedRotation(true);
    
    physicsWorld.registerPhysicsConnector(new PhysicsConnector(this, body, true, false)
    {
        @Override
        public void onUpdate(float pSecondsElapsed)
        {
            super.onUpdate(pSecondsElapsed);
            camera.onUpdate(0.1f);
            
            if (getY() <= 0)
            {                    
                onDie();
            }
            
            if (canRun)
            {    
                body.setLinearVelocity(new Vector2(5, body.getLinearVelocity().y)); 
            }
        }
    });
}

What we just did there? We initialized players body, set user data so we can latter recognise this body in certain events (such as contact between bodies detection), we also set fixed body rotation, so body will not rotate. Latter we registered physics connector (so player`s sprite, will automatically update its position, following body updates) inside we override onUpdate() method, and used camera onUpdate method, it helps to reduce camera "jitering" effect while moving. On the end, we created code checking player`s Y coordinate, if player`s Y is less than 0, onDie will be executed.  We also check if canRun boolean returns true, and if yes we set linear velocity on the X axis to stimulate run.

  • execute this method inside constructor. Lets also add code setting camera`s chase entity, so camera will follow player`s position.

public Player(float pX, float pY, VertexBufferObjectManager vbo, Camera camera, PhysicsWorld physicsWorld)
{
    super(pX, pY, ResourcesManager.getInstance().player_region, vbo);
    createPhysics(camera, physicsWorld);
    camera.setChaseEntity(this);
}

  • create method responsible for setting player run and animate, we will execute this method, after player`s first touch of the scene. Latter, every next screen touch will cause player to jump.

public void setRunning()
{
    canRun = true;
        
    final long[] PLAYER_ANIMATE = new long[] { 100, 100, 100 };
        
    animate(PLAYER_ANIMATE, 0, 2, true);
}

We defined duration for each player`s tile/frame (in milliseconds)  used for animation, we also set player to animate (continuously by setting last parameter to true) animating player`s tiled region from first to last tile (means from 0 to 2, since first value starts from 0 not 1) On the end, we set linear velocity to the body on the X axis to set player running. 

  • create method responsible for jumping:

public void jump()
{
    body.setLinearVelocity(new Vector2(body.getLinearVelocity().x, 12)); 
}

We simply set some linear velocity on the Y axis, to stimulate player jump.
player.java
File Size: 2 kb
File Type: java
Download File


3. Initializing player on the scene:


We fully implemented player class logic, now lets initialize it on the scene, firstly we will take care about implementing possibility to catch scene touch events (to be able to execute player jump functionality)

  • open our GameScene class, and implement IOnSceneTouchListener class. You will be forced by eclipse to add unimplemented method.

public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent)
{
    if (pSceneTouchEvent.isActionDown())
    {

    }
    return false;
}

  • inside our createScene method, add this line to register this scene touch listener:

setOnSceneTouchListener(this);

  • lets take care about initializing player and placing it on the scene, create new field for player, and tag used for level loader.

private static final Object TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_PLAYER = "player";
    
private Player player;

  • add code responsible for initializing player inside level loader code, just like we did in previous article for loading platforms and coin from xml file:

else if (type.equals(TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_PLAYER))
{
    player = new Player(x, y, vbom, camera, physicsWorld)
    {
        @Override
        public void onDie()
        {
            // TODO Latter we will handle it.
        }
    };
    levelObject = player;
}

  • now simply open our level data file, and put line for our player:

<entity x="60" y="140" type="player"/>

After running game, we should be able to see player on our first platform.
Picture

4. Setting player run and allowing to jump:


Okay now when we finally have our player on the scene, lets take care about jump and run functions, as mentioned, our player will conterminously run (automatically) in the right direction, after FIRST touch of the screen, after that, every next touch will make player jump, quite simple I guess.  Lest create new boolean, flag to  know if it was first touch.

private boolean firstTouch = false;

  • now inside onSceneTouchEvent lets execute our logic:

public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent)
{
    if (pSceneTouchEvent.isActionDown())
    {
        if (!firstTouch)
        {
            player.setRunning();
            firstTouch = true;
        }
        else
        {
            player.jump();
        }
    }
    return false;
}

We check if firstTouch flag is false, if yes we set player running and change flag to true. If flag is true, every screen touch make player jump.

  • inside disposeScene() method lets add code responsible for removing chase entity.

camera.setChaseEntity(null);

Without that, after moving back to the menu scene, we would see black screens, because camera would still follow our player position.

That`s all in this article, after running our game code, you should be able to see player, after first screen touch player should start running, after each another should jump.

Notes: currently, player can jump infinity times, after touching ground first, it will be fixed in next article, where contact listener will be introduced. In next article we will also implement coin`s picking, player die, and camera bounds limits.

Previous article
Next article


HTML Comment Box is loading comments...
Powered by Create your own unique website with customizable templates.