【问题标题】:How to make sure only one key is pressed如何确保只按下一个键
【发布时间】:2013-08-05 05:39:27
【问题描述】:

所以我正在制作一个用户在水平、垂直平铺地图上移动的游戏。但是我不希望用户能够按 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 值移动播放器。 stop move 方法将这些值重置为 0,以便在未按下键时停止移动。

【问题讨论】:

    标签: java optimization libgdx keylistener


    【解决方案1】:

    试试下面的代码并告诉我,因为我还没有测试过。

    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
        }
    

    【讨论】:

    • 当用户按下一个键时,它会将 xd,yD 发送到 render 方法,因此看到 render 不断被调用,它会继续使用 xD,yD 值移动玩家。 stop move 方法将这些值设置为 0
    • 不幸的是,它做同样的事情
    • 我认为如果你删除 stopMove 并保持玩家按下键如果他想通过 playScreen.currentX +=2; 移动会更好你能?然后尝试实现代码
    • 如果我删除 stopMove 方法,播放器实际上不会停止移动
    • 我知道,但是你必须改变移动方式,如果玩家实例是你的可以改变播放方式,你必须按住键移动而不是一键移动它会自行移动,如果可能的话做出(大)改变,否则我没有其他想法
    【解决方案2】:

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

    您可以跟踪按键并根据所按的内容确定移动角色的方向。因此,例如,当您按下向上箭头时,它会将方向设置为向上,但是当您按下向左时,我会跟踪它但忽略该按钮。如果您松开向上箭头,那么您的角色将向左移动,并且在任何时候它的移动方向都不会超过 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() {}
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 2022-07-19
      • 1970-01-01
      • 2012-06-26
      相关资源
      最近更新 更多