-1

所以我正在制作一个用户在水平、垂直平铺地图上移动的游戏。但是我不希望用户能够按 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,以便在未按下键时停止移动。

4

2 回答 2

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
    }
于 2013-08-05T06:29:47.963 回答
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() {}
}
于 2013-08-09T18:08:14.253 回答