如何在JME3中正确地听鼠标移动?

时间:2014-05-16 20:36:10

标签: java 3d jmonkeyengine

我希望几何体通过鼠标移动绕其中心旋转。

类似于相机在样品应用中旋转。

下面的程序应该在鼠标水平移动时旋转立方体。如果鼠标向左移动,它应该向左旋转,如果鼠标向右移动,它应该向右旋转。

不幸的是,它总是向右旋转。

package jme3test.helloworld;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jme3.app.SimpleApplication;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.MouseAxisTrigger;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.math.ColorRGBA;

public class HelloJME3_3 extends SimpleApplication {

    private static final Logger log = LoggerFactory.getLogger(HelloJME3_3.class);

    public static void main(String[] args){
        HelloJME3_3 app = new HelloJME3_3();
        app.start(); // start the game
    }

    @Override
    public void simpleInitApp() {
        Box b = new Box(1, 1, 1); // create cube shape
        final Geometry geom = new Geometry("Box", b);  // create cube geometry from the shape
        Material mat = new Material(assetManager,
          "Common/MatDefs/Misc/Unshaded.j3md");  // create a simple material
        mat.setColor("Color", ColorRGBA.Blue);   // set color of material to blue
        geom.setMaterial(mat);                   // set the cube's material
        rootNode.attachChild(geom);              // make the cube appear in the scene


        flyCam.setEnabled(false); 

        inputManager.addMapping("RotateX", 
                new MouseAxisTrigger(MouseInput.AXIS_X, false),
                new MouseAxisTrigger(MouseInput.AXIS_X, true)
        );

        inputManager.addListener(new AnalogListener() {

            @Override
            public void onAnalog(String name, float value, float tpf) {
                log.debug(name);

                if( "RotateX".equals(name) ) {
                    //geom.rotate((float) (value*speed), 0, 0);
                    geom.rotate(0, (float) (value*speed), 0);

                }
            }
        }, "RotateX");



    }
}

2 个答案:

答案 0 :(得分:1)

这里的问题是正轴和负轴运动都会为value生成正值。因此,您的对象只能以一种方式旋转。

最简单的解决方案是分别绑定正轴和负轴运动并分别管理它们。

public class HelloJME_3 extends SimpleApplication {


    public static void main(String[] args){
        HelloJME_3 app = new HelloJME_3();
        app.start(); // start the game
    }

    @Override
    public void simpleInitApp() {
        Box b = new Box(1, 1, 1); // create cube shape
        final Geometry geom = new Geometry("Box", b);  // create cube geometry from the shape
        Material mat = new Material(assetManager,
          "Common/MatDefs/Misc/Unshaded.j3md");  // create a simple material
        mat.setColor("Color", ColorRGBA.Blue);   // set color of material to blue
        geom.setMaterial(mat);                   // set the cube's material
        rootNode.attachChild(geom);              // make the cube appear in the scene


        flyCam.setEnabled(false); 

        inputManager.addMapping("RotateX", 
                new MouseAxisTrigger(MouseInput.AXIS_X, true)
        );

        inputManager.addMapping("RotateX_negative", 
                new MouseAxisTrigger(MouseInput.AXIS_X, false)
        );


        inputManager.addListener(new AnalogListener() {

            @Override
            public void onAnalog(String name, float value, float tpf) {

                if( "RotateX".equals(name) ) {
                    geom.rotate(0, (float) (value*speed), 0);

                }else if("RotateX_negative".equals(name)){
                    geom.rotate(0, (float) (-value*speed), 0);
                }
            }
        }, "RotateX", "RotateX_negative");


    }
}

绝对光标位置的基本旋转

您提到要创建旋转,以便当鼠标位于屏幕中心时,对象不会旋转。您可以使用鼠标屏幕坐标来实现此目的。

inputManager.getCursorPosition();

除了当前的旋转之外,这当然还要求你设置旋转而不是旋转(这需要一个Quaternion参数,但我们不必担心它是如何工作的。

  Quaternion quat=new Quaternion();
  quat.fromAngles(0, desiredAngle, 0);

  geom.setLocalRotation(quat);

当然,当鼠标最初被捕获时,对象将突然移动到其正确的状态"现在鼠标的位置。

完整代码

public class HelloJME_3 extends SimpleApplication {

    public static float PIXELSMOVED_TO_RADIANSROTATED=0.01f;


    public static void main(String[] args){
        HelloJME_3 app = new HelloJME_3();
        app.start(); // start the game
    }

    @Override
    public void simpleInitApp() {
        Box b = new Box(1, 1, 1); // create cube shape
        final Geometry geom = new Geometry("Box", b);  // create cube geometry from the shape
        Material mat = new Material(assetManager,
          "Common/MatDefs/Misc/Unshaded.j3md");  // create a simple material
        mat.setColor("Color", ColorRGBA.Blue);   // set color of material to blue
        geom.setMaterial(mat);                   // set the cube's material
        rootNode.attachChild(geom);              // make the cube appear in the scene


        flyCam.setEnabled(false); 

        inputManager.addMapping("MouseMoved", 
                new MouseAxisTrigger(MouseInput.AXIS_X, false),
                new MouseAxisTrigger(MouseInput.AXIS_X, true)
        );

        inputManager.addListener(new AnalogListener() {

            @Override
            public void onAnalog(String name, float value, float tpf) {
                inputManager.getCursorPosition();

                    float centredX=inputManager.getCursorPosition().x-0.5f*settings.getWidth();

                    Quaternion quat=new Quaternion();
                    quat.fromAngles(0, PIXELSMOVED_TO_RADIANSROTATED*centredX, 0);

                    geom.setLocalRotation(quat);

            }
        }, "MouseMoved");
    }
}

答案 1 :(得分:0)

我正在开发一个类似的项目,这是我的代码,因为它正是你要找的。

    this.addControl("Positive Mouse X", new MouseAxisTrigger(MouseInput.AXIS_X, false));
    this.addControl("Negative Mouse X", new MouseAxisTrigger(MouseInput.AXIS_X, true));
    this.addControl("Positive Mouse Y", new MouseAxisTrigger(MouseInput.AXIS_Y, false));
    this.addControl("Negative Mouse Y", new MouseAxisTrigger(MouseInput.AXIS_Y, true));

这是addControl方法(它在同一个类中因此使用它):

public void addControl(String key, Trigger trigger)
{
    inputManager.addMapping(key, trigger);
    inputManager.addListener(this, key);
}

它真的只是一种方便的方法,但我认为如果能有所帮助就包括它。请记住,MouseAxisTrigger中的布尔值是否为负数。这意味着true会给你一个负值而false会给你一个积极的值,因此我命名为映射。这种混乱的布尔值是一个常见的错误所以在未来的项目中要小心,因为我经常忘记它。

至于处理输入并按照几何体的旋转做你想做的事情,我相信你的示例代码是正确的。