用java写个小游戏

下面用 Java 编写一个经典的 “贪吃蛇”小游戏,基于 Swing 图形界面,逻辑清晰、易于理解,适合入门学习。

贪吃蛇游戏代码(完整可运行)

import javax.swing.;
import java.awt.
;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

// 主游戏窗口
public class SnakeGame extends JFrame implements KeyListener, ActionListener {
// 游戏参数(可调整)
private final int GRID_SIZE = 20; // 格子大小(像素)
private final int GRID_COUNT = 20; // 网格行列数(20x20)
private final int SPEED = 150; // 游戏速度(毫秒/帧,值越小越快)

// 蛇的属性
private int[] snakeX = new int[GRID_COUNT * GRID_COUNT]; // 蛇身X坐标
private int[] snakeY = new int[GRID_COUNT * GRID_COUNT]; // 蛇身Y坐标
private int snakeLength = 3; // 初始蛇长
private String direction = "RIGHT"; // 初始方向(上UP/下DOWN/左LEFT/右RIGHT)

// 食物属性
private int foodX;
private int foodY;
private Random random = new Random();

// 游戏状态
private boolean isRunning = true;
private Timer timer;

// 构造方法:初始化窗口和游戏
public SnakeGame() {
    // 窗口设置
    setTitle("Java 贪吃蛇");
    setSize(GRID_SIZE * GRID_COUNT, GRID_SIZE * GRID_COUNT);
    setLocationRelativeTo(null); // 窗口居中
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setResizable(false); // 禁止缩放

    // 添加键盘监听(控制方向)
    addKeyListener(this);

    // 初始化蛇的初始位置(屏幕中间)
    snakeX[0] = GRID_COUNT / 2 * GRID_SIZE;
    snakeY[0] = GRID_COUNT / 2 * GRID_SIZE;
    for (int i = 1; i < snakeLength; i++) {
        snakeX[i] = snakeX[0] - i * GRID_SIZE;
        snakeY[i] = snakeY[0];
    }

    // 生成第一个食物
    generateFood();

    // 定时器:控制游戏刷新频率
    timer = new Timer(SPEED, this);
    timer.start();
}

// 生成食物(随机位置,不与蛇身重叠)
private void generateFood() {
    // 食物坐标必须是格子的整数倍
    foodX = random.nextInt(GRID_COUNT) * GRID_SIZE;
    foodY = random.nextInt(GRID_COUNT) * GRID_SIZE;

    // 检查食物是否落在蛇身上,是则重新生成
    for (int i = 0; i < snakeLength; i++) {
        if (snakeX[i] == foodX && snakeY[i] == foodY) {
            generateFood();
            break;
        }
    }
}

// 绘制游戏画面(重写JFrame的paint方法)
@Override
public void paint(Graphics g) {
    super.paint(g);
    // 1. 绘制背景(黑色)
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, GRID_SIZE * GRID_COUNT, GRID_SIZE * GRID_COUNT);

    // 2. 绘制蛇(绿色)
    g.setColor(Color.GREEN);
    for (int i = 0; i < snakeLength; i++) {
        g.fillRect(snakeX[i], snakeY[i], GRID_SIZE - 1, GRID_SIZE - 1); // 减1避免蛇身粘连
    }

    // 3. 绘制食物(红色)
    g.setColor(Color.RED);
    g.fillRect(foodX, foodY, GRID_SIZE - 1, GRID_SIZE - 1);

    // 4. 游戏结束提示
    if (!isRunning) {
        g.setColor(Color.WHITE);
        g.setFont(new Font("宋体", Font.BOLD, 20));
        g.drawString("游戏结束!得分:" + (snakeLength - 3), 
                GRID_SIZE * GRID_COUNT / 6, GRID_SIZE * GRID_COUNT / 2);
    }
}

// 蛇的移动逻辑
private void moveSnake() {
    // 1. 蛇身跟随头部移动(从后往前更新坐标)
    for (int i = snakeLength - 1; i > 0; i--) {
        snakeX[i] = snakeX[i - 1];
        snakeY[i] = snakeY[i - 1];
    }

    // 2. 根据方向更新蛇头坐标
    switch (direction) {
        case "UP":
            snakeY[0] -= GRID_SIZE;
            break;
        case "DOWN":
            snakeY[0] += GRID_SIZE;
            break;
        case "LEFT":
            snakeX[0] -= GRID_SIZE;
            break;
        case "RIGHT":
            snakeX[0] += GRID_SIZE;
            break;
    }

    // 3. 检测是否吃到食物(蛇头与食物坐标重合)
    if (snakeX[0] == foodX && snakeY[0] == foodY) {
        snakeLength++; // 蛇身变长
        generateFood(); // 重新生成食物
    }

    // 4. 检测游戏结束条件
    checkGameOver();
}

// 检测游戏结束(撞墙/咬到自己)
private void checkGameOver() {
    // 撞墙:蛇头超出网格边界
    if (snakeX[0] < 0 || snakeX[0] >= GRID_SIZE * GRID_COUNT ||
        snakeY[0] < 0 || snakeY[0] >= GRID_SIZE * GRID_COUNT) {
        isRunning = false;
        timer.stop();
    }

    // 咬到自己:蛇头与蛇身坐标重合
    for (int i = 1; i < snakeLength; i++) {
        if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
            isRunning = false;
            timer.stop();
            break;
        }
    }
}

// 键盘监听:控制蛇的方向(避免180度反向)
@Override
public void keyPressed(KeyEvent e) {
    int key = e.getKeyCode();
    switch (key) {
        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;
    }
}

// 定时器触发:每帧执行移动和重绘
@Override
public void actionPerformed(ActionEvent e) {
    if (isRunning) {
        moveSnake();
        repaint(); // 重绘画面
    }
}

// 以下两个方法为KeyListener接口必填(无需实现)
@Override
public void keyTyped(KeyEvent e) {}
@Override
public void keyReleased(KeyEvent e) {}

// 主方法:启动游戏
public static void main(String[] args) {
    //  Swing 建议在EDT(事件调度线程)中创建界面
    SwingUtilities.invokeLater(() -> {
        SnakeGame game = new SnakeGame();
        game.setVisible(true); // 显示窗口
    });
}

}

游戏说明

1. 运行方式:

  • 将代码复制到 Java 开发工具(如 IDEA、Eclipse)中,创建  SnakeGame.java  文件;

  • 直接运行  main  方法,即可启动游戏。
    2. 操作规则:

  • 使用键盘 上、下、左、右箭头键 控制蛇的移动方向;

  • 蛇吃到红色食物后会变长,得分 = 蛇长 - 3(初始长度为3);

  • 蛇撞墙或咬到自己时,游戏结束并显示得分。
    3. 可自定义参数:

  • GRID_SIZE :调整格子大小(如改为25,画面会变大);

  • GRID_COUNT :调整网格行列数(如改为25,地图会更大);

  • SPEED :调整游戏速度(如改为100,蛇移动更快)。

核心逻辑解析

  • 图形绘制:通过  paint  方法绘制背景、蛇身、食物,每帧刷新一次;
  • 蛇的移动:从后往前更新蛇身坐标,再根据方向更新蛇头坐标,模拟“跟随”效果;
  • 碰撞检测:实时检测蛇头是否撞墙或咬到自己,触发游戏结束;
  • 定时器:通过  Timer  控制刷新频率,保证游戏匀速运行。
posted @ 2025-11-21 19:19  炖猪脚  阅读(34)  评论(0)    收藏  举报