andengine编程之sprite(四)

在andengine编程之sprite(三)中,我们介绍了一些sprite对位置的设置以及对触摸的监听。这次,我们要再来介绍介绍sprite对位置的设置,但这一次,我们要借助另一个方式——物理引擎。

PhysicsHandler是一个比较基本的物理类,它主要是对sprite设置移动速度,加速度,角速度等。
下面,我们先来看看它的一些方法:
速度:
public void setVelocityX(final float pVelocityX) 和public void setVelocityY(final float pVelocityY):分别对X方向和Y方向设置速度。
public void setVelocity(final float pVelocity) :X方向和Y方向设置同一数值的速度。
public void setVelocity(final float pVelocityX, final float pVelocityY)对X方向和Y方向设置速度。

加速度:
public void setAccelerationX(final float pAccelerationX)public void setAccelerationY(final float pAccelerationY):分别对X方向和Y方向设置加速度。
public void setAcceleration(final float pAcceleration):X方向和Y方向设置同一数值的速度。
public void setAcceleration(final float pAccelerationX, final float pAccelerationY):对X方向和Y方向设置加速度。
public void accelerate(final float pAccelerationX, final float pAccelerationY):对X方向和Y方向加速度数值做累加修正,例如加速度一直在提升,非匀加速状态。

角速度:
public void setAngularVelocity(final float pAngularVelocity):设置角速度。

重置,清零:
public void reset():将所有设置都设置为零,即重置。


接下来,我们用一张坦克的图片来实现一下精灵的移动:

	public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)
			throws Exception {
		Scene mScene = new Scene();

		final AnimatedSprite tank = new AnimatedSprite(400, 200,
				mSpriteTiledTextureRegion, getVertexBufferObjectManager());

		// 设置背景
		mScene.setBackground(background);
		mScene.attachChild(tank);
		// 注册精灵要实现触摸效果
		mScene.registerTouchArea(tank);

		// 构建运动机制
		final PhysicsHandler physicsHandler = new PhysicsHandler(tank);
		tank.registerUpdateHandler(physicsHandler);

		// 为场景注册触摸监听事件
		mScene.setOnSceneTouchListener(new IOnSceneTouchListener() {
			public boolean onSceneTouchEvent(Scene pScene,
					TouchEvent pSceneTouchEvent) {

				// 求得角度根据两个坐标,这里取一下坦克中心点作为坦克的坐标
				final float angleRad = MathUtils.atan2(
						tank.getY() + tank.getHeight() / 2
								- pSceneTouchEvent.getY(),
						(tank.getX() + tank.getWidth() / 2)
								- pSceneTouchEvent.getX());

				// 求出移动的速度,这里也是根据三角形的计算法则,已知角度和总速度,求出X方向速度和Y方向速度
				// 100f:即为其总速度
				float VelocityX = FloatMath.cos(angleRad) * 100f;
				float VelocityY = FloatMath.sin(angleRad) * 100f;

				switch (pSceneTouchEvent.getAction()) {
				// 这里,我们只取了按下抬起时的效果,方便我们观察
				case TouchEvent.ACTION_DOWN:
				case TouchEvent.ACTION_MOVE:

					// 为其设置X方向速度和Y方向速度
					physicsHandler.setVelocity(-VelocityX, -VelocityY);

					// 为图片设置旋转角度(+ 90:为了修正旋转方向)
					tank.setRotation(MathUtils.radToDeg(angleRad) + 90);
					break;
				case TouchEvent.ACTION_UP:
					// 松开按键后,将运动状态还原
					physicsHandler.reset();
					break;
				}
				return true;
			}
		});
		pOnCreateSceneCallback.onCreateSceneFinished(mScene);
	}

如果对上面提到的速度求法不太明白的话,我这里用图片示例来说明一下,以便大家理解:
andengine编程之sprite(四)_第1张图片
通过精灵当前坐标和触摸点的坐标,我们可以求得两条直角边的长度:X方向touch.x-sprite.x和Y方向touch.y-sprite.y,然后求得当前所夹角度。

然后根据角度和速度,可以分别求的X方向速度和Y方向速度:即代码中所写的FloatMath.cos(angleRad) * 100f和FloatMath.sin(angleRad) * 100f。

