#java #android #libgdx #touch-event
#java #Android #libgdx #касание-событие
Вопрос:
Я создаю змеиную игру, я не понимаю, как обрабатывать змеиную навигацию. Вот что я пробовал: у меня есть класс Button, в котором я обрабатываю клики. Я попытался подключить 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) amp;amp; cDirection != 2)) nDirection = 0;
else if ((Gdx.input.isKeyPressed(Input.Keys.RIGHT))
amp;amp; cDirection != 3) nDirection = 1;
else if ((Gdx.input.isKeyPressed(Input.Keys.DOWN))
amp;amp; cDirection != 0) nDirection = 2;
else if ((Gdx.input.isKeyPressed(Input.Keys.LEFT))
amp;amp; cDirection != 1) nDirection = 3;
}
}
Добавьте больше кода, чтобы найти, в чем проблема.
GameState
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() amp;amp; 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()
amp;amp; 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();
}
}
Класс для создания snake
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;
}
}
Комментарии:
1. Вы уверены, что
snakeBody
это не пустое? Согласно исключению, это так. У вас есть несколько экземпляровButtons
?2. Я отладил его и head = 0, но как сделать его не пустым? Я вижу змеиную очередь на экране, почему она может быть пустой?
3. Нет, у меня есть только один экземпляр на кнопке.
4. Может быть, я неправильно понял всю концепцию событий касания? Я хочу коснуться экрана и моей змеи, чтобы изменить направление. Как этого добиться?
5. Вы добавляли элементы в очередь?
Ответ №1:
Исключение означает, что snakeBody.first()
вызывается без каких-либо элементов в очереди.
Это потому snakeBody
, что in Buttons
отличается Queue
от snakeBody
in GameState
.
В 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 );
Комментарии:
1. О, это сработало, это не навигация так, как я хотел, но она обрабатывает клики. Спасибо!