首页 > 代码库 > 场景精灵间的坐标转换

场景精灵间的坐标转换

1.要点分析
1.在制作动画精灵的时候,为了方便计算,常常需要把场景中的坐标转换为精灵的内部坐标或者需要把精灵的内部坐标转换为场景坐标.如果精灵没有进行过旋转操作,他们之间只一个offset而已
2.本节需要实现的是在一个人脸精灵内,找到他的眼睛位置,然后随意变换精灵(大小比例,旋转,移动等)然后依旧定位出精灵的眼睛.


2.新内容
1.要在Activity上标注精灵的眼睛,需要使用到箭头,在简略的情况下,可以用三根直线实现,好在AndEngine已经为我们提供一Line类:
public class Line extends Shape

  1. <font color="#000000">/**

  2.          * Uses a default {@link HighPerformanceLineVertexBufferObject} in {@link DrawType#STATIC} with the {@link VertexBufferObjectAttribute}s: {@link Line#VERTEXBUFFEROBJECTATTRIBUTES_DEFAULT}.

  3.          */

  4.         public Line(final float pX1, final float pY1, final float pX2, final float pY2, final VertexBufferObjectManager pVertexBufferObjectManager) {

  5.                 this(pX1, pY1, pX2, pY2, Line.LINE_WIDTH_DEFAULT, pVertexBufferObjectManager, DrawType.STATIC);

  6.         }


  7.         /**

  8.          * Uses a default {@link HighPerformanceLineVertexBufferObject} with the {@link VertexBufferObjectAttribute}s: {@link Line#VERTEXBUFFEROBJECTATTRIBUTES_DEFAULT}.

  9.          */

  10.         public Line(final float pX1, final float pY1, final float pX2, final float pY2, final VertexBufferObjectManager pVertexBufferObjectManager, final DrawType pDrawType) {

  11.                 this(pX1, pY1, pX2, pY2, Line.LINE_WIDTH_DEFAULT, pVertexBufferObjectManager, pDrawType);

  12.         }


  13.         /**

  14.          * Uses a default {@link HighPerformanceLineVertexBufferObject} in {@link DrawType#STATIC} with the {@link VertexBufferObjectAttribute}s: {@link Line#VERTEXBUFFEROBJECTATTRIBUTES_DEFAULT}.

  15.          */

  16.         public Line(final float pX1, final float pY1, final float pX2, final float pY2, final float pLineWidth, final VertexBufferObjectManager pVertexBufferObjectManager) {

  17.                 this(pX1, pY1, pX2, pY2, pLineWidth, pVertexBufferObjectManager, DrawType.STATIC);

  18.         }


  19.         public Line(final float pX1, final float pY1, final float pX2, final float pY2, final float pLineWidth, final VertexBufferObjectManager pVertexBufferObjectManager, final DrawType pDrawType) {

  20.                 this(pX1, pY1, pX2, pY2, pLineWidth, new HighPerformanceLineVertexBufferObject(pVertexBufferObjectManager, Line.LINE_SIZE, pDrawType, true, Line.VERTEXBUFFEROBJECTATTRIBUTES_DEFAULT));

  21.         }


  22.         public Line(final float pX1, final float pY1, final float pX2, final float pY2, final float pLineWidth, final ILineVertexBufferObject pLineVertexBufferObject) {

  23.                 super(pX1, pY1, PositionColorShaderProgram.getInstance());</font>

复制代码





2.AnalogOnScreenControl类,这个我们在上一节的内容中已经详细介绍了,使用这个类只是方便我们观看坐标切换后的效果3.源代码分析        1.内部成员变量定义:背景+控制器+精灵脸

  1. private static final float CAMERA_WIDTH = 800;

  2.         private static final float CAMERA_HEIGHT = 480;

  3.         

  4.         private Camera mCamera;

  5.         private RepeatingSpriteBackground mBackground;

  6.         private TiledTextureRegion mBaseRegion;

  7.         private TiledTextureRegion mKnobRegion;

  8.         private TiledTextureRegion mFaceRegion;

  9.         

  10.         

  11.         @Override

  12.         public EngineOptions onCreateEngineOptions() {

  13.                 // TODO Auto-generated method stub

  14.                 mCamera = new Camera(0,0,CAMERA_WIDTH,CAMERA_HEIGHT);

  15.                 EngineOptions mEngineOptions = new EngineOptions(true,ScreenOrientation.LANDSCAPE_SENSOR, new RatioResolutionPolicy(CAMERA_WIDTH,CAMERA_HEIGHT),mCamera);

  16.                 return mEngineOptions;

  17.         }


  18.         @Override

  19.         public void onCreateResources(

  20.                         OnCreateResourcesCallback pOnCreateResourcesCallback)

  21.                         throws Exception {

  22.                 // TODO Auto-generated method stub

  23.                 mBackground = new RepeatingSpriteBackground(CAMERA_WIDTH, CAMERA_HEIGHT, getTextureManager(), AssetBitmapTextureAtlasSource.create(getAssets(), "background_grass.png"), getVertexBufferObjectManager());

  24.                 

  25.                 BitmapTextureAtlas mTexture = new BitmapTextureAtlas(getTextureManager(), 256, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);

  26.                 

  27.                 mBaseRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "onscreen_control_base.png", 0, 0, 1, 1);

  28.                 mKnobRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "onscreen_control_knob.png",128,0,1, 1);

  29.                 mFaceRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "face_box.png", 192, 0, 1, 1);

  30.                 

  31.                 mTexture.load();

  32.                 

  33.                 pOnCreateResourcesCallback.onCreateResourcesFinished();

  34.         }

