09-03 PhysicsHandler のメソッド – 2

CatmullRomMoveModifierConfig にどはまり。。。orz

結果として、ソースファイルにミスがあって、修正しないと使えないメソッドでした。
修正箇所は下のファイルの (ここっ!) に static を入れます。
※2013/02/21 現在のお話です。git でダウンロードした人は修正済みのはずですが zip の場合は最新版をダウンロードしてもダメでした。
AndEngine-GLES2\src\org\andengine\entity\modifierCatmullRomSplineMoveModifier.java

// 修正前
public (ここっ!) class CatmullRomMoveModifierConfig extends CardinalSplineMoveModifierConfig {

↓↓↓

// 修正後
public static class CatmullRomMoveModifierConfig extends CardinalSplineMoveModifierConfig {

 

以下は見つけるまで苦労したのでメモです 😉

CardinalSplineMoveModifier とまったく同じ方法でやっていたのですが

private static final CatmullRomMoveModifierConfig pCatmullRomMoveModifierConfig = new CatmullRomMoveModifierConfig(5);

↑のところでエラー。。。

No enclosing instance of type CatmullRomSplineMoveModifier is accessible. Must qualify the allocation with an enclosing instance of type CatmullRomSplineMoveModifier (e.g. x.new A() where x is an instance of CatmullRomSplineMoveModifier).

ご丁寧に CatmullRomSplineMoveModifier の instance だから “x.new A()” って感じで書いてね!って出てくれてたので “CatmullRomSplineMoveModifier.new CatmullRomMoveModifierConfig()” とかやってみてもダメで。。。
調べると

January 11, 2013
nicolasgramlich closed issue nicolasgramlich/AndEngine#195
Minor but important fix in CatmullRomMoveModifierConfig
https://github.com/nicolasgramlich/AndEngine/issues/195 のやり取りで、public → static になったんだ~

というところまでは分かったのですが、いかんせん java(というか オブジェクト指向を) を知らないので static に代わるとどうなるのかわかりません X(
てことで static を調べまくって。。。。 むしろ static の方がいちいち instance 生成(?)しなくてもいいのかー。。。とか ↓ のように
http://stackoverflow.com/questions/4413000/how-do-i-properly-delcare-an-instance-of-a-subclass-in-java

private static CatmullRomSplineMoveModifier pCatmullRomSplineMoveModifier = new CatmullRomSplineMoveModifier().new CatmullRomMoveModifierConfig(); 
private static CatmullRomSplineMoveModifier pCatmullRomSplineMoveModifier = new CatmullRomSplineMoveModifier();
private static CatmullRomSplineMoveModifier pCatmullRomSplineMoveModifier = CatmullRomSplineMoveModifier.new pCatmullRomSplineMoveModifier();

とかとか、いろいろやりまくってもダメダメ。。。ecilpse さんの修正候補もことごとく外れまくりです X(

唯一、↓はコンパイルエラーにはならなかったですけど、実行すると null pointer…
※これは薄々そうではないかと思ってたのですが(汗

private static CatmullRomSplineMoveModifier pCatmullRomSplineMoveModifier

にっちもさっちもいかなくなり、自分のプログラムではなく自分の環境の AndEngine のソースをじっくり見てみることに。。。

するとっ!

CatmullRomSplineMoveModifier.java

public (ここっ!) class CatmullRomMoveModifierConfig extends CardinalSplineMoveModifierConfig {

static が入ってないじゃないかあああああ!

最新版をダウンロードしてるはずなのに。。。。。orz
今ダウンロードしてもやっぱり修正されていないので github の zip ダウンロードは release 版のみなのですね?
やっぱり git を入れないとダメっぽいですね><

んまぁ、とりあえず動いたのでよしとしますか。。。

09-02 PhysicsHandler のメソッド – 1

setVelocity(float pVelocity)

設定した速度で直線に移動 (値が大きい程早い)

faceSprite.setVelocity(100); // 斜め右下に 100 の速度で移動

値 1 つの場合は X, Y を同時指定

faceSprite.setVelocity(100);

値は X, Y を別々に指定可能

faceSprite.setVelocity(100, 200);

X のみ, Y のみを指定可能

faceSprite.setVelocityX(100); // X のみ指定
faceSprite.setVelocityY(200); // Y のみ指定

 

setAcceleration(float pAcceleration)

指定した加速度で直線に移動 (値が大きい程早く加速する)

faceSprite.setAcceleration(100); // 斜め右下に 100 の速度で加速

 

setAngularVelocity(float pAngularVelocity)

指定した速度で回転 (正:右回転、負:左回転)
 ※このメソッドは X, Y の指定ができません。

faceSprite.setAngularVelocity(100);

 

setEnabled(boolean pEnabled)

 true:移動や回転などがはじまる
 false:移動や回転などが止まる

faceSprite.setEnabled(false);

 

AlphaModifier(float pDuration, float pFromAlpha, float pToAlpha, IEntityModifierListener pEntityModifierListener, IEaseFunction pEaseFunction)

pDuration 時間で pFromAlpha から pToAlpha に変える

faceSprite.registerEntityModifier(new AlphaModifier(5.0f, 0.0f, 1.0f));

 

CardinalSplineMoveModifier(float pDuration, VardinalSplineMoveModifierConfig pCardinalSplineMoveModifierConfig, IEntityModifierListener pEntityModifierListener, IEaseFunction pEaseFunction)

CardinalSplineMoveModifierConfig(int pControlPointCount, float pTension)

pDuration 時間で 指定された point を pTension で指定された緩やかさ(値が大きいほどカクカク、マイナスだと丸びを帯びる感じ)で移動

pControlPointCount で指定した point と setControlPoint した数がアンマッチの場合はエラー

※1.0f でほぼ直線的?、2.0f だとなんかぐるっとバックする。-1.0f だと丸びを帯びて、-2.0f だと 2.0f とは反対方向にぐるっと回る感じでした

AndEngine Examples は -0.5f ~ 0.5f の範囲だったのでそれくらいがちょうどいいのかもです。
とりあえず CardinalSpline を画像検索するとわかりやすいと思います。

private static final CardinalSplineMoveModifierConfig pCardinalSplineMoveModifierConfig = new CardinalSplineMoveModifierConfig(5, -0.5f);

public void move() {
	pCardinalSplineMoveModifierConfig.setControlPoint(0, 120,  60);
	pCardinalSplineMoveModifierConfig.setControlPoint(1, 180, 120);
	pCardinalSplineMoveModifierConfig.setControlPoint(2, 240, 120);
	pCardinalSplineMoveModifierConfig.setControlPoint(3, 300,  60);
	pCardinalSplineMoveModifierConfig.setControlPoint(4, 360, 120);

	this.registerEntityModifier(new CardinalSplineMoveModifier(5.0f, catmullRomMoveModifierConfig));
}

 

CatmullRomSplineMoveModifier(float pDuration, CatmullRomMoveModifierConfig pCatmullRomMoveModifierConfig, IEntityModifierListener pEntityModifierListener, IEaseFunction pEaseFunction)

CatmullRomMoveModifierConfig(int pControlPointCount)

CardinalSplineMoveModifier とほとんど同じですが、CardinalSplineMoveModifier がすべての線がなめらかになるのに対して、CatmullRomSplineMoveModifier は Point 間のみなめらかになるようです。(<1 href="http://markun.cs.shinshu-u.ac.jp/learn/cg/cg3/index5.html">http://markun.cs.shinshu-u.ac.jp/learn/cg/cg3/index5.html ← めっちゃわかりやすかったです)

private CatmullRomMoveModifierConfig pCatmullRomMoveModifierConfig = new CatmullRomMoveModifierConfig(5);

public void move() {
	pCatmullRomMoveModifierConfig.setControlPoint(0, 120,  60);
	pCatmullRomMoveModifierConfig.setControlPoint(1, 180, 120);
	pCatmullRomMoveModifierConfig.setControlPoint(2, 240, 120);
	pCatmullRomMoveModifierConfig.setControlPoint(3, 300,  60);
	pCatmullRomMoveModifierConfig.setControlPoint(4, 360, 120);

	this.registerEntityModifier(new CatmullRomSplineMoveModifier(5.0f, pCatmullRomMoveModifierConfig));
}

 

ColorModifier(float pDuration, float pFromRed, float pToRed, float pFromGreen, float pToGreen, float pFromBlue, float pToBlue, IEntityModifierListener pEntityModifierListener, IEaseFunction pEaseFunction)

pDuration 時間で pFromColor から pToColor へ色を変化させる
 ※アルファを指定しても(new Color(1, 1, 1, 1))エラーはでませんでしたが、アルファは適用されませんでした

oAnimatedSprite.registerEntityModifier(new ColorModifier(5.0f, new Color(1, 1, 1), new Color(0, 0, 0)));

 


CubicBezierCurveMoveModifier(float pDuration, float pX1, float pY1, float pX2, float pY2, float pX3, float pY3, float pX4, float pY4, IEntityModifierListener pEntityModifierListener, IEaseFunction pEaseFunction)

pDuration 時間で (3 次元) ベジェ曲線を描きながら移動する
サンプルは↓の画像をセットした際の動き
http://www.w3.org/TR/SVG/images/paths/cubic02.svg

oAnimatedSprite.registerEntityModifier(new CubicBezierCurveMoveModifier(5.0f, 100f, 200f, 100f, 100f, 400f, 100f, 400f, 200f));

09-01 registerEntityModifier というか PhysicsHandler というか Modifier(?) というか

Sprite を移動させたいだけなのですが、単なる移動と物理学的(?) 移動とあるようです。
単純な移動の方がメモリを食わない気がしますが

package com.example.mytestproject;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.handler.physics.PhysicsHandler;		// 追加
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
// import org.andengine.entity.sprite.Sprite;					// 削除
import org.andengine.entity.sprite.AnimatedSprite;				// 追加
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
// import org.andengine.opengl.texture.region.ITextureRegion;	// 削除
import org.andengine.opengl.texture.region.TiledTextureRegion;	// 追加 (ITextureRegion でも 動きます)
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.ui.activity.SimpleBaseGameActivity;

/**
 * (c) 2010 Nicolas Gramlich
 * (c) 2011 Zynga
 *
 * @author Nicolas Gramlich
 * @since 14:27:22 - 14.06.2011
 */
public class MyShowImage extends SimpleBaseGameActivity {
	// ===========================================================
	// Constants
	// ===========================================================
	private static final int CAMERA_WIDTH  = 480;
	private static final int CAMERA_HEIGHT = 720;
	private static final float DEMO_VELOCITY = 100.0f;		// 追加

	// ===========================================================
	// Fields
	// ===========================================================
	private BitmapTextureAtlas mBitmapTextureAtlas;
	private TiledTextureRegion mFaceTextureRegion;

	@Override
	public EngineOptions onCreateEngineOptions() {
		final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		return new EngineOptions(true, ScreenOrientation.PORTRAIT_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
	}

	@Override
	public void onCreateResources() {
		BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");

		this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 32, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
//		this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "face_box.png", 0, 0);				// 削除
		this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "face_box.png", 0, 0, 1, 1);	// 追加
		this.mBitmapTextureAtlas.load();
	}

	@Override
	public Scene onCreateScene() {
		final Scene scene = new Scene();
		scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));

		/* Calculate the coordinates for the face, so its centered on the camera. */
		final float centerX = (CAMERA_WIDTH  - this.mFaceTextureRegion.getWidth())  / 2;
		final float centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;

//		final Sprite faceSprite = new Sprite(centerX, centerY, this.mFaceTextureRegion, this.getVertexBufferObjectManager()); 	// 削除
		final Ball faceSprite = new Ball(centerX, centerY, this.mFaceTextureRegion, this.getVertexBufferObjectManager());		// 追加

		scene.attachChild(faceSprite);

		return scene;
	}

	// 以下、すべて追加
	private static class Ball extends AnimatedSprite {
		private final PhysicsHandler mPhysicsHandler;

		public Ball(final float pX, final float pY, final TiledTextureRegion pTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) {
			super(pX, pY, pTextureRegion, pVertexBufferObjectManager);
			this.mPhysicsHandler = new PhysicsHandler(this);
			this.registerUpdateHandler(this.mPhysicsHandler);
			this.mPhysicsHandler.setVelocity(MyShowImage.DEMO_VELOCITY, MyShowImage.DEMO_VELOCITY);
		}

		@Override
		protected void onManagedUpdate(final float pSecondsElapsed) {
			if(this.mX < 0) {
				this.mPhysicsHandler.setVelocityX(MyShowImage.DEMO_VELOCITY);
			} else if(this.mX + this.getWidth() > MyShowImage.CAMERA_WIDTH) {
				this.mPhysicsHandler.setVelocityX(-MyShowImage.DEMO_VELOCITY);
			}

			if(this.mY < 0) {
				this.mPhysicsHandler.setVelocityY(MyShowImage.DEMO_VELOCITY);
			} else if(this.mY + this.getHeight() > MyShowImage.CAMERA_HEIGHT) {
				this.mPhysicsHandler.setVelocityY(-MyShowImage.DEMO_VELOCITY);
			}

			super.onManagedUpdate(pSecondsElapsed);
		}
	}
}