大数跨境
0
0

手把手教你用C语言实现经典贪吃蛇游戏,代码简单易懂!

手把手教你用C语言实现经典贪吃蛇游戏,代码简单易懂! 趣聊科技圈
2024-09-12
2
导读:主要用了链表来存储蛇的身体,每次蛇移动的时候,蛇头会变成新位置,蛇尾则跟着移动。

hello,大家好,我是程序员黎明 ,写一个贪吃蛇游戏其实挺有意思的,用C语言可以实现一个简单版本,下面我就从第一视角带你了解一下怎么一步步写出来。



1. 确定思路

首先,我得弄清楚贪吃蛇的基本玩法:蛇在一个网格里移动,每次吃到食物就会变长,不能撞墙也不能撞自己。如果撞墙或者撞自己,那游戏就结束。

大体思路是这样:

  1. 蛇的身体可以用一个链表来表示,每个节点代表身体的一部分。
  2. 网格用二维数组来表示,0代表空地,1代表蛇,2代表食物。
  3. 蛇的头部会根据用户按的方向键来移动,每移动一步检查是否吃到食物或者撞到自己/墙。

2. 准备工作

我需要用到一些库函数:

#include <stdio.h>   // 输入输出
#include <stdlib.h>  // 动态内存分配
#include <conio.h>   // 用于检测键盘输入
#include <windows.h> // 实现延时和光标移动

3. 定义数据结构

先把蛇和地图的数据结构搞定:

#define WIDTH 20    // 地图的宽度
#define HEIGHT 20   // 地图的高度

typedef struct Node {    // 蛇的每一节
    int x, y;            // 位置
    struct Nodenext;   // 指向下一个节点
} SnakeNode;

typedef struct {         
    SnakeNode* head;     // 蛇头
    SnakeNode* tail;     // 蛇尾
    int length;          // 蛇的长度
} Snake;

int map[HEIGHT][WIDTH];  // 地图数组
int foodX, foodY;        // 食物的坐标

蛇用链表来表示,蛇头和蛇尾分别有指针,这样方便控制蛇的增长和移动。

4. 初始化

我要让游戏有个初始状态,比如蛇和食物的位置。

void initGame(Snake* snake) {
    // 初始化蛇,默认在地图中央
    snake->head = (SnakeNode*)malloc(sizeof(SnakeNode));
    snake->head->x = WIDTH / 2;
    snake->head->y = HEIGHT / 2;
    snake->head->next = NULL;
    snake->tail = snake->head;
    snake->length = 1;
    
    // 清空地图
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            map[i][j] = 0;
        }
    }
    
    // 设置食物位置
    foodX = rand() % WIDTH;
    foodY = rand() % HEIGHT;
    map[foodY][foodX] = 2;
}

5. 游戏循环

游戏的主要逻辑需要不断重复,所以我需要一个循环来控制蛇的移动、吃食物、碰撞检测等。

5.1 方向控制

先处理方向控制,用户按方向键来控制蛇的移动方向:

char getInput() {
    if (_kbhit()) {  // 检查是否有按键输入
        return _getch();  // 获取用户按下的键
    }
    return '\0';  // 没有输入时返回空字符
}

5.2 移动蛇

根据方向移动蛇的头部,然后更新身体位置:

void moveSnake(Snake* snake, char direction) {
    int newX = snake->head->x;
    int newY = snake->head->y;

    // 根据方向调整新坐标
    if (direction == 'w') newY--;  // 上
    else if (direction == 's') newY++;  // 下
    else if (direction == 'a') newX--;  // 左
    else if (direction == 'd') newX++;  // 右

    // 创建新节点并移动蛇头
    SnakeNode* newHead = (SnakeNode*)malloc(sizeof(SnakeNode));
    newHead->x = newX;
    newHead->y = newY;
    newHead->next = snake->head;
    snake->head = newHead;
    
    // 检查是否吃到食物
    if (newX == foodX && newY == foodY) {
        snake->length++;
        // 随机生成新食物
        foodX = rand() % WIDTH;
        foodY = rand() % HEIGHT;
        map[foodY][foodX] = 2;
    } else {
        // 蛇尾跟随移动,释放旧蛇尾节点
        SnakeNode* temp = snake->tail;
        snake->tail = snake->tail->next;
        free(temp);
    }
}

5.3 碰撞检测

每次移动蛇后,我还得检查有没有撞墙或者撞自己。

int checkCollision(Snake* snake) {
    int headX = snake->head->x;
    int headY = snake->head->y;

    // 撞墙
    if (headX < 0 || headX >= WIDTH || headY < 0 || headY >= HEIGHT) {
        return 1;
    }

    // 撞自己
    SnakeNode* current = snake->head->next;
    while (current != NULL) {
        if (current->x == headX && current->y == headY) {
            return 1;
        }
        current = current->next;
    }
    return 0;
}

5.4 游戏展示

要让玩家看到蛇和食物,我需要实时刷新屏幕,把当前的状态打印出来。

void drawGame(Snake* snake) {
    system("cls");  // 清屏

    // 绘制地图
    for (int i = 0; i < HEIGHT; i++) {
        for (int j = 0; j < WIDTH; j++) {
            if (i == snake->head->y && j == snake->head->x) {
                printf("O");  // 蛇头
            } else if (i == foodY && j == foodX) {
                printf("F");  // 食物
            } else {
                printf(" ");  // 空地
            }
        }
        printf("\n");
    }
}

6. 游戏结束

一旦蛇撞墙或者撞自己,游戏就结束,跳出循环:

int main() {
    Snake snake;
    initGame(&snake);
    
    char direction = 'd';  // 初始方向向右

    while (1) {
        char input = getInput();
        if (input) {
            direction = input;
        }
        
        moveSnake(&snake, direction);
        
        if (checkCollision(&snake)) {
            printf("Game Over!\n");
            break;
        }
        
        drawGame(&snake);
        Sleep(200);  // 控制移动速度
    }
    
    return 0;
}

7. 总结

这就是一个简单版的贪吃蛇游戏,用C语言实现的。我主要用了链表来存储蛇的身体,每次蛇移动的时候,蛇头会变成新位置,蛇尾则跟着移动。如果你想要加更多功能,比如加速、关卡等,可以在这个基础上继续扩展哦。

这样写出来的贪吃蛇虽然很基础,但完全可以作为学习C语言编程的一个好项目。好了,本期我们就学到这里啦,我们下期不见不散!


【声明】内容源于网络
0
0
趣聊科技圈
🧐探索科技,发现乐趣。🤩带你玩遍科技好物!
内容 511
粉丝 0
趣聊科技圈 🧐探索科技,发现乐趣。🤩带你玩遍科技好物!
总阅读260
粉丝0
内容511