网站的总体方案,做网站发现是传销,如何做中英文网站,网站规划步骤经过#xff08;1#xff09;#xff08;2#xff09;两篇文章的介绍#xff0c;相信大家对该游戏的实现已经有了具体的思路#xff0c;废话不多说#xff0c;让我们开始实现相关的代码吧#xff01; 1.游戏主逻辑 void test()
{int ch 0;srand((unsigned int)time(NU…经过12两篇文章的介绍相信大家对该游戏的实现已经有了具体的思路废话不多说让我们开始实现相关的代码吧 1.游戏主逻辑 void test()
{int ch 0;srand((unsigned int)time(NULL));do{Snake snake { 0 };GameStart(snake);GameRun(snake);GameEnd(snake);SetPos(20, 15);printf(再来一局吗(Y/N):);ch getchar();} while (ch Y);SetPos(0, 27);
}
int main()
{setlocale(LC_ALL, );//修改当前地区为本地模式test();return 0;
}
2.游戏开始
void GameStart(pSnake ps)
{system(mode con cols100 lines30);//设置控制台窗口大小为30行100列system(title 贪吃蛇);//设置窗口名HANDLE houtput GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出的句柄CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(houtput, CursorInfo);//获取控制台光标信息CursorInfo.bVisible false;//隐藏控制台光标SetConsoleCursorInfo(houtput, CursorInfo);//设置控制台光标状态//打印欢迎界面WelcomeToGame();//打印地图CreateMap();//初始化蛇InitSnake(ps);//创造第一个食物CreateFood(ps);
}
2.1打印欢迎界面
在游戏正式开始之前做一些功能提醒
void WelcomeToGame()
{SetPos(40, 15);printf(欢迎来到贪吃蛇小游戏);SetPos(40, 25);system(pause);system(cls);SetPos(25, 12);printf(用↑ ↓ ← →分别控制蛇的移动F3为加速F4为减速);SetPos(25, 13);printf(加速能够获得更高的分数);SetPos(40, 25);//让任意键继续出现的位置好看些system(pause);system(cls);
}2.2创建地图
墙体打印的宽字符 #define WALL L✖
创建地图函数CreateMap
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 26; i){SetPos(0, i);wprintf(L%lc, WALL);}for (i 1; i 26; i){SetPos(56, i);wprintf(L%lc, WALL);}
}
2.3初始化蛇身
蛇最开始的长度为5节每节对应链表的一个节点蛇身的每一个节点都有自己的坐标。创建5个节点然后将每一个节点放在链表中进行管理。创建完蛇身后将蛇的每一节打印在屏幕上然后再设置当前游戏的1状态蛇移动的速度默认的方向初始成绩蛇的状态和每个食物的分数。
蛇身打印的宽字符 #define BODY L〇
初始化蛇身函数InitSnake
#define POS_X 24
#define POS_Y 5
void InitSnake(pSnake ps)
{pSnakeNode cur NULL;int i 0;//创建蛇身节点并初始化坐标头插法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;}}//打印蛇的身体while (cur){SetPos(cur-x, cur-y);wprintf(L%lc, BODY);cur cur-next;}//初始化贪吃蛇数据ps-_sleepTime 200;ps-_Score 0;ps-_foodWeight 10;ps-_Dir RIGHT;ps-_Status OK;
}
2.4创建食物
先随机生成食物的坐标x坐标必须是2的倍数并且食物的坐标不能和蛇身的每个节点坐标重复创建食物节点打印食物食物打印宽字符#define FOOD L❤
创建食物的函数CreateFood
void CreateFood(pSnake ps)
{int x 0;int y 0;
again:do{x rand() % 53 2;y rand() % 25 1;} while (x % 2 ! 0);//产生的x坐标应该是2的倍数这样才能和蛇头对齐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;}else{pFood-x x;pFood-y y;SetPos(pFood-x, pFood-y);wprintf(L%lc, FOOD);ps-_pFood pFood;}}
3.游戏运行
游戏运行期间右侧帮助打印信息提示玩家根据游戏状态检查游戏是否继续如果游戏继续继续检测按键状态确定蛇下一步移动的方向以及是否加速减速暂停退出确定了上述信息后蛇继续移动
void GameRun(pSnake ps)
{PrintHelpInfo();do{SetPos(64, 10);printf(得分%5d, ps-_Score);printf(每个食物得分%02d, ps-_foodWeight);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_ESCAPE)){ps-_Status END_NORMAL;break;}else if (KEY_PRESS(VK_SPACE)){pause();}else if (KEY_PRESS(VK_F3))//加速休眠时间减少每次得分增加{if (ps-_sleepTime 50){ps-_sleepTime - 30;ps-_foodWeight 2;}}else if (KEY_PRESS(VK_F4)){if (ps-_foodWeight 2){ps-_sleepTime 30;ps-_foodWeight - 2;}}Sleep(ps-_sleepTime);//睡眠一下SnakeMove(ps);//走一步} while (ps-_Status OK);
}3.1KEY_PRESS
为了检测按键状态我们封装了一个宏
#define KEY_PRESS(VK) ((GetAsyncKeyState(VK)0x1)?1:0)
3.2打印帮助信息PrintHelpInfo
void PrintHelpInfo()
{//打印提示信息SetPos(64, 15);printf(不能穿墙不能咬到自己);SetPos(64, 16);printf(用↑↓←→分别控制蛇的移动);SetPos(64, 17);printf(F3为加速F4为减速);SetPos(64, 18);printf(ESC:退出游戏 space暂停游戏);
}3.3蛇身移动
先创建下一个节点根据移动方向和蛇头的坐标蛇移动到下一个位置的坐标确定了下一个位置后看下一个位置是否是食物NextIsFood是食物就做吃食物处理EatFood不是食物就做前进一步处理NoFood。蛇身移动以后判断此次移动是否会撞墙KillByWall或者撞到自己KillBySelf从而影响游戏的状态
void SnakeMove(pSnake ps)
{//创建下一个节点pSnakeNode pNextNode (pSnakeNode)malloc(sizeof(SnakeNode));if (pNextNode NULL){perror(SnakeMove()::malloc());return;}pNextNode-next NULL;//要根据蛇头的坐标和方向确定下一个节点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-x2;pNextNode-y ps-_pSnake-y;}break;}if (NextIsFood(pNextNode, ps)){EatFood(pNextNode,ps);}else{NoFood(pNextNode, ps);}KillByWall(ps);KillBySelf(ps);}
NextIsFood
int NextIsFood(pSnakeNode psn, pSnake ps)
{return ((psn-x ps-_pFood-x) (psn-y ps-_pFood-y));
}EatFood void EatFood(pSnakeNode psn, pSnake ps)//第一个参数是下一个节点的指针第二个参数是维护蛇的指针
{//头插法psn-next ps-_pSnake;ps-_pSnake psn;pSnakeNode cur ps-_pSnake;//打印蛇while (cur){SetPos(cur-x, cur-y);wprintf(L%lc, BODY);cur cur-next;}ps-_Score ps-_foodWeight;free(ps-_pFood);//释放食物节点CreateFood(ps);//创建新的食物
}
NoFood
将下一个节点头插入蛇的身体并且将之前蛇身的最后一个节点打印为空格放弃掉原来蛇身的最后一个节点
void NoFood(pSnakeNode psn, pSnake ps)//将下一个节点插入蛇的身体并且将蛇身的最后一个节点打印为空
{//头插法psn-next ps-_pSnake;ps-_pSnake psn;pSnakeNode cur ps-_pSnake;//打印蛇while (cur-next-next){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;
}KillByWall
判断蛇头的坐标是否与墙体坐标冲突
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;}
}
KillBySelf
判断蛇头的坐标是否和蛇身冲突
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;}}
}
4.游戏结束
当游戏状态不再是OK时要告知游戏结束的原因并且释放蛇身节点
void GameEnd(pSnake ps)
{pSnakeNode cur ps-_pSnake;SetPos(24, 12);switch (ps-_Status){case END_NORMAL:printf(您主动退出游戏\n);break;case KILL_BY_SELF:printf(撞上自己游戏结束\n);break;case KILL_BY_WALL:printf(装上墙壁游戏结束\n);break;}//释放蛇身节点while (cur){pSnakeNode del cur;cur cur-next;free(del);}free(ps-_pFood);ps-_pFood NULL;ps-_pSnake NULL;
}
以上就是贪吃蛇小游戏的全部核心代码啦完整的代码请大家移步我的码云
https://gitee.com/peach-table
新年新气象让我们用一条贪吃蛇来迎接2024的好运吧~
祝大家新的一年身体健康万事如意发大财☼