《球球大做战》是Superpop一款自主研du发的免费手机网络游戏。 以玩家间的实时互动PK产生游戏乐趣为设计宗旨,经过简单的规则将玩家操做直接转化为游戏策略,体验智谋碰撞的战斗乐趣。 算法
游戏的基本操做包括键盘按下(上下左右四个方向,还有做弊测试按键空格键和A键),玩家能够在地图上随意移动,不过不能超出边界。无论是玩家仍是AI均可以吃比本身小的球,反之也能够被吃,吃掉以后直径会增大,增大算法是被吃掉的半径的1/4。若是玩家被吃掉,会在任意地方从新开始。编程
那么今天,咱们就用C语言,来写出咱们的球球大做战,一块儿来看看吧!数组
球球大做战游戏分为几个步骤:微信
①使用自定义空白图片表示地图;②绘制玩家,食物;③处理玩家移动,以及吃食物判断;④绘制一个AI并实现其移动;网络
话很少说,接下来咱们之间来看咱们的代码吧!须要素材以及相关资料源码能够关注微信公众号输入关键词领取,那先来看看代码吧!ide
#include<graphics.h> //包含easyx图形库文件
#include<time.h> //C语言时间头文件
#include<mmsystem.h>//win32多媒体设备接口文件
#pragma comment(lib,"winmm.lib")//win32多媒体设备接口库
#define WIN_WIDTH 1024 //屏幕的宽
#define WIN_HEIGHT 640//576 //屏幕高
#define MAP_WIDTH (WIN_WIDTH*3) //地图宽度
#define MAP_HEIGHT (WIN_HEIGHT*3)//地图高度
#define FOOD_NUM 500 //食物数量
#define AI_NUM 200 //ai数量 IMAGE map(MAP_WIDTH, MAP_HEIGHT); POINT g_CameraPos; // 摄像机(屏幕左上角)在地图上的位置
struct Ball { bool flag; // 是否被吃 活 1,死 0
COLORREF color; // 颜色
float r; // float x; // 坐标
float y; int type; //食物独有属性,决定是什么类型的食物(圆?矩形?多边形?)
}; struct Ball mover; //玩家
struct Ball food[FOOD_NUM]; //食物数组
struct Ball ai[AI_NUM]; //AI数量
void ChaseAlgorithom(Ball *chase, Ball *run); float DisTance(Ball b1, Ball b2); void Gameinit() { //设置随机数种子
srand((unsigned)time(NULL)); //播放背景音乐
mciSendString("open BallGame.mp3 alias bk", 0, 0, 0); mciSendString("play bk repeat", 0, 0, 0); //初始化食物
for (int i = 0; i < FOOD_NUM; i++) { food[i].x = (float)(rand() % MAP_WIDTH); food[i].y = (float)(rand() % MAP_HEIGHT); food[i].r = (float)(rand() % 5 + 1); food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256); // 随机颜色
food[i].flag = 1; food[i].type = rand() % 3; } //初始化AI
for (int i = 0; i < AI_NUM; i++) { ai[i].color = RGB(rand() % 256, rand() % 256, rand() % 256); //rand()%256 随机取值 0-255
ai[i].flag = 1; ai[i].x = rand() % (MAP_WIDTH - int(ai[i].r + 0.5)) + int(ai[i].r + 0.5); //AI产生的位置不会出现一个越界
ai[i].y = rand() % (MAP_HEIGHT - int(ai[i].r + 0.5)) + int(ai[i].r + 0.5); ai[i].r = float(rand() % 10 + 10); } {//初始化玩家数据
mover.color = BLUE; mover.r = 10; //玩家在窗口的位置
mover.x = rand() % WIN_WIDTH; mover.y = rand() % WIN_HEIGHT; mover.flag = 1; } } //游戏地图开始绘制位置判断
void computeCameraPos() { // 以人物位置为中心计算摄像机的理论位置
g_CameraPos.x = mover.x - WIN_WIDTH / 2; g_CameraPos.y = mover.y - WIN_HEIGHT / 2; // 防止摄像机越界
if (g_CameraPos.x < 0) g_CameraPos.x = 0; if (g_CameraPos.y < 0) g_CameraPos.y = 0; if (g_CameraPos.x > MAP_WIDTH - WIN_WIDTH) g_CameraPos.x = MAP_WIDTH - WIN_WIDTH; if (g_CameraPos.y > MAP_HEIGHT - WIN_HEIGHT) g_CameraPos.y = MAP_HEIGHT - WIN_HEIGHT; } //游戏绘制
void Gamedraw() { SetWorkingImage(&map); setbkcolor(WHITE); // 白色背景
cleardevice(); //画食物
for (int i = 0; i < FOOD_NUM; i++) { if (food[i].flag == 1) { setfillcolor(food[i].color); if (food[i].type == 0) { solidellipse((int)food[i].x, (int)food[i].y, (int)(food[i].x + food[i].r), (int)(food[i].y + food[i].r)); } else if (food[i].type == 1) { solidpie((int)food[i].x, (int)food[i].y, (int)(food[i].x + food[i].r), (int)(food[i].y + food[i].r), 0.0, 1.5); } else { solidcircle(int(food[i].x), int(food[i].y), int(food[i].r)); } } else { food[i].x = (float)(rand() % MAP_WIDTH); food[i].y = (float)(rand() % MAP_HEIGHT); food[i].r = (float)(rand() % 5 + 1); food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256); // 随机颜色
food[i].flag = 1; food[i].type = rand() % 3; } } //画AI
for (int i = 0; i < AI_NUM; i++) { if (ai[i].flag == 1) { setfillcolor(ai[i].color); solidcircle(ai[i].x, ai[i].y, ai[i].r); } else { ai[i].color = RGB(rand() % 256, rand() % 256, rand() % 256); //rand()%256 随机取值 0-255
ai[i].flag = 1; ai[i].x = rand() % (MAP_WIDTH - int(ai[i].r + 0.5)) + int(ai[i].r + 0.5); //AI产生的位置不会出现一个越界
ai[i].y = rand() % (MAP_HEIGHT - int(ai[i].r + 0.5)) + int(ai[i].r + 0.5); ai[i].r = float(rand() % 10 + 10); } } //绘制玩家
setfillcolor(RED); fillcircle(mover.x, mover.y, mover.r); //绘制玩家名称
settextcolor(BLACK); setbkmode(TRANSPARENT); settextstyle(20, 0, "楷体"); char pname[] = "微信公众号:C语言编程学习基地"; int twidth = textwidth(pname) / 2;//计算文字宽度为了居中显示在玩家中央
outtextxy(mover.x - twidth, mover.y, pname); //恢复默认工做区,即窗口
SetWorkingImage(); //更新摄像机位置
computeCameraPos(); //把地图显示到窗口上
putimage(0, 0, WIN_WIDTH, WIN_HEIGHT, &map, g_CameraPos.x, g_CameraPos.y); } //玩家移动,参数为玩家移动的速度(单位像素)
void Gamemove(int speed) { //获取键盘按键
if (GetAsyncKeyState(VK_UP) & 0x8000) { if (mover.y - mover.r > 0) { mover.y -= speed; } } if (GetAsyncKeyState(VK_DOWN) & 0x8000) { if (mover.y + mover.r < MAP_HEIGHT) { mover.y += speed; } } if (GetAsyncKeyState(VK_LEFT) & 0x8000) { if (mover.x - mover.r > 0) { mover.x -= speed; } } if (GetAsyncKeyState(VK_RIGHT) & 0x8000) { if (mover.x + mover.r < MAP_WIDTH) { mover.x += speed; } } //做弊测试,按空格不断增大,A缩小
if (GetAsyncKeyState(VK_SPACE) & 0x8000) { mover.r += 3; } if (GetAsyncKeyState('A') & 0x8000) { if (mover.r > 1) mover.r -= 1; } } //玩家吃食物
void EatFood() { for (int i = 0; i < FOOD_NUM; i++) { if (food[i].flag == 1 && DisTance(food[i], mover) < mover.r) { food[i].flag = 0; mover.r += food[i].r / 4; } } } //玩家吃Ai,Ai吃玩家
void EatAi() { for (int i = 0; i < AI_NUM; i++) { if (ai[i].flag == 0) continue; //玩家吃Ai
if (DisTance(ai[i], mover) < mover.r - ai[i].r / 3) { ai[i].flag = 0; mover.r += ai[i].r / 4; break;//吃到一个就退出
} //ai吃玩家
else if (DisTance(ai[i], mover) < ai[i].r - mover.r / 3) { mover.x = rand() % MAP_WIDTH; mover.y = rand() % MAP_HEIGHT; ai[i].r += mover.r / 4; mover.r = 10; break; } } } //AI吃食物,AI吃Ai
void AiEatFood() { for (int i = 0; i < AI_NUM; i++) { if (ai[i].flag == 0) continue; //ai吃食物
for (int j = 0; j < FOOD_NUM; j++) { if (food[j].flag == 1 && DisTance(ai[i], food[j]) < ai[i].r) { food[j].flag = 0; ai[i].r += food[i].r / 4; } } //Ai吃Ai
for (int k = i + 1; k < AI_NUM; k++) { if (ai[k].flag == 1) { if (DisTance(ai[i], ai[k]) < ai[k].r - ai[i].r / 3) { ai[i].flag = 0; ai[k].r += ai[i].r / 4; } else if (DisTance(ai[i], ai[k]) < ai[i].r - ai[k].r / 3) { ai[k].flag = 0; ai[i].r += ai[k].r / 4; } } } } } //Ai移动算法,追逐比本身半径小的球
void AiMove() { for (int i = 0; i < AI_NUM; i++) { double min_DISTANCE = MAP_WIDTH;//最大搜索距离
int min = -1;//用来保存找到目标小球的下标
if (ai[i].flag == 1) { //AI靠近AI
for (int k = i + 1; k < AI_NUM; k++) { if (ai[i].r > ai[k].r&&ai[k].flag == 1) {//若是能吃,且距离达到要求则更新距离,并保存下标
if (DisTance(ai[i], ai[k]) < min_DISTANCE) { min_DISTANCE = DisTance(ai[i], ai[k]); min = k; } } } } //若是找到目标,则去追逐
if ((min != -1)) { ChaseAlgorithom(&ai[i], &ai[min]); } } } void JudeEat() { EatFood(); EatAi(); AiEatFood(); AiMove(); } int main() { initgraph(WIN_WIDTH, WIN_HEIGHT, 1); Gameinit(); DWORD t1, t2; t1 = t2 = GetTickCount(); while (1) { Gamedraw(); Gamemove(1); if (t2 - t1 > 50) { JudeEat(); t1 = t2; } t2 = GetTickCount(); } getchar(); closegraph(); return 0; } //追逐算法
void ChaseAlgorithom(Ball *chase, Ball *run) { if (rand() % 2 == 0) { if (chase->x < run->x) { chase->x += 2; } else { chase->x -= 2; } } else { if (chase->y < run->y) { chase->y += 2; } else { chase->y -= 2; } } } //求两点之间的距离
float DisTance(Ball b1, Ball b2) { return sqrt((b1.x - b2.x)*(b1.x - b2.x) + (b1.y - b2.y)*(b1.y - b2.y)); }
以上就是本篇文章的所有分享,但愿对你们有帮助!学习
自学C/C++编程难度很大,不妨和一些志同道合的小伙伴一块儿学习成长!测试
C语言C++编程学习交流圈子,【点击进入】微信公众号:C语言编程学习基地spa
有一些源码和资料分享,欢迎转行也学习编程的伙伴,和你们一块儿交流成长会比本身琢磨更快哦!设计