Управление событиями мыши в моем графическом интерфейсе

Я разработал игровой графический интерфейс с JMonkeyengine введите здесь описание изображения

package adventure;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.TextArea;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.JFrame;
import javax.swing.JPanel;

import com.jme3.app.SimpleApplication;
import com.jme3.asset.plugins.ZipLocator;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.collision.shapes.CollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.bullet.util.CollisionShapeFactory;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeCanvasContext;

/**
 * Example 9 - How to make walls and floors solid. This collision code uses
 * Physics and a custom Action Listener.
 * 
 * @author normen, with edits by Zathras
 */
public class TownView extends SimpleApplication implements ActionListener,
        Playable {

    private Spatial sceneModel;
    private BulletAppState bulletAppState;
    private RigidBodyControl landscape;
    private CharacterControl player;
    private Vector3f walkDirection = new Vector3f();
    private boolean left = false, right = false, up = false, down = false;

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                AppSettings settings = new AppSettings(true);
                settings.setWidth(850);
                settings.setHeight(440);

                TownView canvasApplication = new TownView();
                canvasApplication.setSettings(settings);
                canvasApplication.createCanvas(); // create canvas!
                JmeCanvasContext ctx = (JmeCanvasContext) canvasApplication
                        .getContext();
                ctx.setSystemListener(canvasApplication);
                Dimension dim = new Dimension(640, 480);
                ctx.getCanvas().setPreferredSize(dim);

                JFrame window = new JFrame("Swing Application");
                window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                JPanel panel = new JPanel(new BorderLayout()); // a panel
                World world = new DungeonWorld(canvasApplication);
                Person me = new Person(world, "You", null);
                PlaceView placeview = new PlaceView(me);
                Commands commands = new Commands(me);
                TextArea textarea = new TextArea("", 10, 60,
                        TextArea.SCROLLBARS_VERTICAL_ONLY);
                textarea.append("You are in a dungeon. The horrible shrieks of the undead chill your bones.\n");
                textarea.setEditable(false);
                panel.add("West", ctx.getCanvas());
                panel.add("East", commands);
                panel.add("South", textarea);
                window.add(panel);
                window.pack();
                window.setVisible(true);
                canvasApplication.startCanvas();

            }
        });
    }

    public void simpleInitApp() {
        /** Set up Physics */
        bulletAppState = new BulletAppState();
        stateManager.attach(bulletAppState);
        // bulletAppState.getPhysicsSpace().enableDebug(assetManager);

        // We re-use the flyby camera for rotation, while positioning is handled
        // by physics
        viewPort.setBackgroundColor(new ColorRGBA(0.7f, 0.8f, 1f, 1f));
        flyCam.setMoveSpeed(100);
        setUpKeys();
        setUpLight();

        // We load the scene from the zip file and adjust its size.
        assetManager.registerLocator("town.zip", ZipLocator.class);
        sceneModel = assetManager.loadModel("main.scene");
        sceneModel.setLocalScale(2f);

        // We set up collision detection for the scene by creating a
        // compound collision shape and a static RigidBodyControl with mass
        // zero.
        CollisionShape sceneShape = CollisionShapeFactory
                .createMeshShape((Node) sceneModel);
        landscape = new RigidBodyControl(sceneShape, 0);
        sceneModel.addControl(landscape);

        // We set up collision detection for the player by creating
        // a capsule collision shape and a CharacterControl.
        // The CharacterControl offers extra settings for
        // size, stepheight, jumping, falling, and gravity.
        // We also put the player in its starting position.
        CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.5f,
                6f, 1);
        player = new CharacterControl(capsuleShape, 0.05f);
        player.setJumpSpeed(20);
        player.setFallSpeed(30);
        player.setGravity(30);
        player.setPhysicsLocation(new Vector3f(0, 10, 0));

        // We attach the scene and the player to the rootNode and the physics
        // space,
        // to make them appear in the game world.
        rootNode.attachChild(sceneModel);
        bulletAppState.getPhysicsSpace().add(landscape);
        bulletAppState.getPhysicsSpace().add(player);
    }

    private void setUpLight() {
        // We add light so we see the scene
        AmbientLight al = new AmbientLight();
        al.setColor(ColorRGBA.White.mult(1.3f));
        rootNode.addLight(al);

        DirectionalLight dl = new DirectionalLight();
        dl.setColor(ColorRGBA.White);
        dl.setDirection(new Vector3f(2.8f, -2.8f, -2.8f).normalizeLocal());
        rootNode.addLight(dl);
    }

    /**
     * We over-write some navigational key mappings here, so we can add
     * physics-controlled walking and jumping:
     */
    private void setUpKeys() {
        inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));
        inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));
        inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W));
        inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S));
        inputManager.addMapping("Jump", new KeyTrigger(KeyInput.KEY_SPACE));
        inputManager.addListener(this, "Left");
        inputManager.addListener(this, "Right");
        inputManager.addListener(this, "Up");
        inputManager.addListener(this, "Down");
        inputManager.addListener(this, "Jump");
    }

    /**
     * These are our custom actions triggered by key presses. We do not walk
     * yet, we just keep track of the direction the user pressed.
     */
    public void onAction(String binding, boolean value, float tpf) {
        if (binding.equals("Left")) {
            left = value;
        } else if (binding.equals("Right")) {
            right = value;
        } else if (binding.equals("Up")) {
            up = value;
        } else if (binding.equals("Down")) {
            down = value;
        } else if (binding.equals("Jump")) {
            player.jump();
        }
    }

    /**
     * This is the main event loop--walking happens here. We check in which
     * direction the player is walking by interpreting the camera direction
     * forward (camDir) and to the side (camLeft). The setWalkDirection()
     * command is what lets a physics-controlled player walk. We also make sure
     * here that the camera moves with player.
     */
    @Override
    public void simpleUpdate(float tpf) {
        Vector3f camDir = cam.getDirection().clone().multLocal(0.6f);
        Vector3f camLeft = cam.getLeft().clone().multLocal(0.4f);
        walkDirection.set(0, 0, 0);
        if (left) {
            walkDirection.addLocal(camLeft);
        }
        if (right) {
            walkDirection.addLocal(camLeft.negate());
        }
        if (up) {
            walkDirection.addLocal(camDir);
        }
        if (down) {
            walkDirection.addLocal(camDir.negate());
        }
        player.setWalkDirection(walkDirection);
        cam.setLocation(player.getPhysicsLocation());
    }

    // Load an image from the net, making sure it has already been
    // loaded when the method returns
    public Image loadPicture(String imageName) {
        Image im = null;

        // Load the image from the net
        try {
            URL imageSource = new URL(
                    "http://www.student.nada.kth.se/~d99-nro/" + imageName);

        } catch (MalformedURLException e) {
        }

        return im;
    }

    // Load and play a sound from /usr/local/hacks/sounds/

    public void playSound(String name) {
        URL u = null;

        try {
            u = new URL("file:" + "/usr/local/hacks/sounds/" + name + ".au");
        } catch (MalformedURLException e) {
        }

        AudioClip a = Applet.newAudioClip(u);
        a.play();
    }

}

