如何处理 libgdx 上的触摸?

How to handle touch on libgdx?

我在做贪吃蛇游戏,不知道怎么处理贪吃蛇导航。这是我尝试过的方法:我有 Button class 来处理点击。我尝试将 snake.first().x 连接到触摸监听器,但出现错误:

public class Buttons {

private int cDirection = 0;
private int nDirection = 0;
public Queue<SnakeBody> snakeBody = new Queue<>();

private Vector3 touch = new Vector3();

public int getDirection() {
    cDirection = nDirection;
    return nDirection;
}

public void update(OrthographicCamera camera) {
    if (Gdx.input.isTouched()) {
        touch.x = Gdx.input.getX();
        touch.y = Gdx.input.getY();
        camera.unproject(touch);
        snakeBody.first().x = (int) touch.x;
    }
    if ((Gdx.input.isKeyPressed(Input.Keys.UP) && cDirection != 2)) nDirection = 0;
    else if ((Gdx.input.isKeyPressed(Input.Keys.RIGHT))
            && cDirection != 3) nDirection = 1;
    else if ((Gdx.input.isKeyPressed(Input.Keys.DOWN))
            && cDirection != 0) nDirection = 2;
    else if ((Gdx.input.isKeyPressed(Input.Keys.LEFT))
            && cDirection != 1) nDirection = 3;
}

}

添加更多代码以查找问题所在。

游戏状态

public class GameState {
    int width = Gdx.graphics.getWidth();
    int height = Gdx.graphics.getHeight();
    private int playgroundSize = 32; //How many squares in the board
    private int yOffset = 0; //How high the board is off the bottom
    private ShapeRenderer shapeRenderer = new ShapeRenderer();
    private Buttons buttons = new Buttons();
    private Queue<SnakeBody> snakeBody = new Queue<>();
    private float timer = 0;
    private Candy candy = new Candy(playgroundSize);
    private int snakeSize = 10;
    private float colourCounter = 0;
    private Stage stage;
    private int score = 0;

    public GameState() {
        snakeBody.addFirst(new SnakeBody(15, 15, playgroundSize)); //head
    }

    public void update(float delta, OrthographicCamera camera) { //update game logic
        timer += delta;
        colourCounter += delta;
        buttons.update(camera);
        if (timer > 0.13f) {
            timer = 0;
            advance();
        }
    }

    private void advance() {
        int headX = snakeBody.first().getX();
        int headY = snakeBody.first().getY();
        switch (buttons.getDirection()) {
            //up
            case 1: //right
                snakeBody.addFirst(new SnakeBody(headX + 1, headY, playgroundSize * 2));
                break;
            case 2: //down
                snakeBody.addFirst(new SnakeBody(headX, headY - 1, playgroundSize * 2));
                break;
            case 3: //left
                snakeBody.addFirst(new SnakeBody(headX - 1, headY, playgroundSize * 2));
                break;
            default://should never happen
                snakeBody.addFirst(new SnakeBody(headX, headY + 1, playgroundSize * 2));
                break;
        }
        if (snakeBody.first().getX() == candy.getX() && snakeBody.first().getY() == candy.getY()) {
            snakeSize++;
            score++;
            candy.randomed(playgroundSize);
        }


        for (int i = 1; i < snakeBody.size; i++) {
            if (snakeBody.get(i).getX() == snakeBody.first().getX()
                    && snakeBody.get(i).getY() == snakeBody.first().getY()) {
                snakeSize = 3;
            }
        }

        while (snakeBody.size - 1 >= snakeSize) {
            snakeBody.removeLast();
        }


    }

    public void setScore() {
        FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("pixelboy.ttf"));
        FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
        parameter.size = 90;
        parameter.borderWidth = 1;
        parameter.color = Color.PURPLE;
        parameter.shadowOffsetX = 3;
        parameter.shadowOffsetY = 3;
        parameter.shadowColor = new Color(0, 0, 0, 1);
        BitmapFont font = generator.generateFont(parameter); // font size 30 pixels
        generator.dispose();

        Label.LabelStyle scoreStyle = new Label.LabelStyle();
        scoreStyle.font = font;

        Label score = new Label("Score: " + this.score, scoreStyle);
        score.setSize(width, height);
        score.setPosition(20, height - 20);
        score.setAlignment(Align.center);
        stage.addActor(score);

    }

    public void draw(float width, int height, OrthographicCamera camera) { //draw snake and board
        shapeRenderer.setProjectionMatrix(camera.combined);
        shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);

        shapeRenderer.setColor(Color.PURPLE);
        shapeRenderer.rect(0, 0, width, height);

        //shapeRenderer.setColor(Color.FOREST);
        shapeRenderer.setColor(MathUtils.sin(colourCounter), -MathUtils.sin(colourCounter), 1, 1);


        float scaleSnake = width / playgroundSize;
        shapeRenderer.rect(candy.getX() * scaleSnake, candy.getY() * scaleSnake, scaleSnake, scaleSnake);

        for (SnakeBody snBody : snakeBody) {
            shapeRenderer.rect(snBody.getX() * scaleSnake, snBody.getY() * scaleSnake, scaleSnake, scaleSnake);
        }

       
        shapeRenderer.end();
    }
}

Class 用于创建蛇

public class SnakeBody {

    int x;
    int y;

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public SnakeBody(int x, int y, int playgroundSize) {
        this.x = x % playgroundSize;
        if (this.x < 0) this.x += playgroundSize;

        this.y = y % playgroundSize;
        if (this.y < 0) this.y += playgroundSize;
    }
  
}

蛇正在画画,但队列还是空的

异常意味着调用snakeBody.first()时队列中没有任何元素。

这是因为 Buttons 中的 snakeBodyGameState 中的 snakeBody 是另一个 Queue

Buttons-class:

public Queue<SnakeBody> snakeBody;
public Buttons(Queue<SnakeBody> body){
    snakeBody=body;
}

GameState中:

private Queue<SnakeBody> snakeBody = new Queue<>();
private Buttons buttons = new Buttons(snakeBody );