如何处理 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
中的 snakeBody
与 GameState
中的 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 );
我在做贪吃蛇游戏,不知道怎么处理贪吃蛇导航。这是我尝试过的方法:我有 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
中的 snakeBody
与 GameState
中的 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 );