AndEngine之DEMO學習(九)CardinalSplineMoveModifierExample

      這個例子又新介紹了一種修改器的實現,CardinalSplineMoveModifier(基數樣條移動修改器)。demo的效果是依靠矩形的運動創造出一個心形,當然心形是一個不規則的形狀,這裏就得使用基數樣條的概念。盜用百科:

      基數樣條是一組單個曲線按照一定的順序連接而成的一條較大麴線。樣條由一系列點指定,並通過每一個指定的點。由於基數樣條平滑地穿過組中的每一個點(不出現尖角),因而它比用直線連接創建的路徑更精確。

      程序中定義了兩組X,Y座標,分別表示心形左右兩邊的控制點,矩形的移動平滑的穿過幾個控制點。下面上代碼:

package org.andengine.examples;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.andengine.entity.modifier.CardinalSplineMoveModifier;
import org.andengine.entity.modifier.CardinalSplineMoveModifier.CardinalSplineMoveModifierConfig;
import org.andengine.entity.modifier.DelayModifier;
import org.andengine.entity.modifier.LoopEntityModifier;
import org.andengine.entity.modifier.ParallelEntityModifier;
import org.andengine.entity.modifier.RotationModifier;
import org.andengine.entity.modifier.SequenceEntityModifier;
import org.andengine.entity.primitive.Rectangle;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.util.FPSLogger;
import org.andengine.ui.activity.SimpleBaseGameActivity;
import org.andengine.util.math.MathUtils;
import org.andengine.util.modifier.ease.EaseLinear;

import android.opengl.GLES20;

public class CardinalSplineMoveModifierExample extends SimpleBaseGameActivity {

	private static final int CAMERA_WIDTH = 720;
	private static final int CAMERA_HEIGHT = 480;

	private static final int COUNT = 400;
	private static final float DURATION = 4;
	private static final float SIZE = 25;

	private static final float[] CONTROLPOINT_1_XS = {
		2 * (CAMERA_WIDTH / 4),
		1 * (CAMERA_WIDTH / 4),
		1.5f * (CAMERA_WIDTH / 4),
		2 * (CAMERA_WIDTH / 4)
	};

	private static final float[] CONTROLPOINT_2_XS = {
		2 * (CAMERA_WIDTH / 4),
		3 * (CAMERA_WIDTH / 4),
		2.5f * (CAMERA_WIDTH / 4),
		2 * (CAMERA_WIDTH / 4)
	};

	private static final float[] CONTROLPOINT_YS = {
		3.5f * (CAMERA_HEIGHT / 4),
		2 * (CAMERA_HEIGHT / 4),
		1 * (CAMERA_HEIGHT / 4),
		1.5f * (CAMERA_HEIGHT / 4),
	};

	@Override
	public EngineOptions onCreateEngineOptions() {
		final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

		return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera);
	}

	@Override
	public void onCreateResources() {

	}

	@Override
	public Scene onCreateScene() {
		this.mEngine.registerUpdateHandler(new FPSLogger());

		final Scene scene = new Scene();
		scene.setBackground(new Background(0, 0, 0));

		for(int i = 0; i < COUNT; i++) {
			final float tension = MathUtils.random(-0.5f, 0.5f);
			this.addRectangleWithTension(scene, tension, MathUtils.random(0, DURATION * 2f));
		}

		return scene;
	}

	private void addRectangleWithTension(final Scene pScene, final float pTension, float pDelay) {
		//生成矩形
		final Rectangle rectangle = new Rectangle(-SIZE, -SIZE, SIZE, SIZE, this.getVertexBufferObjectManager());
		rectangle.setBlendFunction(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE);
		if(pTension < 0) {
			rectangle.setColor(1 - pTension, 0, 0, 0.5f);
		} else {
			rectangle.setColor(pTension, 0, 0, 0.5f);
		}

		//包含控制點的配置
		final CardinalSplineMoveModifierConfig catmullRomMoveModifierConfig1 = new CardinalSplineMoveModifierConfig(CardinalSplineMoveModifierExample.CONTROLPOINT_1_XS.length, pTension);
		final CardinalSplineMoveModifierConfig catmullRomMoveModifierConfig2 = new CardinalSplineMoveModifierConfig(CardinalSplineMoveModifierExample.CONTROLPOINT_1_XS.length, pTension);

		//填充控制點
		for(int i = 0; i < CardinalSplineMoveModifierExample.CONTROLPOINT_1_XS.length; i++) {
			catmullRomMoveModifierConfig1.setControlPoint(i, CardinalSplineMoveModifierExample.CONTROLPOINT_1_XS[i] - SIZE / 2, CardinalSplineMoveModifierExample.CONTROLPOINT_YS[i] - SIZE / 2);
			catmullRomMoveModifierConfig2.setControlPoint(i, CardinalSplineMoveModifierExample.CONTROLPOINT_2_XS[i] - SIZE / 2, CardinalSplineMoveModifierExample.CONTROLPOINT_YS[i] - SIZE / 2);
		}

		rectangle.registerEntityModifier(
			new SequenceEntityModifier(
				new DelayModifier(pDelay),
				//無限循環,相當於根據控制點從下到上跑完左邊,在從下到上跑完右邊。
				new LoopEntityModifier(
					//順序容器
					new SequenceEntityModifier(
						new ParallelEntityModifier(
							//基數樣條移動改變器
							new CardinalSplineMoveModifier(CardinalSplineMoveModifierExample.DURATION, catmullRomMoveModifierConfig1, EaseLinear.getInstance()),
							//旋轉改變器
							new RotationModifier(CardinalSplineMoveModifierExample.DURATION, -45, -315)
						),
						new ParallelEntityModifier(
							//基數樣條移動改變器
							new CardinalSplineMoveModifier(CardinalSplineMoveModifierExample.DURATION, catmullRomMoveModifierConfig2, EaseLinear.getInstance()),
							//旋轉改變器
							new RotationModifier(CardinalSplineMoveModifierExample.DURATION, 45, 315)
						)
					)
				)
			)
		);

		pScene.attachChild(rectangle);
	}
}

      代碼也很少,說的也很清晰,CardinalSplineMoveModifierConfig中記錄了控制點和張力,CardinalSplineMoveModifier根據配置文件計算出改變的路徑。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章