项目实践---贪吃蛇小游戏(下)

server/2024/9/23 6:29:37/

  • 对于贪吃蛇小游戏,最主要的还是主函数部分,这里就和大家一一列举出来,
  • 上一章已经写过头文件了,这里就不多介绍了。

  • 首先就是打印桌面,也就是背景,则对应的代码为:
void SetPos(short x, short y)
{//获取标准输出设备的句柄HANDLE houtput = NULL;houtput = GetStdHandle(STD_OUTPUT_HANDLE);//定位光标的位置COORD pos = { x,y };SetConsoleCursorPosition(houtput, pos);
}void WelcomeToGame()
{system("cls");SetPos(40, 14);wprintf(L"欢迎来到贪吃蛇小游戏\n");SetPos(42, 20);system("pause");system("cls");SetPos(35, 14);wprintf(L"用 w.s.a.d来控制蛇的移动,按q加速,e减速\n");SetPos(35, 15);wprintf(L"加速能够得到更高的分数\n");SetPos(42, 20);system("pause");system("cls");}

  • 然后就是打印墙体,在打印墙体之前,要先声明一下类型,用#define,来定义。则对应的代码为:
void CreateMap()
{//上int i = 0;SetPos(0, 0);for (i = 0; i < 58; i ++){wprintf(L"%lc", WALL);}//下SetPos(0, 26);for (i = 0; i < 58; i++) {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);}
}

  • 然后就是创建蛇身(用链表来实现)和食物,则代码为:
    void InitSnake(pSnake ps)
    {int i = 0;pSnakeNode cur = NULL;for (i = 0; i < 6; i++){cur = (pSnakeNode)malloc(sizeof(SnakeNode));if (cur == NULL){perror("InitSnake()::malloc");return;}cur->next = NULL;cur->x = POS_X + 2 * i;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->_score = 0;ps->_food_weight = 10;ps->_sleep_time = 200;   //单位是msps->_status = OK;
    }void CreateFood(pSnake ps)
    {int x = 0;int y = 0;//生成2的倍数//x:2~53//y:1~25again:do{x = rand() % 53 + 2;y = rand() % 25 + 1;} while (x % 2 != 0);//x和y的坐标不能和蛇的身体坐标冲突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){return;}pFood->x = x;pFood->y = y;pFood->next = NULL;SetPos(x, y);//定义位置wprintf(L"%lc", FOOD);ps->_pFood = pFood;
    }

    有点小多,请耐心看完哦。

  • 蛇的移步和游戏的初始化,则代码为:
    void GameStart(pSnake ps)
    {//1.先设置窗口得大小,再光标隐藏system("mode con cols = 100 lines = 30");system("title 贪吃蛇");HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);//隐藏光标操作CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(houtput, &CursorInfo);//获取控制台光标信息CursorInfo.bVisible = false; //隐藏控制台光标SetConsoleCursorInfo(houtput, &CursorInfo);  //设置控制台光标状态//2.打印环境界面和功能介绍WelcomeToGame();//3.绘制地图CreateMap();//4.创建蛇InitSnake(ps);//5.创建食物CreateFood(ps);
    }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);}
    }

  • 判断下一个坐标是否是食物和下一个位置是食物和下一个位置不是食物,就吃掉食物:则代码为:

    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);//把倒数第二个节点的地址置为NULLcur->next = NULL;
    }

    确实多,请耐心看完。

  • 游戏运行的逻辑,则代码为:
    void GameRun(pSnake ps)
    {//打印帮助信息PrintHelpInfo();do{//打印总分数和食物的分值SetPos(64, 10);printf("总分数:%d\n", ps->_score);SetPos(64, 11);printf("当前食物的分数:%d\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;}}else if (KEY_PRESS(VK_F4)){//减速if (ps->_food_weight > 2){ps->_sleep_time += 30;ps->_food_weight -= 2;}}SnakeMove(ps); //蛇走一步的过程Sleep(ps->_sleep_time);} while (ps->_status == OK);
    }

  • 暂停响应,检测蛇是否撞墙,检测是否撞到自己和结束游戏 - 善后工作,则代码为:
    void pause()
    {while (1){Sleep(200);if(KEY_PRESS(VK_SPACE)){break;}}
    }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 (cur->x == ps->_pSnake->x && cur->y == ps->_pSnake->y){ps->_status = KILL_BY_SELF;break;}cur = cur->next;}
    }void GameEnd(pSnake ps)
    {SetPos(24, 12);switch (ps->_status){case END_NORMAL:wprintf(L"你主动退出\n");break;case KILL_BY_WALL:wprintf(L"您撞上自己了 ,游戏结束!\n");break;case KILL_BY_SELF:wprintf(L"您撞墙了,游戏结束!\n");break;}//释放蛇身的链表pSnakeNode cur = ps->_pSnake;while (cur){pSnakeNode del = cur;cur = cur->next;free(del);}
    }

  • 这贪吃蛇的主函数代码确实多,但也是最重要一部分。请大家耐心看完哦。