复制代码


在这里,控制器的背景,控制器指针和精灵脸蛋共用一个Texture.              
2.在onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)函数中,定义了3条直线,一个人脸精灵和一个控制器

  1. Scene mScene = new Scene();

  2.             mScene.setBackground(mBackground);

  3.             

  4.             final Line mDownLine = new Line(0,0,0,0,3,getVertexBufferObjectManager());

  5.                   mDownLine.setColor(1, 0, 0);

  6.             final Line mLeftLine = new Line(0,0,0,0,3,getVertexBufferObjectManager());

  7.                   mLeftLine.setColor(1, 0, 0);

  8.             final Line mRightLine = new Line(0,0,0,0,3,getVertexBufferObjectManager());

  9.                   mRightLine.setColor(1, 0, 0);

  10.             

  11.             final MySprite mFace = new MySprite(100, 100,mFaceRegion, getVertexBufferObjectManager()){


  12.                         @Override

  13.                         protected void onManagedUpdate(float pSecondsElapsed) {

  14.                                 // TODO Auto-generated method stub

  15.                                 float mCoordinates[] = this.convertLocalToSceneCoordinates(11, 13);//坐标转换

  16.                                 float x = mCoordinates[0];

  17.                                 float y = mCoordinates[1];

  18.                                 mDownLine.setPosition(x, y+50, x, y);

  19.                                 mLeftLine.setPosition(x-10, y+10, x, y);

  20.                                 mRightLine.setPosition(x+10, y+10, x, y);

  21.                                 super.onManagedUpdate(pSecondsElapsed);

  22.                         }

  23.                     

  24.                     

  25.             };

复制代码


在这里比较重要的是convertLocalToSceneCoordinates函数,先看看它是如何实现的,这个方法是在Entity类中实现的:

  1. /* (non-Javadoc)

  2.          * @see org.andengine.entity.IEntity#convertLocalToSceneCoordinates(float[])

  3.          */

  4.         @Override

  5.         public float[] convertLocalToSceneCoordinates(final float[] pCoordinates) {

  6.                 return this.convertLocalToSceneCoordinates(pCoordinates, Entity.VERTICES_LOCAL_TO_SCENE_TMP);

  7.         }


  8.         /* (non-Javadoc)

  9.          * @see org.andengine.entity.IEntity#convertLocalToSceneCoordinates(float[], float[])

  10.          */

  11.         @Override

  12.         public float[] convertLocalToSceneCoordinates(final float[] pCoordinates, final float[] pReuse) {

  13.                 final Transformation localToSceneTransformation = this.getLocalToSceneTransformation();


  14.                 pReuse[Constants.VERTEX_INDEX_X] = pCoordinates[Constants.VERTEX_INDEX_X];

  15.                 pReuse[Constants.VERTEX_INDEX_Y] = pCoordinates[Constants.VERTEX_INDEX_Y];


  16.                 localToSceneTransformation.transform(pReuse);


  17.                 return pReuse;

  18.         }

