如何确保只按下一个键

时间:2013-08-05 05:39:28

标签: java optimization libgdx keylistener

所以我正在制作一个用户在水平垂直平铺地图上移动的游戏。但是我不希望用户能够按下2个键并让玩家移动对角线。左,右,上,下。

我目前有一个代码可以执行此操作,但如果用户按下另一个键然后将其抬起,则播放器因我编码而停止移动

@Override
public boolean keyDown(int keycode) {
    if (keyNotDown) {
        switch (keycode) {
        case Keys.RIGHT:
            playScreen.setXD(2);
            break;
        case Keys.LEFT:
            playScreen.setXD(-2);
            break;
        case Keys.DOWN:
            playScreen.setYD(-2);
            break;
        case Keys.UP:
            playScreen.setYD(2);
            break;
        }
        keyNotDown = false;
    }
    return false;
}


@Override
public boolean keyUp(int keycode) {
    player.stopMove();
    keyNotDown = true;
    return false;
}

正如你可以看到一个人在按下另一个按键时按下一个按键,它将无法工作,但当他们抬起所述按键时,它将停止移动

修改

当用户按下某个键时,它会将xd,yD值发送到render方法,并且因为render继续被调用,所以它会继续使用xD,yD值移动播放器。停止移动方法将这些值重置为0,以便在未按下该键时停止移动。

2 个答案:

答案 0 :(得分:2)

请尝试以下代码并告诉我,因为我还没有测试过。

private KEY_PRESSE keyPressed = KEY_PRESSE.NONE;

    @Override
    public boolean keyDown(int keycode) {
        switch (keycode) {
        case Keys.RIGHT:
            if (keyPressed.equals(KEY_PRESSE.RIGHT) || keyPressed.equals(KEY_PRESSE.NONE)) {
                playScreen.setXD(2);
                keyPressed = KEY_PRESSE.RIGHT;
                break;
            }
        case Keys.LEFT:
            if (keyPressed.equals(KEY_PRESSE.LEFT) || keyPressed.equals(KEY_PRESSE.NONE)) {
                playScreen.setXD(-2);
                keyPressed = KEY_PRESSE.LEFT;
                break;
            }

        case Keys.DOWN:
            if (keyPressed.equals(KEY_PRESSE.DOWN) || keyPressed.equals(KEY_PRESSE.NONE)) {
                playScreen.setYD(-2);
                keyPressed = KEY_PRESSE.DOWN;
                break;
            }
        case Keys.UP:
            if (keyPressed.equals(KEY_PRESSE.UP) || keyPressed.equals(KEY_PRESSE.NONE)) {
                playScreen.setYD(2);
                keyPressed = KEY_PRESSE.UP;
                break;
            }
        }
        return false;
    }

    @Override
    public boolean keyUp(int keycode) {
        player.stopMove();// I don't know exactly but can you remove this ligne, I
                            // think its useless , when no key is pressed
                            // the player will stop no?
        keyPressed = KEY_PRESSE.NONE;
        return false;
    }

    enum KEY_PRESSE {
        RIGHT, LEFT, DOWN, UP, NONE
    }

答案 1 :(得分:1)

通常情况下,我不会发布完整的解决方案,但您想要做的事情相当简单。该解决方案为您提供了一种实现设计的不同方式。由于你的速度是恒定的,我认为不需要设置三角洲但只改变方向。

您可以跟踪按键,根据按下的内容,您可以确定移动角色的方向。因此,例如,当您按向上箭头时,它会将方向设置为向上,但是当您按向左键时我会跟踪它但忽略按钮。如果你释放向上箭头,那么你的角色将向左移动,在任何时候它都不会向多个方向移动。

import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputAdapter;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;

public class Move implements ApplicationListener {
    private static final Map<Integer, Direction> MOVE_KEYS = new HashMap<Integer, Direction>(){{
        this.put(Keys.RIGHT, Direction.RIGHT);
        this.put(Keys.LEFT, Direction.LEFT);
        this.put(Keys.UP, Direction.UP);
        this.put(Keys.DOWN, Direction.DOWN);
    }};

    private static enum Direction {
        RIGHT, LEFT, UP, DOWN;
    }

    private static class Player {
        public float x;
        public float y;
        public float speed;
        public Queue<Direction> dirStack = new LinkedList<Direction>();

        public Player(float x, float y, float speed) {
            this.x = x;
            this.y = y;
            this.speed = speed;
        }

        public void update(float delta) {
            if (!dirStack.isEmpty()) {
                switch(dirStack.peek()) {
                case DOWN: 
                    y -= speed;
                    break;
                case LEFT:
                    x -= speed;
                    break;
                case RIGHT:
                    x += speed;
                    break;
                case UP:
                    y += speed;
                    break;
                }
            }
        }

        public void render(ShapeRenderer render) {
            render.begin(ShapeType.FilledRectangle);
            render.setColor(1, 0, 0, 1);
            render.filledRect(x, y, 20, 20);
            render.end();
        }
    }

    private static class MoveController extends InputAdapter {
        private final Player player;

        public MoveController(Player player) {
            this.player = player;
        }

        @Override public boolean keyDown(int keycode) {
            if (MOVE_KEYS.containsKey(keycode)) {
                final Direction dir = MOVE_KEYS.get(keycode);
                Gdx.app.log("D", dir.toString());
                return player.dirStack.add(dir);
            }
            return false;
        }

        @Override public boolean keyUp(int keycode) {
            if (MOVE_KEYS.containsKey(keycode)) {
                final Direction dir = MOVE_KEYS.get(keycode);
                Gdx.app.log("U", dir.toString());
                return player.dirStack.remove(dir);
            }
            return false;
        }
    }

    private Camera cam;
    private ShapeRenderer render;
    private Player player;

    @Override public void create() {
        Gdx.app.log("CREATE", "App Opening");

        this.player = new Player(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, 5);
        Gdx.input.setInputProcessor(new MoveController(player));

        this.cam = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
        this.render = new ShapeRenderer();

        cam.apply(Gdx.gl10);

        Gdx.gl10.glClearColor(0f, 0f, 0f, 1);
    }

    @Override public void render() {
        Gdx.gl10.glClear(GL20.GL_COLOR_BUFFER_BIT);

        player.update(Gdx.graphics.getDeltaTime());
        player.render(render);
    }

    @Override public void dispose() {
        Gdx.app.log("DISPOSE", "App Closing");
    }

    @Override public void resize(final int width, final int height) {
        Gdx.app.log("RESIZE", width + "x" + height);
        Gdx.gl10.glViewport(0, 0, width, height);
    }

    @Override public void pause() {}

    @Override public void resume() {}
}