源代码:
package com.testsprite;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.handler.physics.PhysicsHandler;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.FillResolutionPolicy;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.RepeatingSpriteBackground;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.input.touch.TouchEvent;
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.atlas.bitmap.source.AssetBitmapTextureAtlasSource;
import org.andengine.opengl.texture.region.TiledTextureRegion;
import org.andengine.ui.activity.BaseGameActivity;
import org.andengine.util.math.MathUtils;

import android.util.FloatMath;

public class TestSprite extends BaseGameActivity {
	private static final int CAMERA_WIDTH = 800;
	private static final int CAMERA_HEIGHT = 480;

	private RepeatingSpriteBackground background;

	private TiledTextureRegion mSpriteTiledTextureRegion;

	public EngineOptions onCreateEngineOptions() {
		Camera mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
		EngineOptions mEngineOptions = new EngineOptions(true,
				ScreenOrientation.LANDSCAPE_FIXED, new FillResolutionPolicy(),
				mCamera);
		return mEngineOptions;
	}

	public void onCreateResources(
			OnCreateResourcesCallback pOnCreateResourcesCallback)
			throws Exception {

		this.background = new RepeatingSpriteBackground(800, 480,
				getTextureManager(), AssetBitmapTextureAtlasSource.create(
						this.getAssets(), "background.png"),
				getVertexBufferObjectManager());

		BitmapTextureAtlas mBitmapTextureAtlas = new BitmapTextureAtlas(
				getTextureManager(), 128, 256, TextureOptions.DEFAULT);
		mSpriteTiledTextureRegion = BitmapTextureAtlasTextureRegionFactory
				.createTiledFromAsset(mBitmapTextureAtlas, this, "tank.png", 0,
						0, 1, 1);
		mBitmapTextureAtlas.load();

		pOnCreateResourcesCallback.onCreateResourcesFinished();
	}

	public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)
			throws Exception {
		Scene mScene = new Scene();

		final AnimatedSprite tank = new AnimatedSprite(400, 200,
				mSpriteTiledTextureRegion, getVertexBufferObjectManager());

		// 设置背景
		mScene.setBackground(background);
		mScene.attachChild(tank);
		// 注册精灵要实现触摸效果
		mScene.registerTouchArea(tank);

		// 构建运动机制
		final PhysicsHandler physicsHandler = new PhysicsHandler(tank);
		tank.registerUpdateHandler(physicsHandler);

		// 为场景注册触摸监听事件
		mScene.setOnSceneTouchListener(new IOnSceneTouchListener() {
			public boolean onSceneTouchEvent(Scene pScene,
					TouchEvent pSceneTouchEvent) {

				// 求得角度根据两个坐标,这里取一下坦克中心点作为坦克的坐标
				final float angleRad = MathUtils.atan2(
						tank.getY() + tank.getHeight() / 2
								- pSceneTouchEvent.getY(),
						(tank.getX() + tank.getWidth() / 2)
								- pSceneTouchEvent.getX());

				// 求出移动的速度,这里也是根据三角形的计算法则,已知角度和总速度,求出X方向速度和Y方向速度
				// 100f:即为其总速度
				float VelocityX = FloatMath.cos(angleRad) * 100f;
				float VelocityY = FloatMath.sin(angleRad) * 100f;

				switch (pSceneTouchEvent.getAction()) {
				// 这里,我们只取了按下抬起时的效果,方便我们观察
				case TouchEvent.ACTION_DOWN:
				case TouchEvent.ACTION_MOVE:

					// 为其设置X方向速度和Y方向速度
					physicsHandler.setVelocity(-VelocityX, -VelocityY);

					// 为图片设置旋转角度(+ 90:为了修正旋转方向)
					tank.setRotation(MathUtils.radToDeg(angleRad) + 90);
					break;
				case TouchEvent.ACTION_UP:
					// 松开按键后,将运动状态还原
					physicsHandler.reset();
					break;
				}
				return true;
			}
		});
		pOnCreateSceneCallback.onCreateSceneFinished(mScene);
	}

	public void onPopulateScene(Scene pScene,
			OnPopulateSceneCallback pOnPopulateSceneCallback) throws Exception {
		pOnPopulateSceneCallback.onPopulateSceneFinished();
	}
}



sprite坦克移动

你可能感兴趣的:(编程,exception,算法,Class,float,引擎)