2012-08-17 220 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