【问题标题】:Rotate on touch by AndEngine通过 AndEngine 触摸旋转
【发布时间】:2012-08-17 08:03:55
【问题描述】:

我有一个名为“枪”的 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));

非常感谢

【问题讨论】:

    标签: java android andengine


    【解决方案1】:

    你应该解决两件事:

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

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

      gun.setRotationCenter(0, 0);
      

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

    注意:

    您应该了解有关 AndEngine (Box2D) 中的物理的更多信息。做你想做的事,通常你应该这样做:

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

    你可以在Physics\Using a RevoluteJoint + MouseJoint看到AndEngine Examples的例子。

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

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

    【讨论】:

    • 您的注释仅适用于 OP 想要制作物理游戏的情况,此处可能并非如此。
    • ok John,因为我看到OP使用AndEngine而不是原生绘图表面,所以我在这里建议引擎的消耗性使用。乍一看,我认为 'JustMe' 和我之前的情况一样,当时我试图放入大部分数学,然后浪费了很多时间来解决运行时问题。
    • 当然,没关系。我只是想确保 OP 不会使用 Box2D 只是为了避免做一些数学运算,因为那将是一个巨大的过度杀伤和性能/内存消耗。您的回答写得很好,很有道理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-02
    • 1970-01-01
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多