【发布时间】:2014-05-07 21:12:19
【问题描述】:
我正在做一个蛇游戏。
我的问题是“游戏结束”图形出现在游戏开始时,但我希望它只在蛇撞到自己时显示。
这是我目前所拥有的:
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.util.*;
import javax.swing.JFrame;
public class Snake extends JFrame implements KeyListener {
private static final long serialVersionUID = 1L;
private boolean gameOver;
private int windowWidth = 800;
private int windowHeight = 600;
private LinkedList<Point> snake;
private int dx;
private int dy;
private Random generator = new Random();
private Point food;
private int points;
public static void main(String[] args) {
new Snake();
}
public Snake() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(windowWidth, windowHeight);
this.setResizable(false);
this.setLocation(100, 100);
this.setVisible(true);
this.createBufferStrategy(2);
this.addKeyListener(this);
initGame();
while(true) {
long start = System.currentTimeMillis();
gameLoop();
while(System.currentTimeMillis()-start < 40) {
//do nothing
}
}
}
private void initGame() {
// game variables initialized here
snake = new LinkedList<Point>();
snake.addFirst(new Point(20,20));
growSnake(5);
dx = 0;
dy = 0;
food = new Point(10,10);
points = 0;
}
private void gameLoop() {
// game logic
// move the snake
moveSnake(dx, dy);
// check if snake has eaten food
if(snake.getFirst().equals(food)) {
moveFood();
growSnake(3);
points++;
}
// go through walls
if (snake.getFirst().x <= 0){
snake.getFirst().x = windowWidth/10;//go left, wrap right
}
else if (snake.getFirst().x >= windowWidth/10){
snake.getFirst().x = 0;//go right, wrap left
}
else if (snake.getFirst().y <= 0){
snake.getFirst().y = windowHeight/10;//go top, wrap bottom
}
else if (snake.getFirst().y >= windowHeight/10){
snake.getFirst().y = 0;//go bottom, wrap top
}
// check if the snake has hit itself
for(int n = 1; n < snake.size(); n++) {
if(snake.getFirst().equals(snake.get(n))) {
initGame();
gameOver = true;
}
}
drawFrame();
}
private void drawFrame() {
// code for drawing
BufferStrategy bf = this.getBufferStrategy();
Graphics g = null;
try {
g = bf.getDrawGraphics();
// clear the back buffer (just draw a big black rectangle over it)
g.setColor(Color.BLACK);
g.fillRect(0, 0, windowWidth, windowHeight);
drawSnake(g);
drawFood(g);
drawPoints(g);
if (gameOver == true){
gameEnd(g);
}
} finally {
g.dispose();
}
// Shows the contents of the backbuffer on the screen.
bf.show();
//Tell the System to do the Drawing now, otherwise it can take a few extra ms until
//Drawing is done which looks very jerky
Toolkit.getDefaultToolkit().sync();
}
private void drawSnake (Graphics g) {
for(int n = 0; n < snake.size(); n++) {
g.setColor(Color.RED);
Point p = snake.get(n);
g.fillOval(p.x*10, p.y*10, 10, 10);
}
}
private void moveSnake(int dx, int dy) {
for(int n = snake.size()-1; n >= 1; n--) {
snake.get(n).setLocation(snake.get(n-1));
}
snake.getFirst().x += dx;
snake.getFirst().y += dy;
}
private void growSnake (int n) {
while(n > 0) {
snake.add(new Point(snake.getLast()));
n--;
}
}
private void moveFood() {
food.x = generator.nextInt((windowWidth/10)-4)+2;
food.y = generator.nextInt((windowHeight/10)-5)+3;
}
private void drawFood(Graphics g) {
g.setColor(Color.BLUE);
g.fillOval(food.x*10, food.y*10, 10, 10);
}
private void drawPoints(Graphics g) {
g.setColor(Color.GRAY);
g.drawString("points: " + points, 10, 40);
}
private static final Font FONT_LARGE = new Font("Times New Roman", Font.BOLD, 40);
private void gameEnd(Graphics g){
if (gameOver == true){
g.setColor(Color.RED);
g.setFont(FONT_LARGE);
g.drawString("Game Over",300, 320);
}
}
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == 37) {//left
dx = -1;
dy = 0;
} else if(key == 38) {//up
dx = 0;
dy = -1;
} else if(key == 39) {//right
dx = 1;
dy = 0;
} else if(key == 40) {//down
dx = 0;
dy = 1;
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
有什么想法吗?
【问题讨论】:
-
Any ideas?使用调试器?不要写容易出错的if (gameOver == true)而是if (gameOver),而不是像while(System.currentTimeMillis()-start < 40) {}那样主动等待使用Timer/Swing Timer。 -
你没有初始化 gameOver 设置为 false
-
@sherif:这不是问题,因为布尔值在声明时默认为 false。
-
只是猜测它使代码更具可读性的任何方式