当前位置: 首页 > web >正文

贪吃蛇游戏设计

整体思路

在开始编码之前,我先对整个游戏的实现思路进行了梳理。主要分为以下几个步骤:

  1. 初始化游戏界面:创建游戏地图,显示欢迎信息和帮助信息。
  2. 初始化蛇和食物:创建蛇的初始形态,并随机生成食物的位置。
  3. 游戏循环:在游戏循环中,不断监听用户的输入,根据输入改变蛇的移动方向,更新蛇的位置,判断蛇是否吃到食物或撞到墙壁、自己的身体,然后更新游戏界面。
  4. 游戏结束处理:当蛇撞到墙壁或自己的身体时,游戏结束,释放相关资源。

代码拆分讲解

1. 头文件 snake.h

#pragma once#include<locale.h>
#include<stdlib.h>
#include<stdio.h>
#include<Windows.h>
#include<stdbool.h>#define WALL L'□'
#define BODY L'■'
#define FOOD L'★'#define POS_X 24
#define POS_Y 5#define KEY_PRESS(VK)  ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )enum GAME_STATUS {OK = 1,ESC,KILL_BY_WALL,KILL_BY_SELF,
};enum DIRECTION {UP=1,DOWN,LEFT,RIGHT,
};typedef struct SnakeNode {int x;int y;struct SnakeNode* next;
}SnakeNode, * pSnakeNode;typedef struct Snake {pSnakeNode pSnake; // 蛇的链表指针pSnakeNode pFood;pSnakeNode pFoodDie;int Score;int FoodScore;int SleepTime;enum GAME_STATUS status;enum DIRECTION dir;
}Snake, * pSnake;// 函数声明
void GameStart(pSnake ps);
void WelcomeToGame();
void CreateMap();
void InitSnake(pSnake ps);
void CreateFood(pSnake ps);
void GameRun(pSnake ps);
void PrintHelpInfo();
void SnakeMove(pSnake ps);
int NextIsFood(pSnake ps, pSnakeNode pNext);
void EatFood(pSnake ps, pSnakeNode pNext);
void CreateeFood(pSnake ps, pSnakeNode pNext);
void NotEatFood(pSnake ps, pSnakeNode pNext);
void KillByWall(pSnake ps);
void KillBySelf(pSnake ps);
void GameEnd(pSnake ps);
void SetPos(int x, int y);

在这个头文件中,我们定义了一些宏和枚举类型,以及蛇和食物的结构体。

同时,声明了游戏中需要用到的所有函数。

例如,WALLBODY 和 FOOD 分别表示墙壁、蛇的身体和食物的字符;

enum GAME_STATUS 表示游戏的状态,包括正常运行、用户退出、撞到墙壁和撞到自己;

enum DIRECTION 表示蛇的移动方向。

2. 初始化游戏界面

void WelcomeToGame()
{// 欢迎信息SetPos(35, 10);printf("欢迎来到贪吃蛇小游戏\n");SetPos(38, 20);system("pause");system("cls");// 操作说明信息SetPos(15, 10);printf("上 . 下 . 左 . 右 控制蛇的移动,F3 是加速,F4 是减速");SetPos(15, 11);printf("合理得到蛇的方向");SetPos(38, 20);system("pause");system("cls");
}void CreateMap() {int i = 0;// 上SetPos(0, 0);for (i = 0; i <= 56; i += 2){wprintf(L"%lc", WALL);}// 下SetPos(0, 26);for (i = 0; i <= 56; i += 2){wprintf(L"%lc", WALL);}// 左for (i = 1; i <= 25; i++){SetPos(0, i);wprintf(L"%lc", WALL);}// 右for (i = 1; i <= 25; i++){SetPos(56, i);wprintf(L"%lc", WALL);}
}void SetPos(int x, int y) {HANDLE hanlde = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos = { x,y };SetConsoleCursorPosition(hanlde, pos);
}

WelcomeToGame 函数用于显示欢迎信息和操作说明,通过 SetPos 函数将光标移动到指定位置,然后输出相应的信息。

CreateMap 函数用于创建游戏地图,绘制出游戏的边界。

SetPos 函数是一个辅助函数,用于将光标移动到控制台的指定位置,方便后续的输出操作。

3. 初始化蛇和食物

