原文:https://www.bbsmax.com/A/kvJ3qEVpdg/
#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", , , ); mciSendString("play bk repeat", , , ); //初始化食物 for (int i = ; i < FOOD_NUM; i++) { food[i].x = (float)(rand() % MAP_WIDTH); food[i].y = (float)(rand() % MAP_HEIGHT); food[i].r = (float)(rand() % + ); food[i].color = RGB(rand() % , rand() % , rand() % ); // 随机颜色 food[i].flag = ; food[i].type = rand() % ; } //初始化AI for (int i = ; i < AI_NUM; i++) { ai[i].color = RGB(rand() % , rand() % , rand() % ); //rand()%256 随机取值 0-255 ai[i].flag = ; 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() % + ); } {//初始化玩家数据 mover.color = BLUE; mover.r = ; //玩家在窗口的位置 mover.x = rand() % WIN_WIDTH; mover.y = rand() % WIN_HEIGHT; mover.flag = ; } } //游戏地图开始绘制位置判断 void computeCameraPos() { // 以人物位置为中心计算摄像机的理论位置 g_CameraPos.x = mover.x - WIN_WIDTH / ; g_CameraPos.y = mover.y - WIN_HEIGHT / ; // 防止摄像机越界 if (g_CameraPos.x < ) g_CameraPos.x = ; if (g_CameraPos.y < ) g_CameraPos.y = ; 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 = ; i < FOOD_NUM; i++) { if (food[i].flag == ) { setfillcolor(food[i].color); if (food[i].type == ) { 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 == ) { 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() % + ); food[i].color = RGB(rand() % , rand() % , rand() % ); // 随机颜色 food[i].flag = ; food[i].type = rand() % ; } } //画AI for (int i = ; i < AI_NUM; i++) { if (ai[i].flag == ) { setfillcolor(ai[i].color); solidcircle(ai[i].x, ai[i].y, ai[i].r); } else { ai[i].color = RGB(rand() % , rand() % , rand() % ); //rand()%256 随机取值 0-255 ai[i].flag = ; 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() % + ); } } //绘制玩家 setfillcolor(RED); fillcircle(mover.x, mover.y, mover.r); //绘制玩家名称 settextcolor(BLACK); setbkmode(TRANSPARENT); settextstyle(, , "楷体"); char pname[] = "微信公众号:C语言编程学习基地"; int twidth = textwidth(pname) / ;//计算文字宽度为了居中显示在玩家中央 outtextxy(mover.x - twidth, mover.y, pname); //恢复默认工作区,即窗口 SetWorkingImage(); //更新摄像机位置 computeCameraPos(); //把地图显示到窗口上 putimage(, , 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 > ) { 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 > ) { 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 += ; } if (GetAsyncKeyState('A') & 0x8000) { if (mover.r > ) mover.r -= ; } } //玩家吃食物 void EatFood() { for (int i = ; i < FOOD_NUM; i++) { if (food[i].flag == && DisTance(food[i], mover) < mover.r) { food[i].flag = ; mover.r += food[i].r / ; } } } //玩家吃Ai,Ai吃玩家 void EatAi() { for (int i = ; i < AI_NUM; i++) { if (ai[i].flag == ) continue; //玩家吃Ai if (DisTance(ai[i], mover) < mover.r - ai[i].r / ) { ai[i].flag = ; mover.r += ai[i].r / ; break;//吃到一个就退出 } //ai吃玩家 else if (DisTance(ai[i], mover) < ai[i].r - mover.r / ) { mover.x = rand() % MAP_WIDTH; mover.y = rand() % MAP_HEIGHT; ai[i].r += mover.r / ; mover.r = ; break; } } } //AI吃食物,AI吃Ai void AiEatFood() { for (int i = ; i < AI_NUM; i++) { if (ai[i].flag == ) continue; //ai吃食物 for (int j = ; j < FOOD_NUM; j++) { if (food[j].flag == && DisTance(ai[i], food[j]) < ai[i].r) { food[j].flag = ; ai[i].r += food[i].r / ; } } //Ai吃Ai for (int k = i + ; k < AI_NUM; k++) { if (ai[k].flag == ) { if (DisTance(ai[i], ai[k]) < ai[k].r - ai[i].r / ) { ai[i].flag = ; ai[k].r += ai[i].r / ; } else if (DisTance(ai[i], ai[k]) < ai[i].r - ai[k].r / ) { ai[k].flag = ; ai[i].r += ai[k].r / ; } } } } } //Ai移动算法,追逐比自己半径小的球 void AiMove() { for (int i = ; i < AI_NUM; i++) { double min_DISTANCE = MAP_WIDTH;//最大搜索距离 int min = -;//用来保存找到目标小球的下标 if (ai[i].flag == ) { //AI靠近AI for (int k = i + ; k < AI_NUM; k++) { if (ai[i].r > ai[k].r&&ai[k].flag == ) {//如果能吃,且距离达到要求则更新距离,并保存下标 if (DisTance(ai[i], ai[k]) < min_DISTANCE) { min_DISTANCE = DisTance(ai[i], ai[k]); min = k; } } } } //如果找到目标,则去追逐 if ((min != -)) { ChaseAlgorithom(&ai[i], &ai[min]); } } } void JudeEat() { EatFood(); EatAi(); AiEatFood(); AiMove(); } int main() { initgraph(WIN_WIDTH, WIN_HEIGHT, ); Gameinit(); DWORD t1, t2; t1 = t2 = GetTickCount(); while () { Gamedraw(); Gamemove(); if (t2 - t1 > ) { JudeEat(); t1 = t2; } t2 = GetTickCount(); } getchar(); closegraph(); return ; } //追逐算法 void ChaseAlgorithom(Ball *chase, Ball *run) { if (rand() % == ) { if (chase->x < run->x) { chase->x += ; } else { chase->x -= ; } } else { if (chase->y < run->y) { chase->y += ; } else { chase->y -= ; } } } //求两点之间的距离 float DisTance(Ball b1, Ball b2) { return sqrt((b1.x - b2.x)*(b1.x - b2.x) + (b1.y - b2.y)*(b1.y - b2.y)); }