3

我有名为“枪”的 Sprite,我想通过用户触摸来旋转它。
我的问题:当我触摸并向下移动时它会旋转并且效果很好,但是当我触摸并向上移动时它不会旋转。
这是我的代码:

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));

非常感谢

4

1 回答 1

3

您应该修复两件事:

  • 实际上directionY是(让我们查看您的公式):

    float directionY = pSceneTouchEvent.getY() - gun.getY();
    
  • 与您的枪的世界位置相比,您directionXdirectionY是触摸位置的移位元素[top,left]=> 所以您计算的角度实际上是围绕这把枪[top,left]位置的旋转。因此,事情应该是:

    gun.setRotationCenter(0, 0);
    

其中 (0,0) 是本地 [top, left] 相对位置,用于设置枪中旋转的锚点。

笔记:

您应该了解有关 AndEngine (Box2D) 中的物理的更多信息。要随心所欲地做事,通常应该执行以下操作:

  • fix anchor body在您希望gun旋转的位置创建一个(可能是圆形体)。
  • 用这个锚创建一个RevoluteJoint来固定你的枪。
  • Mouse Joint每次触摸您的枪并释放您的触摸时,在您的枪和鼠标点之间创建和处置一个。

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

这将帮助您创建在现实世界中发生的正常交互,而不管计算身体对象的位置、旋转或速度(因为物理引擎会为您完成)。

此外,您可以在游戏中的任何对象上应用相同的机制(通过将上述过程封装在函数或类中)。

于 2012-08-22T07:52:30.567 回答