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

基于EasyX库开发的球球大作战游戏

目录

球球大作战

一、开发环境

二、流程图预览

三、代码逻辑

1、初始化时间

2、设置开始界面大小

3、设置开始界面

4、让玩家选择速度

5、设置玩家小球、人机小球、食物的属性

6、一次性把图绘制到界面里

7、进入死循环

8、移动玩家小球

9、移动人机

10、食物刷新

11、画出边界、食物、人机、玩家、小地图,添加击杀数、半径(质量)、玩家名字

12、将内存中的绘图操作批量地绘制到屏幕上,从而提高绘图效率

四、代码预览+运行结果


球球大作战

一、开发环境

VisualStudio专业版:

所需依赖库:EasyX库

二、流程图预览

由于上面的比较模糊,下面分开截取流程图图片

三、代码逻辑

1、初始化时间

starttime();

2、设置开始界面大小

initgraph(WIDTH, HEIGHT);

3、设置开始界面

void start() {setbkcolor(WHITE);                          // 白色背景cleardevice();                              // 初始化背景settextcolor(BLACK);                            // 改字体setbkmode(TRANSPARENT);                 //设置背景是透明的//加载背景图片IMAGE image;loadimage(&image, _T("D:\\桌面\\file2\\球球大作战\\source\\Ball Ball\\x64\\img\\10.jpg"), WIDTH, HEIGHT);//在当前设备上绘制指定图像putimage(0, 0, &image);//加入提示信息settextcolor(WHITE);settextstyle(22, 0, _T("黑体"));outtextxy(50, 480, _T("请选择关卡:"));outtextxy(50, 550, _T("1.小试牛刀"));outtextxy(200, 550, _T("2.炉火纯青"));outtextxy(350, 550, _T("3.登峰造极"));settextstyle(15, 0, _T("宋体"));outtextxy(600, 550, _T("注:按序号选择,默认选择关卡1;游戏中按空格键可以暂停。"));settextcolor(BLACK);settextstyle(22, 0, _T("黑体"));TCHAR s[5];//_stprintf(s, _T("%d"), readCount());_stprintf_s(s, _countof(s), _T("%d"), readCount());outtextxy(810, 200, _T("欢迎进入游戏!"));outtextxy(810, 240, _T("游戏次数:"));outtextxy(910, 240, s);
}

4、让玩家选择速度

void ChooseSpeed() {switch (_getch()) {case 1:speed = 4;case 2:speed = 3;case 3:speed = 2;default:speed = 4;}
}

5、设置玩家小球、人机小球、食物的属性