http://www.ppmy.cn/server/12170.html

相关文章

Keil和VSCode协同开发STM32程序

系列文章 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. 配置环境 2. 测试打开工程 3. 测试编译工程 随着项目的复杂度上升&#xff0c;开发者不仅需要强大的硬件支持&#xff0c;还需要一个高效和灵活的开发环境。 vscode是一款集成大量可以便携开发插件的代码…

理解CSS中的sticky与fixed定位

在CSS中&#xff0c;position: sticky; 和 position: fixed; 是两种常见的定位方式&#xff0c;它们可以让元素脱离文档流&#xff0c;并具有固定位置的效果。然而&#xff0c;它们在实际应用中有着不同的特点和使用场景。 sticky定位 特点&#xff1a;position: sticky; 允许…

Maven基础篇1

1.Maven依赖管理 2.依赖传递 项目2需要用到项目3 需要将项目三作为资源配置到项目二 也就是dependecy中加入项目三的gav 两点注意事项&#xff1a; 使用项目三&#xff0c;直接将其gav添加到依赖中&#xff0c; 使用项目三&#xff0c;项目三不能感知到&#xff0c;自己有…

在vscode上面进行分支merge的记录

前言&#xff1a;在我们的项目中&#xff0c;有两个分支&#xff1a;master和liutielong。现在要将liutielong分支的改动merge到master分支中。 如果master分支已经更改了&#xff0c;所以要先pull&#xff08;这是在git bash里面的命令&#xff09;。 git pull origin master…

Opencv_11_通道的分离与合并

void ColorInvert::channels_demo(Mat& image) { std::vector<Mat> mv; split(image, mv); imshow("蓝色", mv[0]); imshow("绿色", mv[1]); imshow("红色", mv[2]); Mat dst; mv[0] 0; merge(mv, dst);…

MVP+敏捷开发

MVP敏捷开发 1. 什么是敏捷开发&#xff1f; 敏捷开发是一种软件开发方法论&#xff0c;旨在通过迭代、自组织的团队和持续反馈&#xff0c;快速响应需求变化并交付高质量的软件。相较于传统的瀑布模型&#xff0c;敏捷开发强调灵活性、适应性和与客户的紧密合作。敏捷开发方…

参数传递 的案例

文章目录 12 1 输出一个int类型的数组&#xff0c;要求为&#xff1a; [11,22,33,44,55] package com.zhang.parameter; //有关方法的案例 public class MethodTest3 {public static void main(String[] args) {//输出一个int类型的数组&#xff0c;要求为&#xff1a; [11,…

css flex布局两个元素水平居中垂直居中

文章目录 问题描述解决方案 问题描述 大家好&#xff01;今天是2024年4月23日|农历三月十五&#xff0c;马上就快到五一假期啦&#xff0c;今天这博文主要以使用flex布局&#xff0c;让两个元素水平居中垂直居中&#xff0c;具体实现效果如下&#xff1a; 让图片和文字描述水平…