C语言实现推箱子游戏:源码解析与关卡设计指南

花开有时
花开有时
发布时间:2026-10-15| 4人浏览过
原创

本文将深入解析如何使用 C 语言在控制台中开发一个功能完整的推箱子(Sokoban)游戏。内容涵盖从常量定义、二维地图加载、实体移动逻辑到多步回退系统的实现细节,并提供基于文本文件的关卡配置方法。

实现目标与技术准备

本项目的目标是构建一个支持多关卡、具备“重新开始”和“回退”功能的控制台推箱子游戏。主要依赖的技术包括:C语言的标准输入输出库、getopt.h或特定环境下的按键处理,以及通过 二维数组 存储和管理地图状态。

第1步:定义常量与数据结构

首先,需要定义地图的尺寸上限、各种实体的标识符以及按键的键值。这些宏定义构成了游戏的基础逻辑。

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

#define MAX_ROWS 16      // 最大行数
#define MAX_COLS 16      // 最大列数 (原文误写为CLOS)
#define MAX_LEVEL 5      // 预设关卡数
#define FILE_NAME_LEN 40

// 地图元素定义
#define ROAD  0   // 空地
#define WALL  1   // 墙壁
#define BOX   2   // 箱子
#define TERM  3   // 终点目标
#define MOUS  4   // 玩家(老鼠)
#define IGN   224 // 无效键值

// 方向键值 (取决于编译环境) 
#define LEFT    75
#define RIGHT   77
#define UP      72
#define DOWN    80

// 组合状态:角色在终点/箱子在终点
#define MINT (MOUS + TERM)
#define BINT (BOX + TERM)

// 操作指令
#define QUIT  'q'
#define RESET 'r'
#define BACK  'b'

struct Act {
    int dir; // 动作方向
    int sta; // 动作状态(MM/BM)
};

int acts[MAX_BACK_STEP] = {};
// ... 其他全局变量声明

第2步:加载地图数据

游戏不再将地图硬编码在代码中,而是通过读取外部的 .txt 文件来动态加载关卡。这种方式极大地扩展了游戏的可玩性。

  • 目的:根据关卡索引读取对应的文本文件,初始化地图数组,并定位玩家初始位置和统计箱子数量。
  • 关键逻辑:
    • 使用 fscanf 读取行列数和每个格子的属性值。
    • 遍历数组时,若遇到 MOUS 或 MINT,记录玩家坐标 (mx, my)。
    • 若遇到 BOX 或 BINT,增加箱子计数器 bcnt。
void load(int level) {
    char fileName[FILE_NAME_LEN];
    sprintf(fileName, "%d.txt", level); // 文件名格式: 1.txt, 2.txt...
    FILE *fp = fopen(fileName, "r");
    if(fp == NULL) {
        printf("%s 文件打开失败\n", fileName);
        exit(-1);
    }
    fscanf(fp, "%d %d", &row, &col);
    // 循环读取矩阵...
    fclose(fp);
}

第3步:渲染地图与控制台显示

每次操作后,程序需要清空屏幕并重绘地图。通过遍历二维数组,根据数值打印对应的字符:

  • ROAD: 空格
  • WALL: #
  • TERM: O
  • BOX: @
  • MOUS: &
  • BINT/MINT: 覆盖层显示 (如终点上的箱子或人)
int show(void) {
    for(i=0; i<row; i++) {
        for(j=0; j<col; j++) {
            switch(board[i][j]) {
                case ROAD: printf(" "); break;
                case WALL: printf("#"); break;
                // ... 其他case
            }
        }
        printf("\n");
    }
    // 返回当前位于终点(TERM)上的箱子数量
}

第4步:核心移动算法

这是游戏最难的部分,需同时处理“玩家移动”和“推箱子移动”。逻辑遵循以下规则:

  1. 玩家进入空地/终点:直接更新位置,原位置减去 MOUS,新位置加上 MOUS。
  2. 玩家进入箱子:
    • 计算箱子前方的格子 (nnx, nny)。
    • 若前方是 ROAD 或 TERM,则执行推箱:箱子移动到前方,玩家移动到箱子原位置。
    • 若前方受阻(墙或其他),则不能移动。
int move(int stepx, int stepy) {
    int nx = mx + stepx;
    int ny = my + stepy;
    
    // 情况1:直接进入空地或终点
    if (board[nx][ny] == ROAD || board[nx][ny] == TERM) {
        board[mx][my] -= MOUS;
        board[nx][ny] += MOUS;
        mx = nx; my = ny;
        return MM; // 移动标记
    }
    // 情况2:尝试推箱子
    else if (board[nx][ny] == BOX || board[nx][ny] == BINT) {
        int nnx = nx + stepx;
        int nny = ny + stepy;
        if (board[nnx][nny] == ROAD || board[nnx][nny] == TERM) {
            board[nnx][nny] += BOX;
            board[nx][ny] -= BOX;
            // 玩家跟随
            board[mx][my] -= MOUS;
            board[nx][ny] += MOUS;
            mx = nx; my = ny;
            return BM; // 推箱标记
        }
    }
    return NM; // 无效移动
}

第5步:实现撤销(回退)功能

为了实现无限回退(受限缓冲区内),系统记录了最近的操作序列。当按下回溯键时,反向执行之前记录的移动。由于推箱子涉及两个物体的变动,回退时需要先还原箱子位置,再还原玩家位置。

void back(void) {
    if(stepsize > 0) {
        // 根据记录的方向反转移动
        // 注意:若上一步是推箱子(BM),需额外处理箱子复位
        moveback(+1, 0); // 示例:反向上移
        stepsize--;
        newindex--;
    }
}

第6步:主循环与交互

游戏的主循环负责监听键盘输入并刷新画面。支持的快捷键包括:

  • 方向键:控制角色移动。
  • 'q':退出游戏。
  • 'r':重置当前关卡。
  • 'b':撤销上一步。

如何创建自定义关卡

要在游戏中添加自定义地图,请在同级目录下创建一个名为 数字.txt 的文件(例如 99.txt)。文件格式要求如下:

  1. 第一行:输入地图的行数和列数,例如 10 10。
  2. 后续行:每行包含一行地图数据,数字间用空格分隔。对应关系见第一步的宏定义(0=路, 1=墙, 2=箱, 3=点, 4=人)。
  3. 注意:确保文件中数字之间有空格,且没有多余的空格符号,以免导致读取错位。
// 示例 1.txt 内容
5 5
0 0 0 0 0
0 1 1 1 0
0 1 3 1 0
0 4 2 3 0
0 0 0 0 0
以上就是利用 C 语言实现推箱子游戏的详细内容,更多关于 C 语言小游戏开发的资料请关注本站其它相关文章!
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。