[AndEngine学习教程] 第7节 场景精灵间的坐标转换

1.要点分析

      1.在制作动画精灵的时候,为了方便计算,常常需要把场景中的坐标转换为精灵的内部坐标,

        或者需要把精灵的内部坐标转换为场景坐标.如果精灵没有进行过旋转操作,他们之间只差

         一个offse而已

      2.本节需要实现的是在一个人脸精灵内,找到他的眼睛位置,然后随意变换精灵(大小比例,旋转,移动等),

          然后依旧定位出精灵的眼睛.

2.新内容

      1.要在Activity上标注精灵的眼睛,需要使用到箭头,在简略的情况下,可以用三根直线实现,好在AndEngine

         已经为我们提供一Line类:public class Line extends Shape

        

/**
	 * Uses a default {@link HighPerformanceLineVertexBufferObject} in {@link DrawType#STATIC} with the {@link VertexBufferObjectAttribute}s: {@link Line#VERTEXBUFFEROBJECTATTRIBUTES_DEFAULT}.
	 */
	public Line(final float pX1, final float pY1, final float pX2, final float pY2, final VertexBufferObjectManager pVertexBufferObjectManager) {
		this(pX1, pY1, pX2, pY2, Line.LINE_WIDTH_DEFAULT, pVertexBufferObjectManager, DrawType.STATIC);
	}

	/**
	 * Uses a default {@link HighPerformanceLineVertexBufferObject} with the {@link VertexBufferObjectAttribute}s: {@link Line#VERTEXBUFFEROBJECTATTRIBUTES_DEFAULT}.
	 */
	public Line(final float pX1, final float pY1, final float pX2, final float pY2, final VertexBufferObjectManager pVertexBufferObjectManager, final DrawType pDrawType) {
		this(pX1, pY1, pX2, pY2, Line.LINE_WIDTH_DEFAULT, pVertexBufferObjectManager, pDrawType);
	}

	/**
	 * Uses a default {@link HighPerformanceLineVertexBufferObject} in {@link DrawType#STATIC} with the {@link VertexBufferObjectAttribute}s: {@link Line#VERTEXBUFFEROBJECTATTRIBUTES_DEFAULT}.
	 */
	public Line(final float pX1, final float pY1, final float pX2, final float pY2, final float pLineWidth, final VertexBufferObjectManager pVertexBufferObjectManager) {
		this(pX1, pY1, pX2, pY2, pLineWidth, pVertexBufferObjectManager, DrawType.STATIC);
	}

	public Line(final float pX1, final float pY1, final float pX2, final float pY2, final float pLineWidth, final VertexBufferObjectManager pVertexBufferObjectManager, final DrawType pDrawType) {
		this(pX1, pY1, pX2, pY2, pLineWidth, new HighPerformanceLineVertexBufferObject(pVertexBufferObjectManager, Line.LINE_SIZE, pDrawType, true, Line.VERTEXBUFFEROBJECTATTRIBUTES_DEFAULT));
	}

	public Line(final float pX1, final float pY1, final float pX2, final float pY2, final float pLineWidth, final ILineVertexBufferObject pLineVertexBufferObject) {
		super(pX1, pY1, PositionColorShaderProgram.getInstance());

      2.AnalogOnScreenControl类,这个我们在上一节的内容中已经详细介绍了,使用这个类只是方便我们观看坐标切换后的效果

3.源代码分析

        1.内部成员变量定义:背景+控制器+精灵脸

            

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 mFaceRegion;
	
	
	@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 mTexture = new BitmapTextureAtlas(getTextureManager(), 256, 128, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
		
		mBaseRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "onscreen_control_base.png", 0, 0, 1, 1);
		mKnobRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "onscreen_control_knob.png",128,0,1, 1);
		mFaceRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(mTexture, this, "face_box.png", 192, 0, 1, 1);
		
		mTexture.load();
		
		pOnCreateResourcesCallback.onCreateResourcesFinished();
	}
在这里,控制器的背景,控制器指针和精灵脸蛋共用一个Texture.

     

         2.在onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback)函数中,定义了3条直线,一个人脸精灵和一个控制器

           

