上分宝:值得大家信赖的下载网站!

所在位置:首页 > 攻略资讯 > 贪吃蛇大作战下载,实战C/C++贪吃蛇大作战

贪吃蛇大作战下载,实战C/C++贪吃蛇大作战

时间:2023-08-23 14:44:32来源:互联网

贪吃蛇大作战
贪吃蛇大作战经典游戏贪吃蛇游戏贪吃蛇大作战
  • 游戏类别:益智休闲
  • 游戏大小:675.6M
  • 游戏语言:中文
  • 游戏版本:5.18.1
点击查看
扫码查看

这是一个贪吃蛇大作战类游戏,修改特性为 AI 不互杀;

该程序有四个类:蛇基类 SnakeBase,玩家类 Player,AI 类,Game 类;SnakeBase 和 AI 均继承自 SnakeBase,SnakeBase 提供基础接口;

Game 提供数据初始化以及游戏主循环。

程序设计之初,采用“实运行”方式,即所有动画均在地图 imgMap 上真实绘制,这样却有一些严重的问题,需要不断地记录节点背景以恢复节点经过的地方等。

后修改为“虚运行”方式,判断位置是否可视后直接绘至窗口内,这样大大降低时间开销,同时不会因为蛇靠近而产生不可擦除的颜色。

至于蛇运行,采用位置继承,即节点下一个位置为上一个节点的位置,但是会发现跨度太大,解决办法是在这个跨度中插入适当帧数。

执行效果如下:

贪吃蛇大作战下载


完整的游戏源代码如下:

/* 程序名称: 贪吃蛇大作战 简介: 简单模拟了游戏 贪吃蛇大作战 程序运行中可以通过 ESC 直接退出 左键或右键可以加速移动,加速会消耗长度 环境: VS2019 EasyX_20190529(beta) 作者: Teternity(QQ:1926594835)*/​​////////// 头文件 //////////include include pragma comment( lib, "MSIMG32.LIB")​​////////// 窗口大小 //////////const short ScreenWidth = 640;const short ScreenHeight = 480;​​////////// 全局变量 //////////long ret = 0;MOUSEMSG msg;const short gap = 20;const short xSide = ScreenWidth / 2 gap;const short ySide = ScreenHeight / 2 gap;IMAGE* imgMap = new IMAGE(ScreenWidth * 4, ScreenHeight * 4);const double PI = 3.1415926;const short nodeSize = 17;const short nodeGap = 16;const short stepLen = 4;const short frame = 4;const short snakeSpecies = 20;int killCount = 0;int mapX = 0;int mapY = 0;typedef struct _FOOD{ int x; int y; int r; COLORREF c;}Food;Food* food;short nFood = 520;IMAGE imgFood(nodeSize, nodeSize);const COLORREF mapMainColor = WHITE;const COLORREF playerColor0 = RGB(120, 0, 0);const COLORREF playerColor1 = RGB(200, 0, 0);const COLORREF playerColor2 = RGB(255, 255, 0);const COLORREF mapLineColor = RGB(225, 225, 225);​​// 透明贴图函数:(更多内容请参考官网)// 参数:// x, y: 目标贴图位置// srcimg: 源 IMAGE 对象指针。null 表示默认窗体// dstimg: 目标 IMAGE 对象指针。NULL 表示默认窗体// transparentcolor: 透明色。srcimg 的该颜色并不会复制到 dstimg 上,从而实现透明贴图void putTimage(int x, int y, IMAGE* srcimg, IMAGE* dstimg = NULL, UINT transparentcolor = 0){ HDC dstDC = GetImageHDC(dstimg); HDC srcDC = GetImageHDC(srcimg); int w = srcimg->getwidth(); int h = srcimg->getheight();​ // 使用 Windows GDI 函数实现透明位图 TransparentBlt(dstDC, x, y, w, h, srcDC, 0, 0, w, h, transparentcolor);}​​////////// 蛇基类 //////////class SnakeBase{public: // 构造函数 SnakeBase() { Count ; isDead = false; length = 50 rand() % 50; nNode = length / 5; maxNode = 9999; imgHead = imgNode = imgTail = nullptr; headNode = tailNode = nullptr; nodeMsg = nullptr; }​ // 析构函数 virtual ~SnakeBase() { Count--; Node* temp = headNode; while (temp != nullptr) { headNode = headNode->nextNode; delete temp; temp = headNode; } delete imgHead, imgNode, imgTail; if (nodeMsg != nullptr) delete[] nodeMsg; }​ // 设置image void SetImage(COLORREF headColor, COLORREF nodeColor, COLORREF tailColor){ imgHead = new IMAGE(nodeSize, nodeSize); imgNode = new IMAGE(nodeSize, nodeSize); imgTail = new IMAGE(nodeSize, nodeSize); SetWorkingImage(imgHead); setfillcolor(headColor); solidcircle(nodeSize / 2, nodeSize / 2, nodeSize / 2); setfillcolor(tailColor); solidcircle(nodeSize / 2, nodeSize / 2, 2); SetWorkingImage(imgNode); setfillcolor(nodeColor); solidcircle(nodeSize / 2, nodeSize / 2, nodeSize / 2); SetWorkingImage(imgTail); setfillcolor(tailColor); solidcircle(nodeSize / 2, nodeSize / 2, nodeSize / 2); SetWorkingImage(); }​ // 创建各节点 void Creat(int headX, int headY){ headNode = new Node; headNode->lastNode = nullptr; headNode->nextNode = nullptr; headNode->x = headX; headNode->y = headY; Node* temp = headNode; for (int i = 0; i lastNode = temp; newNode->x = temp->x; newNode->y = temp->y; temp->nextNode = newNode; temp = newNode; } temp->nextNode = nullptr; tailNode = temp; temp = nullptr; }​ // 绘制蛇身 void ShowBody(){ int n = nNode % 2; Node* temp = tailNode; while (temp != headNode) { if (temp->x - nodeSize / 2 mapX >= nodeSize * -1 && temp->x - nodeSize / 2 mapX y - nodeSize / 2 mapY >= nodeSize / -2 && temp->y - nodeSize / 2 mapY x - nodeSize / 2 mapX, temp->y - nodeSize / 2 mapY, n % 2 == 0 ? imgNode : imgTail); temp = temp->lastNode; n ; } if (temp->x - nodeSize / 2 mapX >= nodeSize * -1 && temp->x - nodeSize / 2 mapX y - nodeSize / 2 mapY >= nodeSize / -2 && temp->y - nodeSize / 2 mapY x - nodeSize / 2 mapX, temp->y - nodeSize / 2 mapY, imgHead); temp = nullptr; }​ // 刷新数据 void FlushData(short& n, int& dx, int& dy){ if (n == frame) { nodeMsg = new POINT[nNode]; Node* temp = headNode; int i = 0; while (temp != nullptr) { nodeMsg[i].x = temp->x; nodeMsg[i].y = temp->y; temp = temp->nextNode; i ; } }​ Node* temp = tailNode; int i = nNode - 2; while (temp != headNode) { if (n == 1) { temp->x = nodeMsg[i].x; temp->y = nodeMsg[i].y; } else { temp->x = int(stepLen * cos(atan2(nodeMsg[i].y - temp->y, nodeMsg[i].x - temp->x))); temp->y = int(stepLen * sin(atan2(nodeMsg[i].y - temp->y, nodeMsg[i].x - temp->x))); } temp = temp->lastNode; i--; } temp = nullptr; headNode->x = dx; headNode->y = dy;​ if (n == 1) { delete[] nodeMsg; nodeMsg = nullptr; } }​ // 据长度添加节点 void SetNode(int ex = 0){ int n = nNode; length = ex; n = length / 5 - n; if (n > 0) { while (nNode lastNode = tailNode; newNode->nextNode = nullptr; newNode->x = tailNode->x; newNode->y = tailNode->y; tailNode->nextNode = newNode; tailNode = newNode; newNode = nullptr; } } else if (n 10 && n != 0) { n ; nNode--; Node* temp = tailNode; tailNode = tailNode->lastNode; tailNode->nextNode = nullptr; delete temp; temp = nullptr; } if (nNode == 10) length = 50; } }​ // 吃到食物 bool GetFood(int k, int x, int y){ int len = nodeGap 5; if (x - headNode->x x - x y y - y getwidth() - xSide * 2) xSide; food[k].y = rand() % (imgMap->getheight() - ySide * 2) ySide; food[k].r = rand() % 2 3; food[k].c = HSVtoRGB(float(rand() % 360), rand() % 1000 / 2000.0f 0.5f, rand() % 1000 / 2000.0f 0.5f); return true; } return false; }​protected: long length; int nNode; int maxNode; IMAGE* imgHead, * imgNode, * imgTail; POINT* nodeMsg;​public: // 蛇节点 typedef struct _NODE { int x; int y; struct _NODE* lastNode; struct _NODE* nextNode; }Node; bool isDead; static int Count; Node* headNode, * tailNode;};int SnakeBase::Count = 0;​​////////// Player 类 //////////class Player :public SnakeBase{public: // 构造函数 Player() :SnakeBase() { SetImage(playerColor0, playerColor1, playerColor2); int headX = rand() % (imgMap->getwidth() - xSide * 2 - nodeSize * 10) xSide nodeSize; int headY = rand() % (imgMap->getheight() - ySide * 2 - nodeSize * 12) ySide nodeSize; Creat(headX, headY); nt = frame; }​ // 是否死亡 void IsDead(){ if (headNode->x x >= imgMap->getwidth() - 1 - xSide || headNode->y y >= imgMap->getheight() - 1 - ySide) isDead = true; else { double radian = atan2(headNode->y - headNode->nextNode->y, headNode->x - headNode->nextNode->x); int x = ScreenWidth / 2 int(nodeSize / 2 * cos(radian)); int y = ScreenHeight / 2 int(nodeSize / 2 * sin(radian)); COLORREF c = getpixel(x, y); if (!(c == mapLineColor || c == mapMainColor)) isDead = true; else { for (int i = 1; i < 8; i ) { x = ScreenWidth / 2 int(nodeSize / 2 * cos(radian)); y = ScreenHeight / 2 int(nodeSize / 2 * sin(radian)); c = getpixel(x, y); if (!(c == mapLineColor || c == mapMainColor)) { isDead = true; break; } x = ScreenWidth / 2 int(nodeSize / 2 * cos(radian)); y = ScreenHeight / 2 int(nodeSize / 2 * sin(radian)); c = getpixel(x, y); if (!(c == mapLineColor || c == mapMainColor)) { isDead = true; break; } } } } }​ // 移动 void Move(int& ex, int& mapX, int& mapY, short& ddx, short& ddy){ int dx = int(stepLen * cos(atan2(ddy, ddx))); int dy = int(stepLen * sin(atan2(ddy, ddx))); mapX -= dx; mapY -= dy; FlushData(nt, dx, dy); for (int k = 0; k < nFood; k ) if (GetFood(k, food[k].x, food[k].y)) ex = food[k].r / 2; nt--; if (nt getwidth() - xSide * 2 - nodeSize * 3) xSide nodeSize; headY = rand() % (imgMap->getheight() - ySide * 2 - nodeSize * 5) ySide nodeSize; } while (IsInPlayer(headX, headY)); Creat(headX, headY); nt = frame; minLine = 3 * frame; curLine = minLine (rand() % 12) * frame; ddx = (rand() % ScreenWidth) * (rand() % 1000 < 500 ? 1 : -1); ddy = (rand() % ScreenHeight) * (rand() % 1000 x x >= imgMap->getwidth() - 1 - xSide || headNode->y y >= imgMap->getheight() - 1 - ySide) return true; else { bool is_dead = IsInPlayer(headNode->x, headNode->y); if (is_dead) { killCount ; ex = nNode; } return is_dead; } }​ // 位置是否接触 player bool IsInPlayer(int headX, int headY){ Node* temp = p->headNode; while (temp != nullptr) { if (headX - temp->x x - headX y y - headY nextNode; } return false; }​ // 移动 void Move(int& ex){ if (curLine <= 0) { double rad = atan2(ddy, ddx); isFast = rand() % 1200 < 100 ? true : false; curLine = minLine (rand() % 21) * frame; do { ddx = (rand() % ScreenWidth 40) * (rand() % 1000 < 500 ? 1 : -1); ddy = (rand() % ScreenHeight 30) * (rand() % 1000 PI / 6 * 5); dx = int(stepLen * cos(atan2(ddy, ddx))); dy = int(stepLen * sin(atan2(ddy, ddx))); } FlushData(nt, dx, dy); for (int k = 0; k < nFood; k ) if (GetFood(k, food[k].x, food[k].y)) exp = food[k].r / 2; nt--; curLine--; if (nt <= 0) { nt = frame; if (rand() % 1000 < 120) { SetNode(rand() % 5 exp); exp = 0; } if (rand() % 1000 < 80) curLine = 0; if (rand() % 1000 0) // 90% 概率避免出界 { int deadX = headNode->x int((rand() % 50 nodeGap) * cos(atan2(ddy, ddx))); int deadY = headNode->y int((rand() % 50 nodeGap) * sin(atan2(ddy, ddx))); if (deadX = imgMap->getwidth() - 1 - xSide) { ddx *= -1; ddy = rand() % 30 30; } if (deadY = imgMap->getheight() - 1 - ySide) { ddy *= -1; ddx = rand() % 40 40; } dx = int(stepLen * cos(atan2(ddy, ddx))); dy = int(stepLen * sin(atan2(ddy, ddx))); } if (rand() % 1000 0) // 40%-80%(也可以理解为60%) 概率躲避 player { int deadX = headNode->x int((nodeGap 5) * cos(atan2(ddy, ddx))); int deadY = headNode->y int((nodeGap 5) * sin(atan2(ddy, ddx))); if (IsInPlayer(deadX, deadY)) { ddx = -1 * ddx rand() % 40 40; ddy = -1 * ddy rand() % 30 30; } dx = int(stepLen * cos(atan2(ddy, ddx))); dy = int(stepLen * sin(atan2(ddy, ddx))); } } isDead = IsDead(ex); if (isDead) { int n = nNode / 2; Node* temp = headNode->nextNode->nextNode; while (n--) { for (int k = 0; k < nFood; k ) { if (food[k].x -1 * mapX nodeSize * 2 ScreenWidth || food[k].y -1 * mapY nodeSize * 2 ScreenHeight) { food[k].x = temp->x (rand() % 5 3) * (rand() % 100 y (rand() % 5 3) * (rand() % 100 nextNode; } temp = nullptr; } }​private: short nt; int minLine; int curLine; int ddx, ddy; int dx, dy; Player* p;​public: bool isFast; clock_t ct; int exp;};​​////////// 游戏主体类 //////////class Game{public: // 构造函数 Game() { flushTime = 32; setbkmode(TRANSPARENT); BeginBatchDraw();​ SetWorkingImage(imgMap); setlinecolor(mapLineColor); setfillcolor(mapMainColor); setbkcolor(BROWN); cleardevice(); solidrectangle(xSide, ySide, imgMap->getwidth() - 1 - xSide, imgMap->getheight() - 1 - ySide); for (int i = gap xSide; i getwidth() - xSide; i = gap) line(i, ySide, i, imgMap->getheight() - 1 - ySide); for (int j = gap ySide; j getheight() - ySide; j = gap) line(xSide, j, imgMap->getwidth() - 1 - xSide, j); SetWorkingImage();​ player = new Player; mapX = -1 * (player->headNode->x - ScreenWidth / 2); mapY = -1 * (player->headNode->y - ScreenHeight / 2);​ ai = new Ai; ai->ais = new AI(player); Ai* temp = ai; for (int i = 1; i next = new Ai; temp = temp->next; temp->ais = new AI(player); } temp->next = ai; temp = nullptr;​ food = new Food[nFood]; for (int k = 0; k getwidth() - xSide * 2) xSide; food[k].y = rand() % (imgMap->getheight() - ySide * 2) ySide; food[k].r = rand() % 2 3; food[k].c = HSVtoRGB(float(rand() % 360), rand() % 1000 / 2000.0f 0.5f, rand() % 1000 / 2000.0f 0.5f); }​ Draw(); outtextxy((ScreenWidth - textwidth(_T("左键或右键加速"))) / 2, ScreenHeight / 4 * 3 25, _T("左键或右键加速")); outtextxy((ScreenWidth - textwidth(_T("按任意键继续"))) / 2, ScreenHeight / 4 * 3 50, _T("按任意键继续")); FlushBatchDraw(); ret = _getwch(); }​ // 析构函数 ~Game() { EndBatchDraw(); delete imgMap; delete player; if (ai != nullptr) { Ai* temp = ai->next; while (temp != ai) { delete temp->ais; temp = temp->next; } delete ai->ais; delete ai; } }​ // 绘制食物 void DrawFood(){ for (int k = 0; k = 0 && food[k].x - 9 mapX = 0 && food[k].y - 9 mapY <= ScreenHeight) { if (food[k].r next; while (temp != ai) { temp->ais->ShowBody(); temp = temp->next; } temp->ais->ShowBody(); player->IsDead(); player->ShowBody(); player->Print(); FlushBatchDraw(); }​ // 运行 void Running(){ short ddx = 0; short ddy = 0; time_t ct = clock() - time_t(100); Ai* temp = ai->next; while (temp != ai) { temp->ais->ct = clock(); temp = temp->next; } temp->ais->ct = clock(); temp = temp->next; int ex = 0; bool isFast = false;​ while (!(GetAsyncKeyState(VK_ESCAPE) & 0x8000) && !player->isDead) { if (GetAsyncKeyState('P') & 0x8000) ret = _getwch(); if (clock() - ct > flushTime) { ct = clock(); isFast = (msg.mkLButton || msg.mkRButton) ? true : false; player->Move(ex, mapX, mapY, ddx, ddy); if (isFast) { player->Move(ex, mapX, mapY, ddx, ddy); if (rand() % 1000 ais->ct > flushTime && !player->isDead) { temp->ais->ct = clock(); temp->ais->Move(ex); if (temp->ais->isDead) { delete temp->ais; temp->ais = new AI(player); temp->ais->ct = clock(); } else if (temp->ais->isFast) { temp->ais->Move(ex); if (temp->ais->isDead) { delete temp->ais; temp->ais = new AI(player); temp->ais->ct = clock(); } } ai = ai->next; temp = temp->next; } } }​private: int flushTime; Player* player; typedef struct _AI { AI* ais; struct _AI* next; }Ai; Ai* ai;};​​////////// 主函数 //////////int main(){ initgraph(ScreenWidth, ScreenHeight); srand((unsigned)time(NULL));​ Game game; game.Running(); settextcolor(BLACK); settextstyle(50, 0, _T("微软雅黑")); outtextxy((ScreenWidth - textwidth(_T("游戏结束"))) / 2, ScreenHeight / 3, _T("游戏结束")); settextstyle(20, 0, _T("微软雅黑")); outtextxy((ScreenWidth - textwidth(_T("按任意键退出"))) / 2, ScreenHeight / 4 * 3 50, _T("按任意键退出")); FlushBatchDraw();​ while (_kbhit()) ret = _getwch(); ret = _getwch(); closegraph(); return 0;}

大家赶紧去动手试试吧!

此外,我也给大家分享我收集的其他资源,从最零基础开始的教程到C语言C 项目案例,帮助大家在学习C语言的道路上披荆斩棘!

编程学习书籍分享:

贪吃蛇大作战下载

编程学习视频分享:

贪吃蛇大作战下载

整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)最重要的是你可以在群里面交流提问编程问题哦!

对于C/C 感兴趣可以关注小编在后台私信我:【编程交流】一起来学习哦!可以领取一些C/C 的项目学习视频资料哦!已经设置好了关键词自动回复,自动领取就好了!

  • 热门资讯
  • 最新资讯
  • 手游排行榜
  • 手游新品榜
  • 软件排行榜
  • 软件新品榜