void InitSnake(pSnake ps) {pSnakeNode cur = NULL;for (int i = 0; i < 5; i++){cur = (pSnakeNode)malloc(sizeof(SnakeNode));if (cur == NULL){perror("InitSnake():malloc()");return;}cur->x = POS_X + 2 * i;cur->y = POS_Y;cur->next = NULL;// 头插法if (ps->pSnake == NULL){ps->pSnake = cur;}else{cur->next = ps->pSnake;ps->pSnake = cur;}}cur = ps->pSnake;while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}ps->dir = RIGHT;ps->FoodScore = 10;ps->pFood = NULL;ps->Score = 0;ps->SleepTime = 200;ps->status = OK;
}void CreateFood(pSnake ps)
{int x = 0;int y = 0;again:do{x = rand() % 53 + 2;y = rand() % 24 + 1;} while (x % 2 != 0);pSnakeNode cur = ps->pSnake;while (cur){if (x == cur->x && y == cur->y){goto again;}cur = cur->next;}pSnakeNode pFood = (pSnakeNode)malloc(sizeof(SnakeNode));if (pFood == NULL){perror("CreateFood()::malloc()");return;}pFood->x = x;pFood->y = y;ps->pFood = pFood;SetPos(x, y);wprintf(L"%lc", FOOD);
}

InitSnake 函数用于初始化蛇的初始形态,使用头插法创建一个长度为 5 的蛇链表,并将蛇的初始方向设置为向右。

同时,初始化游戏的其他参数,如分数、食物分数、睡眠时间和游戏状态。

CreateFood 函数用于随机生成食物的位置,确保食物不会出现在蛇的身体上。

4. 游戏循环

void GameRun(pSnake ps)
{PrintHelpInfo();do{SetPos(62, 10);printf("总分:%5d\n", ps->Score);SetPos(62, 11);printf("食物的分值:%02d\n", ps->FoodScore);if (KEY_PRESS(0x26) && ps->dir != DOWN){ps->dir = UP;}else if (KEY_PRESS(0x28) && ps->dir != UP){ps->dir = DOWN;}else if (KEY_PRESS(0x25) && ps->dir != RIGHT){ps->dir = LEFT;}else if (KEY_PRESS(0x27) && ps->dir != LEFT){ps->dir = RIGHT;}else if (KEY_PRESS(0x1B)){ps->status = ESC;break;}else if (KEY_PRESS(0x20)){pause();}else if (KEY_PRESS(0x72)){if (ps->SleepTime >= 80){ps->SleepTime -= 30;ps->FoodScore += 2;}}else if (KEY_PRESS(0x73)){if (ps->FoodScore > 2){ps->SleepTime += 30;ps->FoodScore -= 2;}}SnakeMove(ps);Sleep(ps->SleepTime);} while (ps->status == OK);
}void SnakeMove(pSnake ps)
{pSnakeNode pNext = (pSnakeNode)malloc(sizeof(SnakeNode));if (pNext == NULL){perror("SnakeMove()::malloc()");return;}pNext->next = NULL;switch (ps->dir){case UP:pNext->x = ps->pSnake->x;pNext->y = ps->pSnake->y - 1;break;case DOWN:pNext->x = ps->pSnake->x;pNext->y = ps->pSnake->y + 1;break;case LEFT:pNext->x = ps->pSnake->x - 2;pNext->y = ps->pSnake->y;break;case RIGHT:pNext->x = ps->pSnake->x + 2;pNext->y = ps->pSnake->y;break;}if (NextIsFood(ps, pNext)){EatFood(ps, pNext);}else{NotEatFood(ps, pNext);}KillByWall(ps);KillBySelf(ps);
}

GameRun 函数是游戏的主循环,不断监听用户的输入,根据输入改变蛇的移动方向,更新游戏界面,并调用 SnakeMove 函数更新蛇的位置。SnakeMove 函数根据蛇的当前方向计算下一个位置,判断是否吃到食物,然后调用相应的处理函数。

同时,检查蛇是否撞到墙壁或自己的身体。

5. 游戏结束处理

void GameEnd(pSnake ps)
{SetPos(15, 12);switch (ps->status){case ESC:printf("你选择了退出游戏,再见!\n");break;case KILL_BY_WALL:printf("你的蛇撞到墙壁了,游戏结束!\n");break;case KILL_BY_SELF:printf("你的蛇撞到自己了,游戏结束!\n");break;}pSnakeNode cur = ps->pSnake;pSnakeNode del = NULL;while (cur){del = cur;cur = cur->next;free(del);}free(ps->pFood);ps = NULL;
}

GameEnd 函数用于处理游戏结束的情况,根据游戏状态输出相应的信息,并释放蛇和食物的内存。

总结

总得来说,要实现一个项目,就得拆分成很多份来一步一步实现,哪怕是前进和后退,都需要一步一步实现,这就很考验学习的耐心了

http://www.xdnf.cn/news/14936.html

相关文章:

  • Linux 内存水位判断机制与实战调优 —— 从卡顿现象到 ftrace 定位全流程
  • AWS WebRTC:通过shell分析viewer端日志文件
  • 结构型智能科技的关键可行性——信息型智能向结构型智能的转变(修改提纲)
  • 力扣 hot100 Day35
  • 模仿学习(Imitation Learning)
  • c++ duiLib环境集成2
  • 使用 DigitalPlat 免费搭配 Cloudflare Tunnel 实现飞牛系统、服务及 SSH 内网穿透教程
  • AIStarter平台使用指南:如何一键卸载已下载的AI项目(最新版操作教程)
  • 【网络与系统安全】强制访问控制——BLP模型
  • latency 对功耗的影响
  • MyDockFinder 绿色便携版 | 一键仿Mac桌面,非常简单
  • Spring Boot + 本地部署大模型实现:安全性与可靠性保障
  • day55-驱动之系统移植II
  • 马尔可夫链:随机过程的记忆法则与演化密码
  • Jenkins 介绍
  • jQuery Mobile 安装使用教程
  • 【MySQL安装-yum/手动安装,卸载,问题排查处理完整文档(linux)】
  • Docker学习笔记:Docker网络
  • 每周资讯 | Krafton斥资750亿日元收购日本动画公司ADK;《崩坏:星穹铁道》新版本首日登顶iOS畅销榜
  • 力扣:70. 爬楼梯
  • PyTorch实战(14)——条件生成对抗网络(conditional GAN,cGAN)
  • LDO VS DCDC
  • 【Agent】构建专家级SQL Agent交互
  • Android 网络请求优化全面指南
  • node.js下载教程
  • Unity 中相机大小与相机矩形大小的关系
  • 力扣hot100题(1)
  • Android 安装使用教程
  • 网安系列【1】:黑客思维、技术与案例解析
  • MIGraphX的动态shape原理解析