在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);
}
如果对上面提到的速度求法不太明白的话,我这里用图片示例来说明一下,以便大家理解:
通过精灵当前坐标和触摸点的坐标,我们可以求得两条直角边的长度: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坦克移动