帖子底部的实际问题!
首先,我想解释一下我的问题。
我正在编写一个基本的贪吃蛇游戏,我让蛇自动移动。当您执行代码时,它会自动移动到窗口右侧,就像预期的那样。然而,我无法按照我想要的方式引导我的蛇,它根本不会改变它的方向。
为了避免混淆,player
是 Snake
类的实例。
解释蛇的运动:
Snake
对象有一个 coordinates
属性,它是一个包含 SnakePart
对象的 ArrayList。每个 SnakePart
对象都有属性 x
和 y
。使用此 ArrayList,蛇通过使用 Canvas y 轴和 x 轴上的 x
和 y
属性在 Canvas 上绘制小矩形来移动。
Snake
对象还有一个 dx
和 dy
属性,可以添加(或减去 - 取决于蛇的方向) ) 到 SnakePart
对象的 x
和 y
属性,以沿某个方向移动蛇。
更新 Snake.java
中的 ArrayList:
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
中的 Canvas 上绘制蛇(部分地,目前不需要该方法的其余部分):
@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 <- 不相关,但可能会防止对 Food
对象产生混淆
最佳答案
问题出在主要部分。
您创建一个板
来托管您的游戏状态,并创建另一个板来监听键盘。
public static void main(String[] args) {
JFrame frame = new JFrame("Snake");
frame.setDefaultCloseOperation(3);
Board board = new Board();
frame.add(board);
frame.setSize(500, 500);
frame.addKeyListener(new Board());
frame.setVisible(true);
board.run(board);
}
应该是:
public static void main(String[] args) {
JFrame frame = new JFrame("Snake");
frame.setDefaultCloseOperation(3);
Board board = new Board();
frame.add(board);
frame.setSize(500, 500);
frame.addKeyListener(board);
frame.setVisible(true);
board.run(board);
}
另外,board.run(board)
没有什么意义,在run
方法的范围内,board可以交换到this
(并且所以省略)...
关于java - 贪吃蛇游戏——无法驾驭蛇,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53322069/