AndEngine之DEMO学习(六)MovingBallExample

上例子之前先罗嗦两句,AndEngine是通过业务线程处理各种变化的,可能包含计算、存储、交互等等,当然最重要的还是改变实体的状态,在渲染的时候会看到实质的改变。举个例子,在业务线程中将TileSprite的显示瓦片顺序的改变,渲染线程显示出来便成为了动画。当然这种改变是需要我们控制的,实体通过注册IUpdateHandler,或者注册IModifier,这两种方式将我们的业务注册到业务线程。下面一段程序清楚的描述了业务线程的行为:

 /**
	 * 对实体的onUpdate方法的实际处理函数
	 * 
	 * @param pSecondsElapsed  间隔秒数
	 */
	protected void onManagedUpdate(final float pSecondsElapsed) {
		//本身注册的实体修改器的onUpdate
		if(this.mEntityModifiers != null) {
			this.mEntityModifiers.onUpdate(pSecondsElapsed);
		}
		//本身注册IUpdateHandler对象的onUpdate
		if(this.mUpdateHandlers != null) {
			this.mUpdateHandlers.onUpdate(pSecondsElapsed);
		}

		//调用子实体的onUpdate方法
		if((this.mChildren != null) && !this.mChildrenIgnoreUpdate) {
			final SmartList<IEntity> entities = this.mChildren;
			final int entityCount = entities.size();
			for(int i = 0; i < entityCount; i++) {
				entities.get(i).onUpdate(pSecondsElapsed);
			}
		}
	}
IModifier相当于IUpdateHandler的增强版,不能拥有onUpdate的业务更新方法,而且增加状态监听功能、自动注销功能和持续时间的设置。在这次的例子中首先登场的就是IUpdateHandler的实现。好可以上代码了:

package org.andengine.examples;

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.AnimatedSprite;
import org.andengine.entity.util.FPSLogger;
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.TiledTextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.ui.activity.SimpleBaseGameActivity;

public class MovingBallExample extends SimpleBaseGameActivity {

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

	private static final float DEMO_VELOCITY = 100.0f;

	private BitmapTextureAtlas mBitmapTextureAtlas;
	private TiledTextureRegion mFaceTextureRegion;

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

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

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

		this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 64, 32, TextureOptions.BILINEAR);
		this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, "face_circle_tiled.png", 0, 0, 2, 1);
		this.mBitmapTextureAtlas.load();
	}

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

		final Scene scene = new Scene();
		scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f));

		final float centerX = (MovingBallExample.CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
		final float centerY = (MovingBallExample.CAMERA_HEIGHT - this.mFaceTextureRegion.getHeight()) / 2;
		final Ball ball = new Ball(centerX, centerY, this.mFaceTextureRegion, this.getVertexBufferObjectManager());

		scene.attachChild(ball);

		return scene;
	}

	/**
	 * 球精灵的定义,完全没有必要继承于AnimatedSprite,Sprit足以。
	 * @author Administrator
	 */
	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);
			//一个模拟物理运动的IUpdateHandler,设置速度和加速度完成实体的运动。(构造函数的参数就是需要运动实体)
			this.mPhysicsHandler = new PhysicsHandler(this);
			this.registerUpdateHandler(this.mPhysicsHandler);
			this.mPhysicsHandler.setVelocity(MovingBallExample.DEMO_VELOCITY, MovingBallExample.DEMO_VELOCITY);
		}

		@Override
		protected void onManagedUpdate(final float pSecondsElapsed) {
			//X轴越界判断,改变mPhysicsHandler的X速度
			if(this.mX < 0) {
				this.mPhysicsHandler.setVelocityX(MovingBallExample.DEMO_VELOCITY);
			} else if(this.mX + this.getWidth() > MovingBallExample.CAMERA_WIDTH) {
				this.mPhysicsHandler.setVelocityX(-MovingBallExample.DEMO_VELOCITY);
			}
			//Y轴越界判断,改变mPhysicsHandler的Y速度
			if(this.mY < 0) {
				this.mPhysicsHandler.setVelocityY(MovingBallExample.DEMO_VELOCITY);
			} else if(this.mY + this.getHeight() > MovingBallExample.CAMERA_HEIGHT) {
				this.mPhysicsHandler.setVelocityY(-MovingBallExample.DEMO_VELOCITY);
			}

			super.onManagedUpdate(pSecondsElapsed);
		}
	}
}
代码一上貌似就没有什么好说的了,注意onManagedUpdate方法是业务线程调用的管理方法,每次业务轮换到业务线程的时候首先调用实体的onUpdate,接着调用实体的onManagedUpdate。相当于实体本身也是一个IUpdateHandler,自身就可以根据条件发生变化,同时也可以通过注册在实体的IUpdateHandler来改变。在这个例子中mPhysicsHandler完成了实体的直线运动,而实体本身完成了接触屏幕边缘改变运动方向,如此如此。

你可能感兴趣的:(AndEngine)