サイトのトップへ戻る

AndEngineドキュメント 日本語訳

Part 12. プレイヤーを作成する。

チュートリアル連載のこのページでは、プレイヤーのコードの作成について説明します。前回の記事で述べたように、このチュートリアルはコードの作成について学ぶことだけが目的なので、 見栄えのいい絵を作成したりしません。プレイヤーとして使用する絵は以下です:
Picture

この絵は三つのタイルしか持っていませんが、簡単な走行アニメーションには十分です。今回のゲームでは、プレイヤーは自動的に右方向へ走ります。プレイヤーはジャンプ機能を操作します。



1. プレイヤーのリソースを読み込む:
ResourcesManager クラスを開いて、player texture  tiled region用に新たに変数を作成します:
public ITiledTextureRegion player_region;
  • loadGameGraphics() メソッド内でこの領域を読み込みます:
    player_region = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(gameTextureAtlas, activity, "player.png", 3, 1);
    

assets/gfx/game ディレクトリ内にプレイヤー画像を配置するのを忘れないでください。 ご覧の通り、読み込んだプレイヤーの画像は3列と1行の構成になっています。



2. プレイヤーのコードを作成する:
プレイヤーの画像の読み込みを司るコードを作成しました。それでは、Playerクラスについて説明しましょう。 AnimatedSpriteを継承したPlayer という名前のクラスを新たに作成します。 eclipse によってコンストラクタの追加を求められるでしょう。今回はコンストラクタを少し編集します。
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);
    }
}

いくつか抽象メソッドを作成するので、このクラスを抽象クラスにします。 

前述のように、コンストラクタを少し編集しています。テクスチャ領域として、前に作成したresources managerのテクスチャ領域を使用しています。 camera やPhysics Worldのような、いくつかの新しいパラメータも必要です。

  • プレイヤーのbody用のフィールドを新たに作成します:
    // ---------------------------------------------
    // VARIABLES
    // ---------------------------------------------
        
    private Body body;
    
  • 抽象メソッド onDie() を新たに作成します。これは特定のイベントが発生した時に実行します。
    public abstract void onDie();
    
  • プレイヤーがジャンプできるかどうかを表すboolean型のフラグを新たに作成します(前に言ったように、あなたが最初に画面をタッチするとプレイヤーが走り出し、以降はタッチする度にプレイヤーがジャンプします)。 以下が、プレイヤーの物理Body作成を司るメソッドです:
    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)); 
                }
            }
        });
    }
    
ここで何をしたかと言うと。プレイヤーのbodyを初期化し、後で (body同士の接触検知のような)特定のイベント内でこのbodyを識別できるようにユーザーデータを設定し、 またbodyが回転しないように回転を固定しています。 後ほど physics connectorを登録します(body の更新に従って、プレイヤーのspriteが自動的に自分の位置を更新するようにするため) 。 onUpdate()メソッドを上書きして、中でcanmeraのonUpdate()メソッドを使用します。 こうすることで、移動中のcameraの"ジッタリング"効果を減らすことができます。 最後に、プレイヤーのY座標を確認するコードを作成します。プレイヤーのY座標が0以下の場合は、onDie()メソッドを実行します。 またcanRun()の値がtrueかどうかを確認し、tureの場合はX軸方向にlinear velocityを設定してプレイヤーを走らせます。
  • コンストラクタ内でこのメソッドを実行します。また、カメラの追跡用エンティティを追加するコードも追加します。これで、カメラはプレイヤーの位置を追いかけるようになります。
    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);
    }
    
  • プレイヤーの走行とアニメーションを司るメソッドを作成します。プレイヤーが最初に画面をタッチした後にこのメソッドを実行します。 以降は、画面をタッチする度にプレイヤーはジャンプをするようになります。
    public void setRunning()
    {
        canRun = true;
            
        final long[] PLAYER_ANIMATE = new long[] { 100, 100, 100 };
            
        animate(PLAYER_ANIMATE, 0, 2, true);
    }
    