Scene mScene = new Scene();
	    mScene.setBackground(mBackground);
	    
	    final Line mDownLine = new Line(0,0,0,0,3,getVertexBufferObjectManager());
	          mDownLine.setColor(1, 0, 0);
	    final Line mLeftLine = new Line(0,0,0,0,3,getVertexBufferObjectManager());
	          mLeftLine.setColor(1, 0, 0);
	    final Line mRightLine = new Line(0,0,0,0,3,getVertexBufferObjectManager());
	          mRightLine.setColor(1, 0, 0);
	    
	    final MySprite mFace = new MySprite(100, 100,mFaceRegion, getVertexBufferObjectManager()){

			@Override
			protected void onManagedUpdate(float pSecondsElapsed) {
				// TODO Auto-generated method stub
				float mCoordinates[] = this.convertLocalToSceneCoordinates(11, 13);//坐标转换
				float x = mCoordinates[0];
				float y = mCoordinates[1];
				mDownLine.setPosition(x, y+50, x, y);
				mLeftLine.setPosition(x-10, y+10, x, y);
				mRightLine.setPosition(x+10, y+10, x, y);
				super.onManagedUpdate(pSecondsElapsed);
			}
	    	
	    	
	    };


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

    

/* (non-Javadoc)
	 * @see org.andengine.entity.IEntity#convertLocalToSceneCoordinates(float[])
	 */
	@Override
	public float[] convertLocalToSceneCoordinates(final float[] pCoordinates) {
		return this.convertLocalToSceneCoordinates(pCoordinates, Entity.VERTICES_LOCAL_TO_SCENE_TMP);
	}

	/* (non-Javadoc)
	 * @see org.andengine.entity.IEntity#convertLocalToSceneCoordinates(float[], float[])
	 */
	@Override
	public float[] convertLocalToSceneCoordinates(final float[] pCoordinates, final float[] pReuse) {
		final Transformation localToSceneTransformation = this.getLocalToSceneTransformation();

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

		localToSceneTransformation.transform(pReuse);

		return pReuse;
	}
再跟踪 getLocalToSceneTransformation() :

       

@Override
	public Transformation getLocalToSceneTransformation() {
		if(this.mLocalToSceneTransformation == null) {
			this.mLocalToSceneTransformation = new Transformation();
		}

		// TODO Cache if parent(recursive) not dirty.
		final Transformation localToSceneTransformation = this.mLocalToSceneTransformation;
		localToSceneTransformation.setTo(this.getLocalToParentTransformation());

		final IEntity parent = this.mParent;
		if(parent != null) {
			localToSceneTransformation.postConcat(parent.getLocalToSceneTransformation());
		}

		return localToSceneTransformation;
	}
这就是经过一系列的转换得到的


    3.布置AnalogOnScreenControl:

          

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

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

					@Override
					public void onControlClick(
							AnalogOnScreenControl pAnalogOnScreenControl) {
						// TODO Auto-generated method stub
						
					}
	    	
	    	
	    });

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

     

mFace.registerEntityModifier(new LoopEntityModifier(new SequenceEntityModifier(new ScaleModifier(3, 1.0f, 4.5f),
				new RotationModifier(5, 0, 360),new ScaleModifier(3, 4.5f, 1.0f),new RotationModifier(2, 360, 0))));
	    mScene.attachChild(mFace);
	    mScene.attachChild(mDownLine);
	    mScene.attachChild(mLeftLine);
	    mScene.attachChild(mRightLine);
	    mScene.setChildScene(mController);
		pOnCreateSceneCallback.onCreateSceneFinished(mScene);
在这里,精灵脸蛋通过修改器来实现缩放和旋转,移动是用过控制器来实现的


5.最后是自定义的精灵类,主要是一点点的修改而已

    

public class  MySprite extends TiledSprite{

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

	@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 setVelocityXY(float vX, float vY){
		mVelocityX = vX;
		mVelocityY = vY;
	}
	
   }

3.测试

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

   转载请注明出处哦!谢谢,made by Season, 2012-11-2 14:25

[AndEngine学习教程] 第7节 场景精灵间的坐标转换_第1张图片


[AndEngine学习教程] 第7节 场景精灵间的坐标转换_第2张图片


[AndEngine学习教程] 第7节 场景精灵间的坐标转换_第3张图片



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


你可能感兴趣的:([AndEngine学习教程] 第7节 场景精灵间的坐标转换)