Java 经典小游戏 ——贪吃蛇,代码简洁易懂,自带图形界面,新手也能直接运行,还能快速上手修改规则~

核心功能

  • 方向键控制蛇移动(上下左右)
  • 吃食物增长身体、加分
  • 撞到边界或自身则游戏结束
  • 实时显示分数

完整代码(直接复制运行)

java

运行

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;

// 贪吃蛇游戏主类
public class SnakeGame extends JFrame {
    // 游戏面板(核心绘图和逻辑)
    private GamePanel gamePanel;

    public SnakeGame() {
        // 窗口设置
        setTitle("Java 贪吃蛇");
        setSize(800, 600); // 窗口大小
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 关闭窗口退出程序
        setLocationRelativeTo(null); // 窗口居中
        setResizable(false); // 禁止缩放窗口

        // 初始化游戏面板
        gamePanel = new GamePanel();
        add(gamePanel); // 把面板加入窗口

        // 监听键盘事件(控制蛇移动)
        addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                gamePanel.changeDirection(e.getKeyCode());
            }
        });
    }

    // 游戏面板(负责绘图、碰撞检测、逻辑更新)
    class GamePanel extends JPanel implements Runnable {
        // 游戏参数(可自定义修改)
        private final int CELL_SIZE = 20; // 每个格子大小(像素)
        private final int MAX_X = 800 / CELL_SIZE; // X轴最大格子数
        private final int MAX_Y = 600 / CELL_SIZE; // Y轴最大格子数
        private final int SPEED = 100; // 移动速度(毫秒/步,数值越小越快)

        // 蛇的属性:数组存储蛇身坐标(x[y] = 对应y的x坐标)
        private int[] snakeX = new int[MAX_X * MAX_Y];
        private int[] snakeY = new int[MAX_X * MAX_Y];
        private int snakeLength; // 蛇身长度
        private String direction; // 移动方向(UP/DOWN/LEFT/RIGHT)

        // 食物属性
        private int foodX;
        private int foodY;
        private Random random; // 随机生成食物位置

        // 游戏状态
        private int score;
        private boolean isGameOver;

        public GamePanel() {
            random = new Random();
            initGame(); // 初始化游戏
            new Thread(this).start(); // 启动游戏线程(控制刷新)
        }

        // 初始化游戏(重置蛇、食物、分数)
        private void initGame() {
            // 蛇初始位置(中间)
            snakeLength = 3;
            snakeX[0] = MAX_X / 2; // 蛇头X
            snakeY[0] = MAX_Y / 2; // 蛇头Y
            snakeX[1] = snakeX[0] - 1; // 蛇身1
            snakeY[1] = snakeY[0];
            snakeX[2] = snakeX[0] - 2; // 蛇身2
            snakeY[2] = snakeY[0];

            direction = "RIGHT"; // 初始方向向右
            score = 0;
            isGameOver = false;
            generateFood(); // 生成初始食物
        }

        // 随机生成食物(不落在蛇身上)
        private void generateFood() {
            while (true) {
                // 随机生成食物坐标(0到最大格子数-1)
                foodX = random.nextInt(MAX_X);
                foodY = random.nextInt(MAX_Y);

                // 检查食物是否落在蛇身上,没落在蛇身上则退出循环
                boolean isOnSnake = false;
                for (int i = 0; i < snakeLength; i++) {
                    if (snakeX[i] == foodX && snakeY[i] == foodY) {
                        isOnSnake = true;
                        break;
                    }
                }
                if (!isOnSnake) break;
            }
        }

        // 改变蛇的移动方向(防止180度转弯)
        public void changeDirection(int keyCode) {
            switch (keyCode) {
                case KeyEvent.VK_UP:
                    if (!direction.equals("DOWN")) direction = "UP";
                    break;
                case KeyEvent.VK_DOWN:
                    if (!direction.equals("UP")) direction = "DOWN";
                    break;
                case KeyEvent.VK_LEFT:
                    if (!direction.equals("RIGHT")) direction = "LEFT";
                    break;
                case KeyEvent.VK_RIGHT:
                    if (!direction.equals("LEFT")) direction = "RIGHT";
                    break;
                case KeyEvent.VK_ENTER: // 游戏结束后按回车重新开始
                    if (isGameOver) initGame();
                    break;
            }
        }

        // 移动蛇(核心逻辑)
        private void moveSnake() {
            // 蛇身跟随蛇头移动(从尾巴到头部依次复制前一个坐标)
            for (int i = snakeLength - 1; i > 0; i--) {
                snakeX[i] = snakeX[i - 1];
                snakeY[i] = snakeY[i - 1];
            }

            // 蛇头按方向移动
            switch (direction) {
                case "UP":
                    snakeY[0]--;
                    break;
                case "DOWN":
                    snakeY[0]++;
                    break;
                case "LEFT":
                    snakeX[0]--;
                    break;
                case "RIGHT":
                    snakeX[0]++;
                    break;
            }
        }

        // 碰撞检测(边界+自身)
        private void checkCollision() {
            // 1. 撞边界
            if (snakeX[0] < 0 || snakeX[0] >= MAX_X || snakeY[0] < 0 || snakeY[0] >= MAX_Y) {
                isGameOver = true;
            }

            // 2. 撞自身
            for (int i = 1; i < snakeLength; i++) {
                if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
                    isGameOver = true;
                }
            }

            // 3. 吃食物(蛇头碰到食物)
            if (snakeX[0] == foodX && snakeY[0] == foodY) {
                snakeLength++; // 蛇身增长
                score += 10; // 加分
                generateFood(); // 重新生成食物
            }
        }

        // 绘图方法(所有图形都在这里画)
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            this.setBackground(Color.BLACK); // 面板背景色(黑色)

            // 1. 画蛇
            g.setColor(Color.GREEN); // 蛇的颜色(绿色)
            for (int i = 0; i < snakeLength; i++) {
                // 画矩形(x*格子大小,y*格子大小,格子大小,格子大小)
                g.fillRect(snakeX[i] * CELL_SIZE, snakeY[i] * CELL_SIZE, CELL_SIZE, CELL_SIZE);
            }

            // 2. 画食物
            g.setColor(Color.RED); // 食物颜色(红色)
            g.fillRect(foodX * CELL_SIZE, foodY * CELL_SIZE, CELL_SIZE, CELL_SIZE);

            // 3. 画分数
            g.setColor(Color.WHITE); // 分数颜色(白色)
            g.setFont(new Font("宋体", Font.BOLD, 20));
            g.drawString("分数:" + score, 20, 30); // 分数显示位置(左上角)

            // 4. 游戏结束提示
            if (isGameOver) {
                g.setColor(Color.RED);
                g.setFont(new Font("宋体", Font.BOLD, 40));
                // 居中显示提示文字
                g.drawString("游戏结束!分数:" + score, MAX_X * CELL_SIZE / 4, MAX_Y * CELL_SIZE / 2);
                g.setFont(new Font("宋体", Font.PLAIN, 20));
                g.drawString("按回车键重新开始", MAX_X * CELL_SIZE / 3, MAX_Y * CELL_SIZE / 2 + 50);
            }
        }

        // 游戏线程(循环更新游戏状态)
        @Override
        public void run() {
            while (true) {
                if (!isGameOver) {
                    moveSnake(); // 移动蛇
                    checkCollision(); // 检测碰撞
                }
                repaint(); // 刷新面板(重新绘图)
                try {
                    Thread.sleep(SPEED); // 控制游戏速度
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    // 主方法(程序入口)
    public static void main(String[] args) {
        // 启动游戏(Swing需在主线程创建窗口)
        SwingUtilities.invokeLater(() -> new SnakeGame().setVisible(true));
    }
}

怎么运行?

  1. 打开 Java 开发工具(如 IDEA、Eclipse),新建一个 Java 项目
  2. 新建一个类,命名为 SnakeGame
  3. 把上面的代码复制粘贴到类中
  4. 点击运行,就能打开游戏窗口啦!

操作说明

  • 方向键 ↑↓←→ 控制蛇的移动方向
  • 吃到红色食物,蛇会变长,分数 + 10
  • 撞到窗口边界或自己的身体,游戏结束
  • 游戏结束后按回车键重新开始

可以自己修改的地方(新手友好)

  1. 游戏速度:修改 SPEED 变量(默认 100 毫秒,改成 50 更难,200 更简单)
  2. 格子大小:修改 CELL_SIZE 变量(默认 20 像素,改大后蛇和食物变大)
  3. 颜色:修改 snakefood背景 的颜色(比如把蛇改成蓝色 Color.BLUE
  4. 分数:修改吃食物加的分数(默认 + 10,改成 + 20)

这个游戏用到了 Java Swing 图形界面、多线程、事件监听等基础知识点,代码结构清晰,适合新手学习和拓展~ 要是想加新功能(比如难度升级、障碍物、自定义皮肤)

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