Актуальный вопрос внизу поста!
Сначала я хочу объяснить свою проблему.
Я пишу простую игру «Змейка», и я заставил змею двигаться автоматически. Он автоматически перемещается вправо от окна при выполнении кода, как и предполагалось. Однако я не могу управлять своей змеей так, как хочу, она совершенно не меняет своего направления.
Чтобы избежать путаницы, player
является экземпляром класса Snake
.
Чтобы объяснить движение змеи:
Объект Snake
имеет свойство coordinates
, которое представляет собой ArrayList, содержащий объекты SnakePart
. Каждый объект SnakePart
имеет свойство x
и y
. Используя этот ArrayList, змея движется, рисуя маленькие прямоугольники на холсте, используя свойства x
и y
на оси Y и X холста.
Объект Snake
также имеет свойство dx
и dy
, которое добавляется (или вычитается - в зависимости от направления змеи) к свойству x
и y
SnakePart
объект для перемещения змеи в направлении.
Чтобы обновить ArrayList в Snake.java
:
public void move() {
SnakePart head = new SnakePart(this.coordinates.get(0).x + this.dx, this.coordinates.get(0).y + this.dy);
this.coordinates.add(0, head);
this.coordinates.remove(this.coordinates.size() - 1);
}
Чтобы нарисовать змею на холсте в Board.java
(частично, остальная часть метода пока не нужна):
@Override
public void paintComponent(Graphics g) {
this.player.coordinates.forEach(snakePart -> {
g.setColor(Color.BLUE);
g.fillRect(snakePart.x, snakePart.y, 10, 10);
});
}
Чтобы управлять змеей, я хочу использовать клавиши со стрелками. В зависимости от того, какая клавиша со стрелкой нажата, координаты / свойства змеи x
и y
изменяются (Board.java
):
@Override
public void keyPressed(KeyEvent event) {
int keyCode = event.getKeyCode();
if (keyCode == 37) {
this.player.dx = -10;
this.player.dy = 0;
} else if (keyCode == 38) {
this.player.dx = 0;
this.player.dy = -10;
} else if (keyCode == 39) {
this.player.dx = 10;
this.player.dy = 0;
} else if (keyCode == 40) {
this.player.dx = 0;
this.player.dy = 10;
}
}
Весь код:
Snake.java
package com.codef0x.snake;
import java.util.ArrayList;
public class Snake {
ArrayList < SnakePart > coordinates;
int dx = 10;
int dy = 0;
public Snake(ArrayList < SnakePart > coords) {
this.coordinates = coords;
}
public void move() {
SnakePart head = new SnakePart(this.coordinates.get(0).x + this.dx, this.coordinates.get(0).y + this.dy);
this.coordinates.add(0, head);
this.coordinates.remove(this.coordinates.size() - 1);
}
public void grow() {
SnakePart newPart = new SnakePart(0, 0);
newPart.x = this.coordinates.get(this.coordinates.size() - 1).x - 10;
newPart.y = this.coordinates.get(this.coordinates.size() - 1).y;
this.coordinates.add(this.coordinates.size() - 1, newPart);
}
}
Board.java
(показаны только соответствующие части, в противном случае было бы слишком много кода)
package com.codef0x.snake;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
public class Board extends JPanel implements KeyListener {
Snake player;
ArrayList<SnakePart> snakeCoordinates;
public Board() {
this.snakeCoordinates = new ArrayList<>();
snakeCoordinates.add(new SnakePart(150, 150));
snakeCoordinates.add(new SnakePart(140, 150));
snakeCoordinates.add(new SnakePart(130, 150));
snakeCoordinates.add(new SnakePart(120, 150));
this.player = new Snake(snakeCoordinates);
this.food = new Food();
}
@Override
public void paintComponent(Graphics g) {
clear(g);
this.player.coordinates.forEach(snakePart - > {
g.setColor(Color.BLUE);
g.fillRect(snakePart.x, snakePart.y, 10, 10);
});
}
public void clear(Graphics g) {
g.clearRect(0, 0, getHeight(), getWidth());
}
@Override
public void update(Graphics g) {
paintComponent(g);
}
@Override
public void keyPressed(KeyEvent event) {
int keyCode = event.getKeyCode();
if (keyCode == 37) {
this.player.dx = -10;
this.player.dy = 0;
} else if (keyCode == 38) {
this.player.dx = 0;
this.player.dy = -10;
} else if (keyCode == 39) {
this.player.dx = 10;
this.player.dy = 0;
} else if (keyCode == 40) {
this.player.dx = 0;
this.player.dy = 10;
}
}
@Override
public void keyTyped(KeyEvent event) {
return;
}
@Override
public void keyReleased(KeyEvent event) {
return;
}
public void run(Board board) {
Timer game = new Timer();
game.schedule(new TimerTask() {
boolean initiallySpawned = false;
@Override
public void run() {
Graphics g = board.getGraphics();
if (hitSomething()) { // removed method hitSomething, not relevant
game.cancel();
return;
}
player.move();
update(g);
}
}, 0, 500);
}
}
SnakePart.java
package com.codef0x.snake;
public class SnakePart {
int x;
int y;
public SnakePart(int x, int y) {
this.x = x;
this.y = y;
}
}
Что я делаю не так и что мне нужно изменить, чтобы правильно управлять змеей?
Если вы все еще хотите / хотите увидеть все файлы целиком, вы можете посмотреть их здесь:
Snake.java
Board.java
SnakePart.java
Food.java <- Не связано, но может предотвратить путаницу с <code>Food объектом