Linux下C语言小游戏如何实现?

99ANYc3cd6
预计阅读时长 22 分钟
位置: 首页 C语言 正文

下面我将为你详细介绍如何在 Linux 下用 C 语言开发一个简单的贪吃蛇游戏,并提供一个完整的、可运行的代码示例,这个例子将涵盖游戏的核心逻辑,包括:

linux下的c语言小游戏
(图片来源网络,侵删)
  • 使用 ncurses 库进行图形渲染和键盘输入处理。
  • 游戏循环。
  • 蛇的移动、增长和碰撞检测。
  • 食物的生成和吃掉食物的逻辑。

第一步:环境准备

在开始编码之前,你需要确保你的 Linux 系统上安装了 gcc 编译器和 ncurses 开发库。

  1. 安装 GCC 大多数 Linux 发行版都默认安装了 GCC,如果没有,可以使用包管理器安装:

    • Debian / Ubuntu:
      sudo apt update
      sudo apt install build-essential
    • Fedora / CentOS / RHEL:
      sudo dnf groupinstall "Development Tools"
  2. 安装 Ncurses 库 ncurses 是一个用于在终端中创建用户界面的库。

    • Debian / Ubuntu:
      sudo apt install libncurses5-dev libncursesw5-dev
    • Fedora / CentOS / RHEL:
      sudo dnf install ncurses-devel

第二步:贪吃蛇游戏设计

我们将创建一个经典的贪吃蛇游戏,规则如下:

linux下的c语言小游戏
(图片来源网络,侵删)
  • 游戏在一个固定大小的网格(20x40)中进行。
  • 玩家通过方向键(上、下、左、右)控制蛇的移动方向。
  • 蛇会不断向前移动,吃到食物()后,身体会变长,并且得分增加。
  • 如果蛇头撞到墙壁或自己的身体,游戏结束。

第三步:编写 C 语言代码

创建一个名为 snake.c 的文件,并将以下代码复制进去。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ncurses.h>
#include <stdbool.h>
// 定义游戏区域的大小
#define WIDTH 40
#define HEIGHT 20
// 定义蛇和食物的结构体
typedef struct {
    int x, y;
} Point;
// 游戏状态
Point snake[100]; // 蛇的身体,最多100节
int snake_length = 3; // 初始蛇的长度
Point food; // 食物的位置
int direction = RIGHT; // 初始方向向右
bool game_over = false;
// 方向定义
enum { UP, DOWN, LEFT, RIGHT };
// 函数声明
void setup();
void draw();
void input();
void logic();
void generate_food();
int main() {
    setup();
    while (!game_over) {
        draw();
        input();
        logic();
        usleep(100000); // 控制游戏速度,100毫秒
    }
    // 游戏结束,清理 ncurses
    endwin();
    printf("Game Over! Your score: %d\n", snake_length - 3);
    return 0;
}
// 初始化游戏
void setup() {
    initscr();          // 初始化 ncurses 模式
    clear();            // 清屏
    noecho();           // 不回显用户输入的字符
    cbreak();           // 立即读取输入,无需回车
    curs_set(0);        // 隐藏光标
    keypad(stdscr, TRUE); // 启用功能键(如方向键)
    nodelay(stdscr, TRUE); // 非阻塞模式,getch() 立即返回
    // 初始化蛇的位置(从中间开始)
    snake[0].x = WIDTH / 2;
    snake[0].y = HEIGHT / 2;
    snake[1].x = WIDTH / 2 - 1;
    snake[1].y = HEIGHT / 2;
    snake[2].x = WIDTH / 2 - 2;
    snake[2].y = HEIGHT / 2;
    generate_food();
}
// 绘制游戏界面
void draw() {
    clear();
    // 绘制上边界
    for (int i = 0; i < WIDTH; i++) {
        mvprintw(0, i, "#");
    }
    // 绘制下边界
    for (int i = 0; i < WIDTH; i++) {
        mvprintw(HEIGHT, i, "#");
    }
    // 绘制左边界
    for (int i = 0; i < HEIGHT; i++) {
        mvprintw(i, 0, "#");
    }
    // 绘制右边界
    for (int i = 0; i < HEIGHT; i++) {
        mvprintw(i, WIDTH, "#");
    }
    // 绘制蛇
    for (int i = 0; i < snake_length; i++) {
        if (i == 0) {
            mvprintw(snake[i].y, snake[i].x, "O"); // 蛇头用 O 表示
        } else {
            mvprintw(snake[i].y, snake[i].x, "o"); // 蛇身用 o 表示
        }
    }
    // 绘制食物
    mvprintw(food.y, food.x, "@");
    // 显示分数
    mvprintw(HEIGHT + 1, 0, "Score: %d", snake_length - 3);
    refresh(); // 将缓冲区的内容输出到屏幕
}
// 处理用户输入
void input() {
    int ch = getch();
    switch (ch) {
        case KEY_UP:
            if (direction != DOWN) direction = UP;
            break;
        case KEY_DOWN:
            if (direction != UP) direction = DOWN;
            break;
        case KEY_LEFT:
            if (direction != RIGHT) direction = LEFT;
            break;
        case KEY_RIGHT:
            if (direction != LEFT) direction = RIGHT;
            break;
        case 'q': // 按 q 键退出游戏
            game_over = true;
            break;
    }
}
// 游戏逻辑更新
void logic() {
    // 1. 移动蛇的身体
    for (int i = snake_length - 1; i > 0; i--) {
        snake[i].x = snake[i - 1].x;
        snake[i].y = snake[i - 1].y;
    }
    // 2. 根据方向移动蛇头
    switch (direction) {
        case UP:
            snake[0].y--;
            break;
        case DOWN:
            snake[0].y++;
            break;
        case LEFT:
            snake[0].x--;
            break;
        case RIGHT:
            snake[0].x++;
            break;
    }
    // 3. 检查是否撞墙
    if (snake[0].x == 0 || snake[0].x == WIDTH - 1 || snake[0].y == 0 || snake[0].y == HEIGHT - 1) {
        game_over = true;
    }
    // 4. 检查是否撞到自己
    for (int i = 1; i < snake_length; i++) {
        if (snake[0].x == snake[i].x && snake[0].y == snake[i].y) {
            game_over = true;
        }
    }
    // 5. 检查是否吃到食物
    if (snake[0].x == food.x && snake[0].y == food.y) {
        snake_length++; // 蛇变长
        generate_food(); // 生成新食物
    }
}
// 生成食物
void generate_food() {
    bool on_snake;
    do {
        on_snake = false;
        food.x = rand() % (WIDTH - 2) + 1; // 1 到 WIDTH-2
        food.y = rand() % (HEIGHT - 2) + 1; // 1 到 HEIGHT-2
        // 检查食物是否生成在蛇身上
        for (int i = 0; i < snake_length; i++) {
            if (snake[i].x == food.x && snake[i].y == food.y) {
                on_snake = true;
                break;
            }
        }
    } while (on_snake);
}

