java - java贪吃蛇游戏,让蛇穿墙

标签 java

我正在制作一个贪吃蛇游戏。我想让蛇从一堵墙穿过另一堵墙。

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
    }

如果蛇到达一堵墙的边界,那么它就变成另一堵墙的值。这适用于除顶部墙壁之外的所有墙壁。

我该如何解决这个问题?

最佳答案

由于这看起来像家庭作业,我不会给出直接答案。尝试一次单步执行 1 行代码。假设snake.getFirst().x0。当您到达 if 语句时,它将进入第一个 block 。

snake.getFirst().x = 600;

现在snake.getFirst().x600。下次到达您的 if 语句时,它将落入第二个语句

else if (snake.getFirst().x >= windowWidth/10)

因为windowWidth/1080,而snake.getFirst().x变成了800。希望这能帮助您发现逻辑中可能存在的错误。

关于java - java贪吃蛇游戏,让蛇穿墙,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23524001/

相关文章:

java - Cordova - Android 上的 XHR 请求在模拟器中工作,但在手机上不工作

java - 如何使用 API 在 Google 电子表格范围内查找值(行号和列号)?

java - 将二进制数据转换为字符串

java - Intellij IDEA跨文件自动导入

java - 抽象异常类中的串行版本 uid

java - JPA + hibernate 外键为空

java - 为 Spring MVC 和 Maven WebApplication 创建文件/图像文件夹目录

java - 嵌套 JAVA API 的简单异常处理

java - Firebase 删除子 onButtonClick

java - 在 Java 中将 HashMap.toString() 转换回 HashMap