21xrx.com
2024-11-05 14:56:18 Tuesday
登录
文章检索 我的文章 写文章
Java实现简单贪吃蛇游戏代码详解
2023-06-11 16:32:02 深夜i     --     --
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();

  }

}

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

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复