void setall() {srand((unsigned)time(NULL));                    // 随机数mover.color = RGB(rand() % 256, rand() % 256, rand() % 256);        // 随机颜色mover.life = 1;                             // 赋初值1//把玩家的球一直放在屏幕中央mover.x = int(WIDTH * 0.5);mover.y = int(HEIGHT * 0.5);//设置半径mover.r = 20;
​for (int i = 0; i < AINUM; i++) {               // AI 的属性ai[i].life = 1;ai[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);//ai[i].r = float(rand() % 10 + 10);ai[i].r = 20;ai[i].x = rand() % (MAPW - int(ai[i].r + 0.5)) + int(ai[i].r + 0.5);ai[i].y = rand() % (MAPH - int(ai[i].r + 0.5)) + int(ai[i].r + 0.5);}
​for (int i = 0; i < FNUM; i++) {                // 食物的属性food[i].eat = 1;food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);food[i].x = rand() % MAPW;food[i].y = rand() % MAPH;food[i].type = rand() % 10 + 1;}
​pBuffer = GetImageBuffer(NULL);                 // 获取显存指针setbkcolor(WHITE);                          // 白色背景cleardevice();                              // 初始化背景settextcolor(LIGHTRED);                     // 改字体//设置背景是透明的setbkmode(TRANSPARENT);settextstyle(16, 0, _T("宋体"));
​
}

6、一次性把图绘制到界面里

BeginBatchDraw();

7、进入死循环

8、移动玩家小球

void move(BALL* ball) {if (ball->r <= 0)ball->life = false;if (ball->life == false) {                      // 判定游戏是否接束HWND hwnd = GetHWnd();MessageBox(hwnd, _T("你被吃了"), _T("游戏结束"), MB_ICONEXCLAMATION);endtime();
​}
​if (eaten + ai_eaten == AINUM)                  // 是否吃掉所有 AI{HWND hwnd = GetHWnd();MessageBox(hwnd, _T("恭喜过关"), _T("游戏结束"), MB_OK | MB_ICONEXCLAMATION);   // 结束endtime();}
​for (int i = 0; i < AINUM; i++) {               // 玩家吃 AI 判定if (ball->r >= ai[i].r) {if (ai[i].life == 0)    continue;if (DISTANCE(ball->x, ball->y, ai[i].x, ai[i].y) < (4 / 5.0 * (ball->r + ai[i].r))) {ai[i].life = 0;                 //AI被吃ball->r = sqrt(ai[i].r * ai[i].r + ball->r * ball->r);eaten++;}}}
​for (int n = 0; n < FNUM; n++) {                // 玩家吃食物if (food[n].eat == 0)   continue;if (DISTANCE(ball->x, ball->y, food[n].x, food[n].y) < ball->r) {ball->r += 4 / ball->r;             // 增加面积food[n].eat = 0;                        // 食物被吃}}
​static int mx = 0, my = 0;                      // 记录偏移量
​//判断怎么移动if (GetAsyncKeyState(VK_UP) && (ball->y - ball->r > 0 && ball->y <= (MAPH - ball->r + 10))) {ball->y -= speed;my += speed;}if (GetAsyncKeyState(VK_DOWN) && (ball->y - ball->r >= -10 && ball->y < (MAPH - ball->r))) {ball->y += speed;my -= speed;}if (GetAsyncKeyState(VK_LEFT) && ball->x - ball->r > 0 && (ball->x <= (MAPW - ball->r + 10))) {ball->x -= speed;mx += speed;}if (GetAsyncKeyState(VK_RIGHT) && ball->x - ball->r >= -10 && (ball->x < (MAPW - ball->r))) {ball->x += speed;mx -= speed;}
​//判断是否输入其他用于退出、暂停、继续的按键if (GetAsyncKeyState(VK_SPACE)) {settextcolor(WHITE);settextstyle(32, 0, _T("宋体"));outtextxy(384 - mx, 350 - my, _T("游戏已暂停!"));outtextxy(20 - mx, 500 - my, _T("(ESC)退出"));outtextxy(780 - mx, 500 - my, _T("(回车键)继续"));FlushBatchDraw();_getch();if (GetAsyncKeyState(VK_ESCAPE))exit(0);else_getch();}
​setorigin(mx, my);                          //坐标修正
}

9、移动人机

void AI() {for (int i = 0; i < AINUM; i++) {               // AI 吃玩家if (ai[i].r > mover.r) {if (DISTANCE(mover.x, mover.y, ai[i].x, ai[i].y) < (ai[i].r + mover.r)) {ai[i].r = sqrt(ai[i].r * ai[i].r + mover.r * mover.r);mover.life = 0;mover.r = 0;}}for (int j = 0; j < AINUM; j++) {           // AI 吃 AIif (ai[i].r > ai[j].r) {if (ai[j].life == 0) continue;if (DISTANCE(ai[i].x, ai[i].y, ai[j].x, ai[j].y) < (ai[i].r + ai[j].r)) {ai[i].r = sqrt(ai[i].r * ai[i].r + ai[j].r * ai[j].r);ai[j].life = 0;ai[j].r = 0;ai_eaten++;}}}
​double min_DISTANCE = 100000;int min = -1;for (int k = 0; k < AINUM; k++) {           // AI 靠近 AIif (ai[i].r > ai[k].r && ai[k].life != 0) {if (DISTANCE(ai[i].x, ai[i].y, ai[k].x, ai[k].y) < min_DISTANCE) {min_DISTANCE = DISTANCE(ai[i].x, ai[i].y, ai[k].x, ai[k].y);min = k;}}}if ((min != -1) && (rand() % 2 == 1) && (ai[i].y - ai[i].r > 0 && ai[i].y <= (MAPH - ai[i].r + 10))) {if (rand() % 2) {if (ai[i].x < ai[min].x)ai[i].x += speed ;elseai[i].x -= speed ;}else {if (ai[i].y < ai[min].y)ai[i].y += speed ;elseai[i].y += speed ;}}for (int n = 0; n < FNUM; n++) {            // AI 吃食物if (food[n].eat == 0) continue;if (DISTANCE(ai[i].x, ai[i].y, food[n].x, food[n].y) < ai[i].r) {ai[i].r += 4 / ai[i].r;food[n].eat = 0;}}}
}

10、食物刷新

void Food() {for (int i = 0; i < FNUM; i++) {				// 食物刷新if (food[i].eat == 0) {food[i].eat = 1;food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);food[i].x = rand() % MAPW;food[i].y = rand() % MAPH;food[i].type = rand() % 10 + 1;}}
}

11、画出边界、食物、人机、玩家、小地图,添加击杀数、半径(质量)、玩家名字

void draw() {float asp = 1;//清空裁剪区,超出区域的绘图操作将被裁剪掉clearcliprgn();IMAGE image;loadimage(&image, _T(""), WIDTH * 4, HEIGHT * 4);putimage(0, 0, &image);//绘画出一个矩形框setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 20);		// 改变笔的颜色、状态setlinecolor(RGB(0, 100, 0));line(-20, MAPH + 20, -20, -20);				// 左竖line(-20, MAPH + 20, MAPW + 20, MAPH + 20);		// 上横line(-20, -20, MAPW + 20, -20);				// 下横line(MAPW + 20, -20, MAPW + 20, MAPH + 20);		// 右竖setfillcolor(GREEN);//当球接近边界时,会在边界外侧绘制一个绿色的填充矩形,// 是用来表示碰撞或者边界的视觉效果if (mover.x - 0.5 * WIDTH / asp < -20)floodfill(-20 - 11, mover.y, RGB(0, 100, 0));if (mover.x + 0.5 * WIDTH / asp > MAPW + 20)floodfill(MAPW + 20 + 11, mover.y, RGB(0, 100, 0));if (mover.y - 0.5 * HEIGHT / asp < -20)floodfill(mover.x, -20 - 11, RGB(0, 100, 0));if (mover.y + 0.5 * HEIGHT / asp > MAPH + 20)floodfill(mover.x, MAPH + 20 + 11, RGB(0, 100, 0));setlinecolor(WHITE);setlinestyle(PS_NULL);for (int i = 0; i < FNUM; i++) {				// 画出食物if (food[i].eat == 0) continue;setfillcolor(food[i].color);switch (food[i].type) {					// 形状case 1:		solidellipse(food[i].x, food[i].y, food[i].x + 2, food[i].y + 4); break;case 2:		solidellipse(food[i].x, food[i].y, food[i].x + 4, food[i].y + 2);	break;case 3:		solidrectangle(food[i].x, food[i].y, food[i].x + 4, food[i].y + 2); break;case 4:		solidrectangle(food[i].x, food[i].y, food[i].x + 2, food[i].y + 4); break;case 5:		solidroundrect(food[i].x, food[i].y, food[i].x + 2, food[i].y + 4, 2, 2); break;case 6:		solidroundrect(food[i].x, food[i].y, food[i].x + 4, food[i].y + 2, 2, 2); break;case 7:		solidroundrect(food[i].x, food[i].y, food[i].x + 4, food[i].y + 2, 4, 2); break;case 8:		solidroundrect(food[i].x, food[i].y, food[i].x + 4, food[i].y + 2, 2, 4); break;case 9:		solidroundrect(food[i].x, food[i].y, food[i].x + 4, food[i].y + 2, 1, 1); break;case 10:	fillcircle(food[i].x, food[i].y, 4); break;}}for (int i = 0; i < AINUM; i++) {				// 画 AIif (ai[i].life == 0) continue;setfillcolor(ai[i].color);//绘圆fillcircle(ai[i].x, ai[i].y, int(ai[i].r + 0.5));}setfillcolor(mover.color);						// 画玩家fillcircle(mover.x, mover.y, int(mover.r + 0.5));IMAGE map(150, 100);							// 小地图SetWorkingImage(&map);setbkcolor(RGB(120, 165, 209));					// 浅灰色背景cleardevice();for (int i = 0; i < AINUM; i++)				// 画 AI(小地图){if (ai[i].life == 0) continue;setfillcolor(ai[i].color);fillcircle(ai[i].x * 150 / WIDTH / 4, ai[i].y * 100 / HEIGHT / 4, int(ai[i].r / 28 + 1.5));}setfillcolor(mover.color);						// 画玩家(小地图)fillcircle(mover.x * 150 / WIDTH / 4, mover.y * 100 / HEIGHT / 4, int(mover.r / 28 + 3.5));setlinecolor(RGB(0, 100, 0));SetWorkingImage();							// 恢复绘图背景putimage(mover.x + int(0.5 * WIDTH) - 150, mover.y - int(0.5 * HEIGHT), 150, 100, &map, 0, 0);						// 画出小地图setlinecolor(LIGHTBLUE);setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 4);line(mover.x + int(0.5 * WIDTH) - 151, mover.y - int(0.5 * HEIGHT), mover.x + int(0.5 * WIDTH) - 151, mover.y - int(0.5 * HEIGHT) + 99);	// 地图边框线line(mover.x + int(0.5 * WIDTH) - 151, mover.y - int(0.5 * HEIGHT) + 99, mover.x + int(0.5 * WIDTH), mover.y - int(0.5 * HEIGHT) + 99);	// 地图边框线setlinestyle(PS_NULL);							// 恢复笔TCHAR str[32];swprintf_s(str, _T("质量:%.1fg  击杀:%d"), mover.r, eaten);settextcolor(WHITE);							// 改字体outtextxy(mover.x - int(0.5 * WIDTH), mover.y - int(0.5 * HEIGHT), str);settextcolor(WHITE);outtextxy(mover.x - 20, mover.y, _T("itlsl"));
}

12、将内存中的绘图操作批量地绘制到屏幕上,从而提高绘图效率

FlushBatchDraw();

四、代码预览+运行结果

源代码+流程图+README资源:https://download.csdn.net/download/2403_82436914/90623088?spm=1001.2014.3001.5503

相关文章:

  • 银河麒麟(Kylin) - V10 SP1桌面操作系统ARM64编译QT-5.15.12版本
  • 2025年国企社招欧治链金再生资源入职测评笔试中智赛码平台SHL测试平台Verify认知能力测试
  • linux-设置每次ssh登录服务器的时候提醒多久需要修改密码
  • MCP调用示例-GitHub仓库操作
  • c++解决动态规划
  • 【16】数据结构之基于树的排序算法篇章
  • 行业深度:金融数据治理中的 SQL2API 应用创新
  • Google政策大更新:影响金融,新闻,社交等所有类别App
  • 亚远景-自动驾驶时代,ASPICE评估标准将如何演进?
  • 【GIT】放弃”本地更改,恢复到远程仓库的状态git fetch origin git reset --hard origin/分支名
  • 【安卓15】分析录屏应用与原生投放和屏幕共享的联系,停止共享后录屏结束
  • D3路网图技术文档
  • 第三篇:深入 Framer Motion Variants:掌握组件动画编排的艺术
  • 基于单片机的出租车计价系统
  • 驱动-兼容不同设备-container_of
  • GPU服务器声音很响可以怎么处理
  • STM32 HAL库之WDG示例代码
  • Python使用FastMCP开发MCP服务端
  • 构建批量论文格式修改系统:从内容识别到自动化处理
  • 【ARM】MDK烧录提示Error:failed to execute‘ ‘
  • 鄂湘赣“中三角”,能否走向文旅C位?
  • 气温“过山车”现象未来或更频繁且更剧烈
  • 俄联邦安全局:俄军高级官员汽车爆炸案嫌疑人已被捕
  • 饶权已任国家文物局局长
  • 蚂蚁财富28亿港元要约收购耀才证券,筹谋香港券商牌照
  • 邮轮、无人机、水上运动……上海多区推动文旅商体展融合发展