[AndEngine学习教程] 第6节 模拟手柄控制器

1.本节要点

      制作一个虚拟手柄来控制动画精灵的移动,旋转.

2.新使用到的AndEngine资源

  1.AnalogOnScreenControl 这是An的Engine给我们提供的用于虚拟手柄,虚拟控制器方面的基础类,其构造如下:

public AnalogOnScreenControl(final float pX, final float pY, final Camera pCamera, final ITextureRegion pControlBaseTextureRegion, final ITextureRegion pControlKnobTextureRegion, final float pTimeBetweenUpdates, final VertexBufferObjectManager pVertexBufferObjectManager, final IAnalogOnScreenControlListener pAnalogOnScreenControlListener) {
		super(pX, pY, pCamera, pControlBaseTextureRegion, pControlKnobTextureRegion, pTimeBetweenUpdates, pVertexBufferObjectManager, pAnalogOnScreenControlListener);

		this.mClickDetector.setEnabled(false);
	}

public AnalogOnScreenControl(final float pX, final float pY, final Camera pCamera, final ITextureRegion pControlBaseTextureRegion, final ITextureRegion pControlKnobTextureRegion, final float pTimeBetweenUpdates, final long pOnControlClickMaximumMilliseconds, final VertexBufferObjectManager pVertexBufferObjectManager, final IAnalogOnScreenControlListener pAnalogOnScreenControlListener) {
		super(pX, pY, pCamera, pControlBaseTextureRegion, pControlKnobTextureRegion, pTimeBetweenUpdates, pVertexBufferObjectManager, pAnalogOnScreenControlListener);

		this.mClickDetector.setTriggerClickMaximumMilliseconds(pOnControlClickMaximumMilliseconds);
	}

  2.参数说明:

       pX,pY是控制器的左上角放置坐标;

       pCamera是我们在场景中使用到的Camera;

       pControlBaseTextureRegion相当于控制器的背景

       pControlKnobTextureRegion相当于控制器的指针图标

      pTimeBetweenUpdates指控制器的重绘刷新时间间隔,单位是秒

      pVertexBufferObjectManager直接使用getVertxeBufferObjectManager()传进去就可以了

      pAnalogOnScreenControlListener是控制器实现自动监听的接口,主要用来监听控制器的位置变化,

     然后将相应的变化转化为一组通用的数据(-1到1之间),接口源代码为:

    

public interface IAnalogOnScreenControlListener extends IOnScreenControlListener {
		// ===========================================================
		// Constants
		// ===========================================================

		// ===========================================================
		// Methods
		// ===========================================================

		public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl);
	}
public static interface IOnScreenControlListener {
		// ===========================================================
		// Constants
		// ===========================================================

		// ===========================================================
		// Methods
		// ===========================================================

		/**
		 * @param pBaseOnScreenControl
		 * @param pValueX between <code>-1</code> (left) to <code>1</code> (right).
		 * @param pValueY between <code>-1</code> (up) to <code>1</code> (down).
		 */
		public void onControlChange(final BaseOnScreenControl pBaseOnScreenControl, final float pValueX, final float pValueY);
	}
这两个接口一个实现点击监听,一个实现变化监听.所以我们可以根据需要,在我们自己的类当中使用.

3.构建符合自己需要的精灵

      本节当中需要根据控制器来控制精灵的旋转,移动.而AndEngine给我们提供的AnimatedSprite类只实现了旋转,

并没有按照一定速度移动的方法,在这里我自己重写了该类:

public class MyControlSprite extends AnimatedSprite{

		public MyControlSprite(float pX, float pY, float pWidth, float pHeight,
				ITiledTextureRegion pTiledTextureRegion,
				VertexBufferObjectManager pVertexBufferObjectManager) {
			super(pX, pY, pWidth, pHeight, pTiledTextureRegion, pVertexBufferObjectManager);
			// TODO Auto-generated constructor stub
			mVelocityX = 0;
			mVelocityY = 0;
		}

		private float mVelocityX;//水平速度
		private float mVelocityY;//垂直速度
		

		@Override
		protected void onManagedUpdate(float pSecondsElapsed) {
			// TODO Auto-generated method stub
			this.mX += mVelocityX * pSecondsElapsed;
			this.mY += mVelocityY * pSecondsElapsed;
			
			this.setPosition(mX, mY);
			super.onManagedUpdate(pSecondsElapsed);
		}
		
		
		void setVolocityX(float vX){
			mVelocityX = vX;
			
		}
		
		void setVolocityY(float vY){	
			mVelocityY = vY;
		}
		
		void setVolocityXY(float vX, float vY){
			mVelocityX = vX;
			mVelocityY = vY;
		}
	}

主要在 onManagedUpdate方法中增加了精灵按照一定速度移动的方法

4.资源构建

1.本例子用到4张图片:背景,精灵,控制器背景,控制器指针

    


     


源代码如下:

