【发布时间】:2021-02-19 11:39:26
【问题描述】:
这是我的第一个问题,如果没有提前提出,我深表歉意。
所以,我正试图让水果(我在代码中也称它们为苹果)在与蛇体不同的位置产卵,就像标题所说的那样。问题是我不知道如何检查新水果的坐标是否不等于蛇的每个身体部位。
public void newApple() {
tempX = random.nextInt(width/unitSize)*unitSize;
tempY = random.nextInt(height/unitSize)*unitSize;
for (int i = 0; i < bodyParts; i++) {
if (tempX != x[i] && tempY != y[i]){
appleX = tempX;
appleY = tempY;
}
else {
newApple();
}
}
}
这就是我到目前为止所想的:我正在使用 2 个临时变量,它们将对应于帧中的随机位置,然后我想检查它们是否不等于蛇的每个位置。 for 循环中的 if 条件只是检查 x[0] 和 y[0],它们是我的蛇头的坐标。
这就是 paintComponent() 方法中绘制苹果的内容。
//drawing apple
if (appleX != null && appleY != null) {
g.setColor(Color.red);
g.fillOval(appleX, appleY, unitSize, unitSize);
}
如果您可能需要,下面是我的整个 2 类项目。
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createGame();
}
});
}
public static void createGame() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.add(new MyPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
public class MyPanel extends JPanel implements ActionListener {
final int width = 600;
final int height = 600;
final int unitSize = 25;
final int maxNumberOfUnits = (width*height)/(unitSize*unitSize);
int[] x = new int[maxNumberOfUnits];
int[] y = new int[maxNumberOfUnits];
int bodyParts = 2;
Integer appleX, appleY, tempX, tempY;
int score = 0;
char direction = 'R';
boolean running;
int delay = 175;
Timer timer = new Timer(delay, this);
Random random = new Random();
Font font1 = new Font("Ink Free", Font.BOLD, 40);
Font font2 = new Font("Ink Free", Font.BOLD, 75);
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
MyPanel() {
setBackground(new Color(16, 16, 16));
setFocusable(true);
timer.start();
running = true;
newApple();
x[0] = 10*unitSize;
y[0] = 10*unitSize;
x[1] = 9*unitSize;
y[1] = 10*unitSize;
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case 37:
if (direction !='R') {
direction = 'L';
}
break;
case 38:
if (direction !='D') {
direction = 'U';
}
break;
case 39:
if (direction !='L') {
direction = 'R';
}
break;
case 40:
if (direction !='U') {
direction = 'D';
}
break;
}
}
});
}
public void moveSnake() {
for (int i = bodyParts; i > 0; i--) {
x[i] = x[i-1];
y[i] = y[i-1];
}
switch (direction) {
case 'U':
y[0] -= unitSize;
break;
case 'D':
y[0] += unitSize;
break;
case 'L':
x[0] -= unitSize;
break;
case 'R':
x[0] += unitSize;
break;
}
}
public void newApple() {
tempX = random.nextInt(width/unitSize)*unitSize;
tempY = random.nextInt(height/unitSize)*unitSize;
for (int i = 0; i < bodyParts; i++) {
if (tempX != x[i] && tempY != y[i]){
appleX = tempX;
appleY = tempY;
}
else {
newApple();
}
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (running) {
/*
//drawing a matrix
for (int i = 1; i < height/unitSize; i++) {
g.drawLine(0, i*unitSize, width, i*unitSize);
}
for (int i = 1; i < width/unitSize; i++) {
g.drawLine(i*unitSize, 0, i*unitSize, height);
}
*/
//drawing apple
if (appleX != null && appleY != null) {
g.setColor(Color.red);
g.fillOval(appleX, appleY, unitSize, unitSize);
}
//drawing snake
g.setColor(Color.green);
for (int i = 0; i < bodyParts; i++) {
g.fillRect(x[i], y[i], unitSize, unitSize);
}
//drawing score
g.setColor(Color.red);
g.setFont(font1);
FontMetrics metrics1 = getFontMetrics(g.getFont());
g.drawString("Score: " + score, (width-metrics1.stringWidth("Score: " + score))/2, g.getFont().getSize());
}
else {
g.setColor(Color.red);
g.setFont(font1);
FontMetrics metrics1 = getFontMetrics(g.getFont());
g.drawString("Score: " + score, (width-metrics1.stringWidth("Score: " + score))/2, g.getFont().getSize());
g.setColor(Color.white);
g.setFont(font2);
FontMetrics metrics2 = getFontMetrics(g.getFont());
g.drawString("Game Over", (width-metrics2.stringWidth("Game Over"))/2, height/2);
}
}
public void checkApple() {
if (x[0]==appleX && y[0]==appleY) {
score++;
bodyParts++;
newApple();
}
}
public void checkCollisions() {
//body
for (int i = bodyParts; i > 0; i--) {
if (x[0] == x[i] && y[0] == y[i]) {
running = false;
}
}
if (x[0] < 0) {
running = false;
}
if (x[0] > width) {
running = false;
}
if (y[0] < 0) {
running = false;
}
if (y[0] > height) {
running = false;
}
if (!running) {
timer.stop();
}
}
@Override
public void actionPerformed(ActionEvent e) {
if (running) {
checkApple();
moveSnake();
checkCollisions();
}
repaint();
}
}
【问题讨论】:
-
spawn 是什么意思?你的意思是要在屏幕上画一个新的苹果?
-
是的,我的意思是在屏幕上画一个苹果,但正如问题所述,我不希望它位于蛇身所在的位置
-
基本上我希望 newApple() 方法中的 if close 检查循环的所有 i (它们是蛇的身体部分),然后将临时变量设置为实际坐标苹果。该代码虽然只是检查第一个,但我想不出另一种方法,所以一切可能从一开始就错了。