复制代码


再跟踪getLocalToSceneTransformation() :

  1. @Override

  2.         public Transformation getLocalToSceneTransformation() {

  3.                 if(this.mLocalToSceneTransformation == null) {

  4.                         this.mLocalToSceneTransformation = new Transformation();

  5.                 }


  6.                 // TODO Cache if parent(recursive) not dirty.

  7.                 final Transformation localToSceneTransformation = this.mLocalToSceneTransformation;

  8.                 localToSceneTransformation.setTo(this.getLocalToParentTransformation());


  9.                 final IEntity parent = this.mParent;

  10.                 if(parent != null) {

  11.                         localToSceneTransformation.postConcat(parent.getLocalToSceneTransformation());

  12.                 }


  13.                 return localToSceneTransformation;

  14.         }

复制代码


这就是经过一系列的转换得到的
3.布置AnalogOnScreenControl:

  1. AnalogOnScreenControl mController = new AnalogOnScreenControl(30, CAMERA_HEIGHT - mBaseRegion.getHeight() - 30, mCamera, mBaseRegion, mKnobRegion, 0.1f, 100, getVertexBufferObjectManager(), 

  2.                             new IAnalogOnScreenControlListener(){


  3.                                         @Override

  4.                                         public void onControlChange(

  5.                                                         BaseOnScreenControl pBaseOnScreenControl,

  6.                                                         float pValueX, float pValueY) {

  7.                                                 // TODO Auto-generated method stub

  8.                                                 mFace.setVelocityXY(pValueX*100,pValueY*100);

  9.                                         }


  10.                                         @Override

  11.                                         public void onControlClick(

  12.                                                         AnalogOnScreenControl pAnalogOnScreenControl) {

  13.                                                 // TODO Auto-generated method stub

  14.                                                 

  15.                                         }

  16.                     

  17.                     

  18.             });

复制代码


4.将各种角色添加到场景中

  1. mFace.registerEntityModifier(new LoopEntityModifier(new SequenceEntityModifier(new ScaleModifier(3, 1.0f, 4.5f),

  2.                                 new RotationModifier(5, 0, 360),new ScaleModifier(3, 4.5f, 1.0f),new RotationModifier(2, 360, 0))));

  3.             mScene.attachChild(mFace);

  4.             mScene.attachChild(mDownLine);

  5.             mScene.attachChild(mLeftLine);

  6.             mScene.attachChild(mRightLine);

  7.             mScene.setChildScene(mController);

  8.                 pOnCreateSceneCallback.onCreateSceneFinished(mScene);

复制代码


在这里,精灵脸蛋通过修改器来实现缩放和旋转,移动是用过控制器来实现的
5.最后是自定义的精灵类,主要是一点点的修改而已

  1. public class  MySprite extends TiledSprite{


  2.           private float mVelocityX = 0;

  3.           private float mVelocityY = 0;

  4.           

  5.         public MySprite(float pX, float pY,

  6.                         ITiledTextureRegion pTiledTextureRegion,

  7.                         VertexBufferObjectManager pVertexBufferObjectManager) {

  8.                 super(pX, pY, pTiledTextureRegion, pVertexBufferObjectManager);

  9.                 // TODO Auto-generated constructor stub

  10.                 

  11.         }


  12.         @Override

  13.         protected void onManagedUpdate(float pSecondsElapsed) {

  14.                 // TODO Auto-generated method stub

  15.                 this.mX += mVelocityX * pSecondsElapsed;

  16.                 this.mY += mVelocityY * pSecondsElapsed;

  17.                 

  18.                 this.setPosition(mX, mY);

  19.                 super.onManagedUpdate(pSecondsElapsed);

  20.         }

  21.            

  22.         void setVelocityXY(float vX, float vY){

  23.                 mVelocityX = vX;

  24.                 mVelocityY = vY;

  25.         }

  26.         

  27.    }

复制代码


3.测试经过层层写代码,是时候看看效果啦,每次到这里都是最开心的时刻哦





转载地址:http://blog.csdn.net/cen616899547/article/details/8140491

http://www.eoeandroid.com/forum-863-1.html

www.ogengine.com