欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 焦点 > 《贪吃蛇小游戏 1.0》源码

《贪吃蛇小游戏 1.0》源码

2024/10/23 19:32:34 来源:https://blog.csdn.net/lrq13965748542/article/details/142765222  浏览:    关键词:《贪吃蛇小游戏 1.0》源码

好久不见!

终于搞好了简易版贪吃蛇小游戏(C语言版),邀请你来玩一下~

目录

Snake.h

Snake.c

test.c


Snake.h

#include<stdio.h>
#include<windows.h>
#include<stdbool.h>
#include<stdlib.h>
#include<time.h>#define POS_X 24
#define POS_Y 5#define WALL L'□'
#define BODY L'●'
#define FOOD L'★'//类型的声明//蛇的方向
enum DIRECTION
{UP,DOWN,LEFT,RIGHT
};//蛇的状态
//正常,撞墙,撞到自己,正常退出
enum GAME_STATUS
{OK,KILL_BY_WALL,KILL_BY_SELF,END_NORMAL
};//蛇身的节点类型
typedef struct SnakeNode
{//坐标int x;int y;//指向蛇身体下一个节点的指针struct SnakeNode* next;
}SnakeNode, * pSnakeNode;//贪吃蛇
typedef struct Snake
{pSnakeNode _pSnake;//指向蛇头的指针pSnakeNode _pFood;//指向食物的指针enum DIRECTION _dir;//蛇的方向enum GAME_STATUS _status;//蛇的状态int _food_weight;//一个食物的分数int _score;//总分数int _sleep_time;//休息时间,时间越短,速度越快,时间越长,速度越慢
}Snake, * pSnake;//函数的声明//定位光标的位置
void SetPos(short x, short y);//游戏的初始化
void GameStart(pSnake ps);//打印欢迎界面
void WelcomeToGame();//打印地图
void CreateMap();//初始化蛇身
void InitSnake(pSnake ps);//创建食物
void CreateFood(pSnake ps);//游戏运行的逻辑
void GameRun(pSnake ps);//蛇移动,走一步
void SnakeMove(pSnake ps);//判断下一个坐标是否是食物
int NextIsFood(pSnakeNode pn, pSnake ps);//下一个位置是食物,就吃掉食物
void EatFood(pSnakeNode pn, pSnake ps);//下一个位置不是食物
void NoFood(pSnakeNode pn, pSnake ps);//检测蛇是否撞墙
void KillByWall(pSnake ps);//检测蛇是否撞到自己
void KillBySelf(pSnake ps);//游戏善后的工作
void GameEnd(pSnake ps);

Snake.c