第四步:编译和运行

  1. 保存代码 将上面的代码保存为 snake.c

  2. 编译 打开终端,进入 snake.c 所在的目录,使用以下命令进行编译。关键在于要链接 ncurses

    gcc snake.c -o snake -lncurses
    • gcc snake.c: 编译 snake.c 文件。
    • -o snake: 指定输出的可执行文件名为 snake
    • -lncurses: 链接 ncurses 库,这是让程序能够使用 ncurses 函数的关键。
  3. 运行 编译成功后,直接运行生成的可执行文件:

    linux下的c语言小游戏
    (图片来源网络,侵删)
    ./snake

你应该可以在终端里看到贪吃蛇游戏了!使用方向键控制,按 q 键退出。


第五步:扩展思路

这个贪吃蛇游戏是一个很好的起点,你可以尝试在此基础上进行扩展,增加更多功能:

  1. 难度递增:随着分数增加,让蛇的移动速度变快(减少 usleep 的参数)。
  2. 计分板:记录最高分,并保存到文件中。
  3. 关卡系统:设置不同大小的地图,或者增加障碍物。
  4. 更好的图形:使用 Unicode 字符(如 )来绘制蛇和食物,让游戏看起来更酷炫。
  5. 多人模式:这是一个比较复杂的挑战,可以使用多线程或进程来实现,两个玩家各自控制一条蛇。
  6. 声音:在吃到食物或游戏结束时播放简单的音效(可以使用 Beep 系统调用或 ALSA 库)。

其他 Linux C 语言小游戏创意

除了贪吃蛇,你还可以尝试开发:

  • 扫雷:经典的逻辑推理游戏,主要挑战在于管理游戏板的状态和计算周围地雷的数量。
  • 俄罗斯方块:需要处理方块的形状、旋转、下落、消行等逻辑,以及预览下一个方块。
  • 井字棋:一个简单的双人游戏,非常适合学习游戏状态管理和胜负判断逻辑。
  • 猜数字:一个简单的文字游戏,可以练习随机数生成和循环结构。

希望这个详细的教程能帮助你开启 Linux C 语言游戏开发之旅!祝你编程愉快!

-- 展开阅读全文 --
头像
dede自定义提交时间如何设置?
« 上一篇 03-04
C语言中rand函数如何正确使用?
下一篇 » 03-04

相关文章

取消
微信二维码
支付宝二维码

目录[+]