import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;
import java.util.LinkedList;
import java.util.Random;
import javax.swing.JFrame;
public class Snake extends JFrame implements KeyListener {
private static final long serialVersionUID = 1L;
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
}
if (snake.getFirst().y <= 0){
snake.getFirst().y = windowWidth/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();
}
}
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);
} 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);
}
@Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(key == 37) {
dx = -1;
dy = 0;
} else if(key == 38) {
dx = 0;
dy = -1;
} else if(key == 39) {
dx = 1;
dy = 0;
} else if(key == 40) {
dx = 0;
dy = 1;
}
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyTyped(KeyEvent e) {
}
}
我的问题在于这段代码
// 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
}
if (snake.getFirst().y <= 0){
snake.getFirst().y = windowWidth/10;//go top, wrap bottom
}
else if (snake.getFirst().y >= windowHeight/10){
snake.getFirst().y = 0;//go bottom, wrap top
}
如果蛇到达一面墙的边界,那么它就成了另一面墙的价值。除了顶部之外,这适用于所有墙壁。
我该如何解决这个问题?
答案 0 :(得分:2)
由于这看起来像家庭作业,我不会直接回答。尝试一次单步执行代码1行。可以说snake.getFirst().x
是0
。当你到达if
语句时,它将进入第一个区块。
snake.getFirst().x = 600;
现在snake.getFirst().x
是600
。下次到达if
语句时,它将落入第二个语句
else if (snake.getFirst().x >= windowWidth/10)
因为windowWidth/10
是80
而snake.getFirst().x
变为800
。希望这可以帮助您查看逻辑错误。
答案 1 :(得分:0)
你的逻辑错了,这就是你必须要做的事情
if(snake.getFirst().x <= 0){
snake.getFirst().x = windowWidth/10; //Warp to right
}
else if (snake.getFirst().x >= windowWidth/10){
snake.getFirst().x = 0; //Warp to left
}
if (snake.getFirst().y <= 0){
snake.getFirst().y = windowHeight/10; //Warp to bottom
}
else if (snake.getFirst().y >= windowHeight/10)
snake.getFirst().y = 0; //Warp to top