Теперь я хочу, чтобы мышь и клики регистрировались с холстом на курсоре над холстом, чтобы я мог использовать кнопки для севера, запада, востока и панелей списка. Можете ли вы помочь мне, как этого добиться? Теперь события мыши и клавиатуры регистрируются на холсте, даже если курсор находится за пределами холста, что делает закрытие окон с помощью Alt + F4 единственным способом закрытия окон, и я не могу использовать свой кнопки направления.


person Niklas R.    schedule 08.07.2012    source источник
comment
Какое приятное подземелье!   -  person David B    schedule 08.07.2012
comment
Общее решение состоит в реализации прослушивателя событий (перехватывающего щелчки мыши), который находит координаты щелчка и проверяет, находится ли он в границах холста. Если это так, он может «принять» событие; передайте его остальной части вашего приложения или «отклоните» его. Извините, я не могу дать вам реализацию; У меня нет опыта работы с JMonnkeyEngine или Swing.   -  person Anti Earth    schedule 08.07.2012
comment
@Anti Earth Большое спасибо за комментарий, который, по крайней мере, дает мне представление о том, как это сделать.   -  person Niklas R.    schedule 08.07.2012
comment
Ребята, я нашел ответ и разместил его здесь. Спасибо за помощь.   -  person Niklas R.    schedule 09.07.2012


Ответы (1)


public void simpleInitApp() {
    flyCam.setDragToRotate(true);
    ...

Просто прочитал в мануале и все заработало.

person Niklas R.    schedule 09.07.2012