21xrx.com
2025-03-26 17:41:29 Wednesday
文章检索 我的文章 写文章
Java实现简单贪吃蛇游戏代码详解
2023-06-11 16:32:02 深夜i     13     0
Java 贪吃蛇 代码详解

贪吃蛇游戏是小众游戏爱好者们非常喜爱的一款游戏,其简单而有趣的玩法深受玩家喜欢。下面就给大家介绍一下Java实现简单贪吃蛇游戏的代码详解。

首先,我们需要一个蛇的实体类,代码如下:

public class Snake {
  private LinkedList
  body;
 
  private int direction;
  private class Node {
    int x;
    int y;
    public Node(int x, int y)
      this.x = x;
      this.y = y;
    
  }
  public Snake() {
    body = new LinkedList<>();
    body.add(new Node(10, 10));
    direction = KeyEvent.VK_RIGHT;
  }
  public void move() {
    Node tail = body.removeLast();
    int x = body.getFirst().x;
    int y = body.getFirst().y;
    switch (direction) {
      case KeyEvent.VK_UP:
        body.addFirst(new Node(x, y - 10));
        break;
      case KeyEvent.VK_DOWN:
        body.addFirst(new Node(x, y + 10));
        break;
      case KeyEvent.VK_LEFT:
        body.addFirst(new Node(x - 10, y));
        break;
      case KeyEvent.VK_RIGHT:
        body.addFirst(new Node(x + 10, y));
        break;
    }
  }
  public void change_direction(int direction) {
    // 禁止蛇掉头
    if (Math.abs(direction - this.direction) != 2 && direction != this.direction)
      this.direction = direction;
    
  }
  public boolean is_dead() {
    int x = body.getFirst().x;
    int y = body.getFirst().y;
    // 碰到边界
    if (x < 0 || x > 490 || y < 20 || y > 490)
      return true;
    
    // 撞到自己
    for (int i = 1; i < body.size(); i++) {
      if (x == body.get(i).x && y == body.get(i).y)
        return true;
      
    }
    return false;
  }
  public void grow() {
    Node tail = body.getLast();
    int x = tail.x;
    int y = tail.y;
    switch (direction) {
      case KeyEvent.VK_UP:
        body.addLast(new Node(x, y + 10));
        break;
      case KeyEvent.VK_DOWN:
        body.addLast(new Node(x, y - 10));
        break;
      case KeyEvent.VK_LEFT:
        body.addLast(new Node(x + 10, y));
        break;
      case KeyEvent.VK_RIGHT:
        body.addLast(new Node(x - 10, y));
        break;
    }
  }
  public LinkedList
  get_body()
 
    return body;
  
}

上述代码实现了贪吃蛇的移动、改变方向、死亡、生长等方法,其核心逻辑为通过一个链表来记录贪吃蛇的身体节点,根据方向来移动蛇的身体。

接着,我们需要一个食物类,在贪吃蛇吃到食物时,会调用其相关方法。

public class Food {
  private int x;
  private int y;
  public Food(int x, int y)
    this.x = x;
    this.y = y;
  
  public int get_x()
    return x;
  
  public int get_y()
    return y;
  
  public void generate_location() {
    x = (int) (Math.random() * 49) * 10;
    y = (int) (Math.random() * 47 + 2) * 10;
  }
}

该类仅仅记录食物的位置,和重新生成新食物的方法。

最后,我们需要一个游戏窗口类。

public class GameFrame extends JFrame {
  private static final int WINDOW_WIDTH = 500;
  private static final int WINDOW_HEIGHT = 520;
  private JPanel game_panel;
  private Snake snake;
  private Food food;
  private class PaintThread implements Runnable {
    @Override
    public void run() {
      while (true) {
        game_panel.repaint();
        snake.move();
        if (snake.is_dead()) {
          JOptionPane.showMessageDialog(null, "Game over");
          dispose();
          System.exit(0);
        }
        Node head = snake.get_body().getFirst();
        if (head.x == food.get_x() && head.y == food.get_y()) {
          snake.grow();
          food.generate_location();
        }
        try {
          Thread.sleep(150);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }
  public GameFrame() {
    setTitle("Java贪吃蛇");
    setBounds(400, 200, WINDOW_WIDTH, WINDOW_HEIGHT);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    game_panel = new JPanel();
    game_panel.setPreferredSize(new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT));
    add(game_panel);
    addKeyListener(new KeyAdapter() {
      @Override
      public void keyPressed(KeyEvent e) {
        super.keyPressed(e);
        int code = e.getKeyCode();
        if (code == KeyEvent.VK_UP || code == KeyEvent.VK_DOWN || code == KeyEvent.VK_LEFT || code == KeyEvent.VK_RIGHT) {
          snake.change_direction(code);
        }
      }
    });
    init_game();
    new Thread(new PaintThread()).start();
    setVisible(true);
  }
  private void init_game() {
    snake = new Snake();
    food = new Food(250, 250);
    food.generate_location();
  }
  @Override
  public void paint(Graphics g) {
    super.paint(g);
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
    LinkedList
  body = snake.get_body();
 
    g.setColor(Color.WHITE);
    for (int i = 0; i < body.size(); i++) {
      Snake.Node node = body.get(i);
      g.fillRect(node.x, node.y, 10, 10);
    }
    g.setColor(Color.RED);
    g.fillRect(food.get_x(), food.get_y(), 10, 10);
  }
}

代码中,我们通过一个JPanel来实现游戏的渲染,而PaintThread线程则处理游戏的逻辑,包括控制游戏速度、判断蛇是否死亡、蛇是否吃到食物等。

使用方法:

public class Main {
  public static void main(String[] args) {
    new GameFrame();
  }
}

代码实现了基础的贪吃蛇游戏,玩家可使用方向键控制蛇的移动方向,当蛇的头部和食物重合时,蛇会生长,同一时刻只能存在一个食物。当蛇撞到墙壁或自己身体时,游戏结束。

  
  

评论区