private static final float CAMERA_WIDTH = 800;
	private static final float CAMERA_HEIGHT = 480;
	
	private Camera mCamera;
	private RepeatingSpriteBackground mBackground;
	private TiledTextureRegion mBaseRegion;
	private TiledTextureRegion mKnobRegion;
	private TiledTextureRegion mDragonRegion;
	
	@Override
	public EngineOptions onCreateEngineOptions() {
		// TODO Auto-generated method stub
		mCamera = new Camera(0,0,CAMERA_WIDTH, CAMERA_HEIGHT);
		EngineOptions mEngineOptions = new EngineOptions(true,ScreenOrientation.LANDSCAPE_SENSOR,new RatioResolutionPolicy(CAMERA_WIDTH,CAMERA_HEIGHT),mCamera);
		
		return mEngineOptions;
	}

	@Override
	public void onCreateResources(
			OnCreateResourcesCallback pOnCreateResourcesCallback)
			throws Exception {
		// TODO Auto-generated method stub
		mBackground = new RepeatingSpriteBackground(CAMERA_WIDTH, CAMERA_HEIGHT, getTextureManager(), AssetBitmapTextureAtlasSource.create(getAssets(), "background_grass.png"), getVertexBufferObjectManager());
		BitmapTextureAtlas mDragonTexture = new BitmapTextureAtlas(getTextureManager(), 512, 256, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		BitmapTextureAtlas mController = new BitmapTextureAtlas(getTextureManager(),256,256,TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		
		mDragonRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mDragonTexture, this, "snapdragon_tiled.png", 0, 0, 4, 3);
		mBaseRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mController, this, "onscreen_control_base.png", 0, 0, 1, 1);
		mKnobRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mController, this, "onscreen_control_knob.png", 128, 0, 1, 1);
		
		mDragonTexture.load();
		mController.load();
		
		
		pOnCreateResourcesCallback.onCreateResourcesFinished();
	}

5.场景创建

   1.基础场景

       

Scene mScene = new Scene();
		mScene.setBackground(mBackground);
		
		if(MultiTouch.isSupported(this)){
			this.mEngine.setTouchController(new MultiTouchController());
			
		}

     2.创建控制器和动画精灵,在这里有两个控制器,一个是控制移动,一个控制旋转

final MyControlSprite mDragon = new MyControlSprite(CAMERA_WIDTH/2, CAMERA_HEIGHT/2,80.0f,80.0f,mDragonRegion, getVertexBufferObjectManager());
		     mDragon.animate(100);     
		     
	   final AnalogOnScreenControl mDerectionControl  = new AnalogOnScreenControl(20, CAMERA_HEIGHT-mBaseRegion.getHeight()-20,
			          mCamera, mBaseRegion, mKnobRegion, 0.1f, 200, 
			          getVertexBufferObjectManager(), 
			          new IAnalogOnScreenControlListener(){

						@Override
						public void onControlChange(
								BaseOnScreenControl pBaseOnScreenControl,
								float pValueX, float pValueY) {
							// TODO Auto-generated method stub
							mDragon.setVolocityXY(pValueX*100, pValueY*100);
						}

						@Override
						public void onControlClick(
								AnalogOnScreenControl pAnalogOnScreenControl) {
							// TODO Auto-generated method stub
							Log.d("Season","Click on Controller");
						}

					

	   });    
		
	   
	   final AnalogOnScreenControl mRotationControl = new AnalogOnScreenControl(CAMERA_WIDTH - 20 - mBaseRegion.getWidth(), CAMERA_HEIGHT-mBaseRegion.getHeight()-20,
		          mCamera, mBaseRegion, mKnobRegion, 0.1f, 200, 
		          getVertexBufferObjectManager(), 
		          new IAnalogOnScreenControlListener(){

					@Override
					public void onControlChange(
							BaseOnScreenControl pBaseOnScreenControl,
							float pValueX, float pValueY) {
						// TODO Auto-generated method stub
						if(pValueX == 0 && pValueY == 0){
							
							mDragon.setRotation(0.0f);
						}
						mDragon.setRotation(MathUtils.radToDeg((float) Math.atan2(pValueY, pValueX)));
					}

					@Override
					public void onControlClick(
							AnalogOnScreenControl pAnalogOnScreenControl) {
						// TODO Auto-generated method stub
						Log.d("Season","Click on Controller");
					}
          });    
	   
	   
	   mDerectionControl.setAlpha(0.65f);
	   mRotationControl.setAlpha(0.65f);

  3.将角色加载到场景,在这里需要注意的地方是:

     mDragon使用mScene.attachChild(IEntity)的方法

     而mDerectionControlsetChildScene只能使用setChildScene(Scene)的方法,不然的话

    这两个控制器你怎么点他们都毫无反应,这也是我刚刚开始的时候没仔细看代码犯下的错误

 mDerectionControl.setAlpha(0.65f);
	   mRotationControl.setAlpha(0.65f);
	   
	   mScene.attachChild(mDragon);
	   mScene.setChildScene(mDerectionControl);
	   mDerectionControl.setChildScene(mRotationControl);
	   
	  pOnCreateSceneCallback.onCreateSceneFinished(mScene);

5.一切准备就绪,运行代码

    终于完成了所有代码,开心呀.hoho~~~~~大笑

   转载请注明出处哦,谢谢!本文由Season于2012-11-1 14:18完成的

   运行结果如下:





本例子源代码:http://download.csdn.net/detail/cen616899547/4710222


  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值