アニメーションに使用される、プレイヤーのタイル画像の毎フレームごと(ミリ秒単位)の表示時間を定義します。 また、プレイヤーをアニメーションするように設定します (最後のパラメータにtrueを設定することで、アニメーションを続けます) 。アニメーションさせるプレイヤーのタイル画像には、最初のタイルから最後のタイルまでの範囲を指定します(最初の値は1ではなく0から始まるので、0から2の値を設定しています)。 最後に、bodyにX軸方向のlinear velocityを設定してプレイヤーを走らせます。 
  • ジャンプを司るメソッドを作成します:
    public void jump()
    {
        body.setLinearVelocity(new Vector2(body.getLinearVelocity().x, 12)); 
    }
    
    単純にY軸方向になんらかのlinear velocityを設定してプレイヤーをジャンプさせます。
player.java
ファイルをダウンロード


3. scene上でプレイヤーを初期化する:
Player クラスのロジックは完全に実装したので、それではscene上でそれを初期化しましょう。 まずは、シーンタッチイベントをキャッチする機能の実装について説明します (プレイヤーのジャンプ機能を実行できるようにするため)。
  • GameScene クラスを開いて、IOnSceneTouchListener クラスを実装します。 eclipse によって、未実装メソッドの追加を求められるでしょう。
    public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent)
    {
        if (pSceneTouchEvent.isActionDown())
        {
    
        }
        return false;
    }
    
  • createScene メソッド内に、このscene touch listenerを登録するための以下の一行を追加します:
    setOnSceneTouchListener(this);
    
  • プレイヤーの初期化とシーンへの配置について説明しましょう。プレイヤー用とステージを読み込むための使用するタグ用の新しいフィールドを作成します。
    private static final Object TAG_ENTITY_ATTRIBUTE_TYPE_VALUE_PLAYER = "player";
        
    private Player player;
    
  • ステージの読み込みコード内に、プレイヤーの初期化を司るコードを追加します。 xml から足場とコインを読み込んだ以前の記事でやったように:
    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;
    }
    
  • それでは、単純にステージデータのファイルを開き、プレイヤー用の以下一行を記載します。:
    <entity x="60" y="140" type="player"/>
    
ゲームを実行すると、一つ目の足場上にいるプレイヤーが表示されるでしょう。
Picture


4. プレイヤーを走らせ、ジャンプできるようにする:
さて、これで遂にプレイヤーをシーン上に設置できました。前に述べたように、ジャンプと走行機能について説明します。 最初に画面をタッチすると、プレイヤーは右方向に一直線に(自動的に)走ります。 その後、タッチする度にプレイヤーがジャンプします。とてもシンプルです。 それが一回目のタッチかどうかを記録するためのboolean型フラグを新規に作成しましょう。
private boolean firstTouch = false;
  • それでは、onSceneTouchEvent 内でこのロジックを実行しましょう:
    public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent)
    {
        if (pSceneTouchEvent.isActionDown())
        {
            if (!firstTouch)
            {
                player.setRunning();
                firstTouch = true;
            }
            else
            {
                player.jump();
            }
        }
        return false;
    }
    
    firstTouchフラグがfalseかどうかを確認し、falseだった場合はプレイヤーを走らせてflag をtrueに変更します。 フラグがtrueの場合は、スクリーンをタッチする度にプレイヤーをジャンプさせます。
  • disposeScene() メソッド内に、追跡テンティティの削除を司るコートを追加しましょう。
    camera.setChaseEntity(null);
    
    これがないと、カメラがプレイヤーの位置を追いかけたままになってしまうので、メニューシーンへ戻った後に画面が真っ黒になってしまいます。 この記事はこれで完了です。ゲームコードを実行するとプレイヤーが表示され、初回のタッチ後にプレイヤーが走り始めます。 以降はタッチする度にジャンプします。 注意: 現時点では、最初に地面に降り立った後、プレイヤーは何度も空中ジャンプができてしまいます。 これは、contact listenerについて紹介する次の記事にて修正します。 次の記事では、コインの収集、プレイヤーの死亡、カメラ領域の制限についても実装します。
前の記事 次の記事