简体   繁体   English

如何确保仅按下一个键

[英]How to make sure only one key is pressed

SO I'm making a game where the user moves on a horizontal, vertical tiled map. 因此,我正在制作一个用户在水平,垂直平铺地图上移动的游戏。 However I dont want the user to be able to press 2 keys and make the player move diagonal. 但是我不希望用户能够按2键并使播放器向对角线移动。 ony left,right,up and down. 仅左,右,上和下。

I currently have a code that does it but if the user presses another key and then lifts it, the player stops moving due to how I have coded it 我目前有执行此操作的代码,但是如果用户按下另一个键然后将其抬起,则播放器会由于我的编码方式而停止移动

@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;
}

As you can see if a person presses a key while another one is pressed, it will not work but when they lift that said key, then it'll stop moving 如您所见,如果一个人在按下另一个键的同时按下了一个键,它将无法正常工作,但是当他们抬起那个键时,它将停止移动

EDIT 编辑

When the user presses down a key it sends the xd,yD values to the render method and because render keeps being called, it keeps on moving the player with the xD,yD values. 当用户按下键时,它将xd,yD值发送到render方法,并且由于render一直被调用,因此它将继续使用xD,yD值移动播放器。 The stop move method resets those values to 0 so it stops moving when the key is not being pressed. 停止移动方法将这些值重置为0,以便在不按下键时停止移动。

Try this following code and let me know, because I haven't test it. 尝试以下代码,让我知道,因为我尚未对其进行测试。

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
    }

Well normally I don't post a full solution but its fairly simple what you want to do. 好吧,通常我不会发布完整的解决方案,但是您要执行的操作相当简单。 The solution offers you a different way to implement your design. 该解决方案为您提供了一种不同的方法来实现您的设计。 Since your speed is constant I figure out don't need to set the delta but only change the direction. 由于您的速度是恒定的,因此我知道不需要设置增量,而只需更改方向。

You can keep track of the key presses and based on what is pressed you can determine the direction to move your character. 您可以跟踪按键,并根据所按下的内容确定角色移动的方向。 So for instance, when you press the up arrow, it sets the direction to up, but when you press left I track it but ignore the button. 因此,例如,当您按下向上箭头时,它会将方向设置为向上,但是当您按下向左键时,我会跟踪它,但忽略按钮。 If you release the up arrow, then your character will move left and at no point will it move in more than 1 direction. 如果释放向上箭头,则角色将向左移动,并且不会在超过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() {}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何确保在 Java 中只选择了一个 JRadioButton? - How Do I Make Sure Only One JRadioButton Is Selected In Java? 如何确保集合仅包含接口的每个实现之一 - How to make sure a collection only contains one of each of the implementations of an interface 如何确保仅启动一个线程 - How do I make sure only one thread gets started 如何确保一次只调用一个servlet(不是实例)? - how to I make sure that only one servlet(not instance) is call at a time? 如何确保java中的Collections只包含一个Type? - How to make sure that Collections in java hold only one Type? 如何确保数据库事务只发生一次? - How to make sure that DB transaction happens only one time? 如何确保基于JButton的文本按升序按下 - how to make sure that JButtons are being pressed in ascending order based on their text 如何确保 hibernate 5 在与共享主键的一对一关系中以正确的顺序持续存在 - How to make sure hibernate 5 persists in the correct order in a one-to-one relationship with shared primary key 当按下键盘上的相应键时如何使按钮按下? JavaFX - How make a button pressed when corresponding key on a keyboard is pressed? JavaFX 如何确保该方法只执行一次并且仅从一个线程执行? - How to make sure that method is executed only once and from one thread only?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM