AndEngine学习 模拟手柄控制器


1.本节要点

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

2.新使用到的AndEngine资源

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


[java]  view plain copy
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之间),接口源代码为:

    


[java]  view plain copy
public interface IAnalogOnScreenControlListener extends IOnScreenControlListener {  
        // ===========================================================  
        // Constants  
        // ===========================================================  
  
        // ===========================================================  
        // Methods  
        // ===========================================================  
  
        public void onControlClick(final AnalogOnScreenControl pAnalogOnScreenControl);  
    }  
[java]  view plain copy
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类只实现了旋转,

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


[java]  view plain copy
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张图片:背景,精灵,控制器背景,控制器指针

    AndEngine学习 模拟手柄控制器_第1张图片


AndEngine学习 模拟手柄控制器_第2张图片     


源代码如下:


[java]  view plain copy
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.基础场景

       


[java]  view plain copy
Scene mScene = new Scene();  
        mScene.setBackground(mBackground);  
          
        if(MultiTouch.isSupported(this)){  
            this.mEngine.setTouchController(new MultiTouchController());  
              
        }  

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


[java]  view plain copy
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)的方法

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

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


[java]  view plain copy
mDerectionControl.setAlpha(0.65f);  
   mRotationControl.setAlpha(0.65f);  
     
   mScene.attachChild(mDragon);  
   mScene.setChildScene(mDerectionControl);  
   mDerectionControl.setChildScene(mRotationControl);  
     
  pOnCreateSceneCallback.onCreateSceneFinished(mScene);  
5.一切准备就绪,运行代码

   运行结果如下:

AndEngine学习 模拟手柄控制器_第3张图片


AndEngine学习 模拟手柄控制器_第4张图片





你可能感兴趣的:(AndEngine学习 模拟手柄控制器)