#include"Snake.h"//定位光标的位置
void SetPos(short x, short y)
{//获取标准输出设备的句柄HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);//定位控制台里面光标的位置COORD pos = { x,y };SetConsoleCursorPosition(houtput, pos);
}//打印欢迎界面
void WelcomeToGame()
{SetPos(46, 14);wprintf(L"欢迎来到贪吃蛇小游戏\n");SetPos(50, 20);//让“按任意位置继续”的位置好看些system("pause");system("cls");SetPos(30, 14);wprintf(L"用 ↑ . ↓ . ← . → 分别控制蛇的移动, F3为加速,F4为减速\n");SetPos(44, 16);wprintf(L"加速将能得到更高的分数\n");SetPos(48, 20);system("pause");system("cls");}//打印地图
void CreateMap()
{int i = 0;//上for (i = 0; i < 29; i++){wprintf(L"%c", WALL);}//下SetPos(0, 26);for (i = 0; i < 29; i++){wprintf(L"%c", WALL);}//左for (i = 1; i < 26; i++){SetPos(0, i);wprintf(L"%c", WALL);}//右for (i = 1; i < 26; i++){SetPos(56, i);wprintf(L"%c", WALL);}}//初始化蛇身
void InitSnake(pSnake ps)
{int i = 0;pSnakeNode cur = NULL;for (i = 0; i < 5; i++){cur = (pSnakeNode)malloc(sizeof(SnakeNode));if (cur == NULL){perror("InitSnake()::malloc()");return;}cur->next = NULL;cur->x = POS_X + i * 2;cur->y = POS_Y;//头插法插入链表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->_status = OK;//蛇的状态ps->_food_weight = 10;//一个食物的分数ps->_score = 0;//总分数ps->_sleep_time = 200; //单位是毫秒}//创建食物
void CreateFood(pSnake ps)
{int x = 0;int y = 0;//x生成是2的倍数//x:2~54//y:1~25
again:do{x = rand() % 53 + 2;y = rand() % 25 + 1;} while (x % 2 != 0);//食物的坐标和蛇身结点的坐标不能冲突pSnakeNode cur = ps->_pSnake;while (cur){if (cur->x == x && cur->y == 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;pFood->next = NULL;SetPos(x, y);wprintf(L"%lc", FOOD);ps->_pFood = pFood;
}void GameStart(pSnake ps)
{//0.先设置窗口大小,再光标隐藏system("mode con cols=115 lines=30");system("title 贪吃蛇");HANDLE hOutput = NULL;//获取标准输出的句柄(⽤来标识不同设备的数值)hOutput = GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息CursorInfo.bVisible = false; //隐藏控制台光标SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态//1.打印游戏界面 + 功能介绍WelcomeToGame();//2.绘制地图CreateMap();//3.创建蛇InitSnake(ps);//4.创建食物CreateFood(ps);
}//右侧提示信息的打印
void PrintHelpInfo()
{SetPos(67, 12);wprintf(L"%ls", L"提示信息如下:");SetPos(67, 14);wprintf(L"%ls", L"1.不能穿墙,不能咬到自己");SetPos(67, 15);wprintf(L"%ls", L"2.用 ↑ . ↓ . ← . → 分别控制蛇的移动");SetPos(67, 16);wprintf(L"%ls", L"3.按F3加速,按F4减速");SetPos(67, 20);wprintf(L"%ls", L"云边有个稻草人@版权");
}#define KEY_PRESS(vk) ((GetAsyncKeyState(vk)&1)?1:0)//暂停游戏
void Pause()
{while (1){Sleep(200);if (KEY_PRESS(VK_SPACE)){break;}}
}//判断下一个节点是否是食物
int NextIsFood(pSnakeNode pn, pSnake ps)
{return (ps->_pFood->x == pn->x && ps->_pFood->y == pn->y);
}//吃食物
void EatFood(pSnakeNode pn, pSnake ps)
{//头插法将食物插入链表ps->_pFood->next = ps->_pSnake;ps->_pSnake = ps->_pFood;//释放下一个位置的节点free(pn);pn = NULL;pSnakeNode cur = ps->_pSnake;//打印蛇while (cur){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}ps->_score += ps->_food_weight;//重新创建食物CreateFood(ps);}void NoFood(pSnakeNode pn, pSnake ps)
{//头插pn->next = ps->_pSnake;ps->_pSnake = pn;//打印蛇身pSnakeNode cur = ps->_pSnake;while (cur->next->next != NULL){SetPos(cur->x, cur->y);wprintf(L"%lc", BODY);cur = cur->next;}//将最后一个节点打印成空白字符SetPos(cur->next->x, cur->next->y);printf("  ");//释放最后一个节点free(cur->next);//将倒数第二个节点的地址置为空cur->next = NULL;
}void KillByWall(pSnake ps)
{if (ps->_pSnake->x == 0 || ps->_pSnake->x == 56 || ps->_pSnake->y == 0 || ps->_pSnake->y == 26){ps->_status = KILL_BY_WALL;}
}void KillBySelf(pSnake ps)
{pSnakeNode cur = ps->_pSnake->next;while (cur){if (ps->_pSnake->x == cur->x && ps->_pSnake->y == cur->y){ps->_status = KILL_BY_SELF;break;}cur = cur->next;}
}void SnakeMove(pSnake ps)
{//创建一个节点,表示蛇即将到达的下一个节点pSnakeNode pNextNode = (pSnakeNode)malloc(sizeof(SnakeNode));if (pNextNode == NULL){perror("SnakeMove()::malloc()");return;}switch (ps->_dir){case UP:pNextNode->x = ps->_pSnake->x;pNextNode->y = ps->_pSnake->y - 1;break;case DOWN:pNextNode->x = ps->_pSnake->x;pNextNode->y = ps->_pSnake->y + 1;break;case LEFT:pNextNode->x = ps->_pSnake->x - 2;pNextNode->y = ps->_pSnake->y;break;case RIGHT:pNextNode->x = ps->_pSnake->x + 2;pNextNode->y = ps->_pSnake->y;break;}//检测下一个坐标处是否是食物if (NextIsFood(pNextNode, ps)){EatFood(pNextNode, ps);}else{NoFood(pNextNode, ps);}//检测蛇是否撞墙KillByWall(ps);//检测蛇是否撞到自己KillBySelf(ps);
}//运行游戏
void GameRun(pSnake ps)
{//打印帮助信息PrintHelpInfo();do{//打印总分数和食物的分值SetPos(64, 10);printf("总分数:%d\n", ps->_score);SetPos(64, 11);printf("每个食物得分:%2d\n", ps->_food_weight);if (KEY_PRESS(VK_UP) && ps->_dir != DOWN){ps->_dir = UP;}else if (KEY_PRESS(VK_DOWN) && ps->_dir != UP){ps->_dir = DOWN;}else if (KEY_PRESS(VK_LEFT) && ps->_dir != RIGHT){ps->_dir = LEFT;}else if (KEY_PRESS(VK_RIGHT) && ps->_dir != LEFT){ps->_dir = RIGHT;}else if (KEY_PRESS(VK_SPACE)){Pause();}else if (KEY_PRESS(VK_ESCAPE)){ps->_status = END_NORMAL;}else if (KEY_PRESS(VK_F3)){if (ps->_sleep_time > 80){ps->_sleep_time -= 30;ps->_food_weight += 2;//⼀个⻝物分数最⾼是20分}}else if (KEY_PRESS(VK_F4)){if (ps->_sleep_time > 2){ps->_sleep_time += 30;ps->_food_weight -= 2;//⼀个⻝物分数最低是2分}}//蛇每次⼀定之间要休眠的时间,时间短,蛇移动速度就快Sleep(ps->_sleep_time);SnakeMove(ps);} while (ps->_status == OK);
}//游戏善后工作
void GameEnd(pSnake ps)
{SetPos(44, 12);switch (ps->_status){case END_NORMAL:printf("您主动退出游戏\n");break;case KILL_BY_WALL:printf("撞到墙上了,游戏结束\n");break;case KILL_BY_SELF:printf("撞到自己了,游戏结束\n");break;}//释放蛇身的链表pSnakeNode cur = ps->_pSnake;while (cur){pSnakeNode del = cur;cur = cur->next;free(del);}
}

test.c

#include<locale.h>
#include "Snake.h"//完成的是游戏的测试逻辑
void test()
{int ch = 0;do{system("cls");//创建贪吃蛇Snake snake = { 0 };//初始化游戏//1.打印游戏界面//2.功能介绍//3.绘制地图//4.创建蛇//5.创建食物//6.设置游戏的相关信息GameStart(&snake);//运行游戏GameRun(&snake);//结束游戏GameEnd(&snake);SetPos(30, 15);printf("再来一局吗? Y/N");ch = getchar();while (getchar() != '\n');} while (ch == 'Y' || ch == 'y');SetPos(0, 27);
}int main()
{setlocale(LC_ALL, "");srand((unsigned int)time(NULL));test();return 0;
}


分享一首宝藏歌曲 

Not Angry_Chris James_高音质在线试听_Not Angry歌词|歌曲下载_酷狗音乐

如有不正确的地方不妨大胆的提出来哦~

我是云边有个稻草人

期待与你的下一次相遇

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com