• Java GUI实现贪吃蛇游戏


    贪吃蛇是一款经典的游戏,玩法相对简单但富有挑战性。以下是贪吃蛇游戏的基本玩法说明:

    1. 目标:控制一条蛇,在游戏区域内吃到尽可能多的食物,使蛇身变长,同时避免撞到自己的身体或游戏区域的边界。

    2. 控制:通常使用方向键(上、下、左、右)或滑动屏幕来控制蛇的移动方向,使其朝着食物的方向前进。

    3. 食物和增长:在游戏区域内随机生成食物。当蛇头接触到食物时,蛇身增长一个单位,并且得分会增加。

    4. 增加难度:随着蛇身不断增长,游戏会变得更加困难。蛇的身体会占据更多的空间,同时移动速度可能加快。

    5. 失败条件:游戏结束的条件包括蛇头撞到自己的身体或者撞到游戏区域的边界。

    6. 计分:游戏通常会记录你的得分,即吃到的食物数量或者游戏时长。

    贪吃蛇是一款简单而又令人上瘾的游戏,你可以在各种平台上找到不同版本的贪吃蛇游戏。希望你能享受这个经典游戏带来的乐趣!

    以下是Java实现的基本贪吃蛇游戏代码,你可以根据自己的需求进行修改和完善:

    1. import java.awt.*;
    2. import java.awt.event.*;
    3. import javax.swing.*;
    4. import java.util.*;
    5. public class SnakeGame extends JFrame implements KeyListener {
    6. private static final long serialVersionUID = 1L;
    7. private JPanel panel;
    8. private static JLabel scoreLabel, gameOverLabel;
    9. private static int score = 0;
    10. private static int highScore = 0;
    11. private static boolean gameOver = false;
    12. private static final int ROWS = 30, COLS = 30;
    13. private static final int CELL_SIZE = 20;
    14. private Snake snake;
    15. private Food food;
    16. private Timer timer;
    17. public static void main(String[] args) {
    18. new SnakeGame().setVisible(true);
    19. }
    20. public SnakeGame() {
    21. setTitle("贪吃蛇游戏");
    22. setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    23. setResizable(false);
    24. panel = new JPanel();
    25. panel.setPreferredSize(new Dimension(ROWS * CELL_SIZE, COLS * CELL_SIZE));
    26. getContentPane().add(panel);
    27. addKeyListener(this);
    28. scoreLabel = new JLabel("得分: 0 最高分: " + highScore);
    29. panel.add(scoreLabel);
    30. gameOverLabel = new JLabel("游戏结束");
    31. gameOverLabel.setForeground(Color.RED);
    32. gameOverLabel.setVisible(false);
    33. panel.add(gameOverLabel);
    34. snake = new Snake();
    35. food = new Food(snake);
    36. food.generate();
    37. timer = new Timer(100, new ActionListener() {
    38. @Override
    39. public void actionPerformed(ActionEvent arg0) {
    40. snake.update();
    41. checkGameOver();
    42. panel.repaint();
    43. }
    44. });
    45. timer.start();
    46. pack();
    47. setLocationRelativeTo(null);
    48. }
    49. private void checkGameOver() {
    50. if (snake.checkCollision()) {
    51. gameOver = true;
    52. gameOverLabel.setVisible(true);
    53. timer.stop();
    54. if (score > highScore) {
    55. highScore = score;
    56. scoreLabel.setText("得分: " + score + " 最高分: " + highScore);
    57. }
    58. }
    59. }
    60. @Override
    61. public void keyPressed(KeyEvent e) {
    62. if (!gameOver) {
    63. int keyCode = e.getKeyCode();
    64. if (keyCode == KeyEvent.VK_UP) {
    65. snake.changeDirection(Snake.UP);
    66. } else if (keyCode == KeyEvent.VK_DOWN) {
    67. snake.changeDirection(Snake.DOWN);
    68. } else if (keyCode == KeyEvent.VK_LEFT) {
    69. snake.changeDirection(Snake.LEFT);
    70. } else if (keyCode == KeyEvent.VK_RIGHT) {
    71. snake.changeDirection(Snake.RIGHT);
    72. }
    73. }
    74. }
    75. @Override
    76. public void keyReleased(KeyEvent e) {
    77. }
    78. @Override
    79. public void keyTyped(KeyEvent e) {
    80. }
    81. public class Snake {
    82. private LinkedList<Point> segments;
    83. private int direction;
    84. public static final int UP = 1, DOWN = -1, LEFT = 2, RIGHT = -2;
    85. public Snake() {
    86. segments = new LinkedList<Point>();
    87. segments.add(new Point(3, 0));
    88. segments.add(new Point(2, 0));
    89. segments.add(new Point(1, 0));
    90. segments.add(new Point(0, 0));
    91. direction = RIGHT;
    92. }
    93. public void changeDirection(int newDirection) {
    94. if (direction + newDirection != 0) {
    95. direction = newDirection;
    96. }
    97. }
    98. public void update() {
    99. Point head = segments.getFirst();
    100. Point newHead = (Point) head.clone();
    101. if (direction == UP) {
    102. newHead.translate(0, -1);
    103. } else if (direction == DOWN) {
    104. newHead.translate(0, 1);
    105. } else if (direction == LEFT) {
    106. newHead.translate(-1, 0);
    107. } else if (direction == RIGHT) {
    108. newHead.translate(1, 0);
    109. }
    110. segments.addFirst(newHead);
    111. if (!food.checkCollision(newHead.x, newHead.y)) {
    112. segments.removeLast();
    113. } else {
    114. score++;
    115. scoreLabel.setText("得分: " + score + " 最高分: " + highScore);
    116. food.generate();
    117. }
    118. }
    119. public boolean checkCollision() {
    120. Point head = segments.getFirst();
    121. if (head.x < 0 || head.x >= COLS || head.y < 0 || head.y >= ROWS) {
    122. return true;
    123. }
    124. for (int i = 1; i < segments.size(); i++) {
    125. if (segments.get(i).equals(head)) {
    126. return true;
    127. }
    128. }
    129. return false;
    130. }
    131. public void draw(Graphics g) {
    132. for (Point p : segments) {
    133. g.setColor(Color.GREEN);
    134. g.fillRect(p.x * CELL_SIZE, p.y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
    135. }
    136. }
    137. }
    138. public class Food {
    139. private int x, y;
    140. private Snake snake;
    141. private Random rand;
    142. public Food(Snake snake) {
    143. this.snake = snake;
    144. rand = new Random();
    145. }
    146. public void generate() {
    147. do {
    148. x = rand.nextInt(COLS);
    149. y = rand.nextInt(ROWS);
    150. } while (snake.segments.contains(new Point(x, y)));
    151. }
    152. public boolean checkCollision(int x, int y) {
    153. if (this.x == x && this.y == y) {
    154. return true;
    155. }
    156. return false;
    157. }
    158. public void draw(Graphics g) {
    159. g.setColor(Color.RED);
    160. g.fillRect(x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE);
    161. }
    162. }
    163. @Override
    164. public void paint(Graphics g) {
    165. g.setColor(Color.LIGHT_GRAY);
    166. g.fillRect(0, 0, getWidth(), getHeight());
    167. snake.draw(g);
    168. food.draw(g);
    169. }
    170. }

    这个代码实现的贪吃蛇游戏界面为:

  • 相关阅读:
    中国家电市场深度调查研究报告
    一、数组经典题型
    cJSON函数用法
    Mybatis使用
    注解详解系列 - @EnableAspectJAutoProxy:启用AspectJ自动代理
    c++运算符
    为什么个人IP对任何行业都至关重要
    STM32之Bootloader、USB、IAP/DFU下载
    【 C++ 】map、multimap的介绍和使用
    【spark】第二章——SparkCore之运行架构及核心编程
  • 原文地址:https://blog.csdn.net/m0_37649480/article/details/134421357