2012-08-17 100 views
3

我有Sprite叫做“枪”,我想通过用户触摸旋转它。
我的问题:当我触摸和向下移动它旋转,做工不错,但是当我触摸和移动了它不会转动。
这里是我的代码:AndEngine触摸旋转

package com.example.samplegameone; 

import java.io.IOException; 
import java.io.InputStream; 

import org.andengine.engine.camera.Camera; 
import org.andengine.engine.options.EngineOptions; 
import org.andengine.engine.options.ScreenOrientation; 
import org.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy; 
import org.andengine.entity.scene.Scene; 
import org.andengine.entity.scene.background.Background; 
import org.andengine.entity.sprite.Sprite; 
import org.andengine.entity.util.FPSLogger; 
import org.andengine.input.touch.TouchEvent; 
import org.andengine.opengl.texture.ITexture; 
import org.andengine.opengl.texture.bitmap.BitmapTexture; 
import org.andengine.opengl.texture.region.ITextureRegion; 
import org.andengine.opengl.texture.region.TextureRegionFactory; 
import org.andengine.ui.activity.SimpleBaseGameActivity; 
import org.andengine.util.adt.io.in.IInputStreamOpener; 
import org.andengine.util.debug.Debug; 

import android.util.Log; 
import android.widget.Toast; 

public class SampleGameOne extends SimpleBaseGameActivity { 

private static final int CAMERA_WIDTH = 480; 
private static final int CAMERA_HEIGHT = 320; 

private ITexture mTexture; 
private ITextureRegion mFaceTextureRegion; 
Sprite gun = null; 

@Override 
public EngineOptions onCreateEngineOptions() { 
    final Camera camera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT); 

    return new EngineOptions(true, ScreenOrientation.LANDSCAPE_SENSOR, 
      new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), camera); 
} 

@Override 
public void onCreateResources() { 
    try { 
     this.mTexture = new BitmapTexture(this.getTextureManager(), 
       new IInputStreamOpener() { 
        @Override 
        public InputStream open() throws IOException { 
         return getAssets().open("gfx/gun.png"); 
        } 
       }); 

     this.mTexture.load(); 
     this.mFaceTextureRegion = TextureRegionFactory 
       .extractFromTexture(this.mTexture); 
    } catch (IOException e) { 
     Debug.e(e); 
    } 
} 

@Override 
public Scene onCreateScene() { 
    this.mEngine.registerUpdateHandler(new FPSLogger()); 

    final Scene scene = new Scene(); 
    scene.setBackground(new Background(0.09804f, 0.6274f, 0.8784f)); 

    final float centerX = (CAMERA_WIDTH - this.mFaceTextureRegion 
      .getWidth())/2; 
    final float centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion 
      .getHeight())/2; 

    gun = new Sprite(centerX, centerY, this.mFaceTextureRegion, 
      this.getVertexBufferObjectManager()) { 

     @Override 
     public boolean onAreaTouched(TouchEvent pSceneTouchEvent, 
       float pTouchAreaLocalX, float pTouchAreaLocalY) { 
      switch (pSceneTouchEvent.getAction()) { 
      case TouchEvent.ACTION_DOWN: 

       break; 
      case TouchEvent.ACTION_MOVE: 
       float pValueX = pSceneTouchEvent.getX(); 
       float pValueY = CAMERA_HEIGHT - pSceneTouchEvent.getY(); 

       float directionX = pValueX - gun.getX(); 
       float directionY = (CAMERA_HEIGHT - pValueY) - gun.getY(); 

       float rotationAngle = (float) Math.atan2(directionY, 
         directionX); 
       gun.setRotationCenter(0, gun.getHeight()/2); 
       gun.setRotation(org.andengine.util.math.MathUtils 
         .radToDeg(rotationAngle)); 


       break; 
      case TouchEvent.ACTION_UP: 
       break; 

      default: 
       break; 
      } 
      return super.onAreaTouched(pSceneTouchEvent, pTouchAreaLocalX, 
        pTouchAreaLocalY); 
     } 

    }; 
    scene.registerTouchArea(gun); 
    scene.setTouchAreaBindingOnActionDownEnabled(true); 
    scene.attachChild(gun); 

    return scene; 
} 
} 

我认为,在计算这部分的旋转角度的问题

   float pValueX = pSceneTouchEvent.getX(); 
       float pValueY = CAMERA_HEIGHT - pSceneTouchEvent.getY(); 

       float directionX = pValueX - gun.getX(); 
       float directionY = (CAMERA_HEIGHT - pValueY) - gun.getY(); 

       float rotationAngle = (float) Math.atan2(directionY, 
         directionX); 
       gun.setRotationCenter(0, gun.getHeight()/2); 
       gun.setRotation(org.andengine.util.math.MathUtils 
         .radToDeg(rotationAngle)); 

非常感谢

回答

3

有两件事情你应该修正:

  • 其实directionY是(让检查您的公式):

    float directionY = pSceneTouchEvent.getY() - gun.getY(); 
    
  • directionXdirectionY是触摸位置的换挡元件比较,以你的枪的[top,left]世界上的地位=>让你计算角度实际上是围绕此枪的位置旋转[top,left]。因此,事应是:

    gun.setRotationCenter(0, 0); 
    

,其中(0,0)是本地[顶,左]相对位置来设置锚在枪的旋转。

注:

你应该更多地了解物理学AndEngine(Box2D的)。要做到的事情,只要你想,通常情况下,你应该做如下:

  • 创建fix anchor body(也可以是圆形体),在您希望您的gun来绕。
  • 创建RevoluteJoint与此固定销你的枪。
  • 建立和处置Mouse Joint你的枪和鼠标点之间每次触摸你的枪和释放你的触摸时间。

您可以在Physics\Using a RevoluteJoint + MouseJoint中看到AndEngine示例的示例。

这将帮助你建立正常的相互作用如发生在现实世界中,不管计算位置,旋转,或身体的物体(事业物理引擎会做他们为你)的速度。

多,你可以使用同样的机制(通过封装在函数或类以上程序)游戏内的任何物体上。

+1

你的笔记只适用于OP想用物理进行游戏的情况,这里可能不是这种情况。 – JohnEye 2012-08-22 20:02:37

+0

好的,因为我看到使用AndEngine的OP而不是本地绘图表面,所以我在这里建议使用引擎的消耗品。对于第一次看,我认为'JustMe'与之前的情况是一样的,因为在尝试投入大量数学时,浪费了很多时间来修复运行时问题。 – 2012-08-23 01:54:43

+1

当然,没关系。我只是想确保OP不会使用Box2D只是为了避免进行一些数学运算,因为这将是一个巨大的矫枉过正和性能/内存的巨头。你的答案写得很好,很有道理。 – JohnEye 2012-08-23 09:31:19