windows游戏编程:球球大作战(吃鸡版)源码

源码介绍https://blog.csdn.net/alzzw/article/details/100043938

#include "stdafx.h"是win32程序系统生成的

创建项目时选择win32程序项目

除了下面代码外,无其他改动


#include "stdafx.h"
#include <SDKDDKVer.h>
#include <graphics.h>   //图形库界面   自己安装的库文件 
#include <conio.h>
#include <stdio.h>
#include <tchar.h>
#include <time.h>
#include <math.h>

#define WIDTH  1024  //屏幕的宽
#define HEIGHT 576   //屏幕高
#define MAPW  (WIDTH*4)
#define MAPH (HEIGHT*4)
#define AINUM 200     //AI数量
#define FNUM 2000	//食物数量
#define DISTANCE(x1,y1,x2,y2)  (sqrt((float)(x1-x2)*(float)(x1-x2)+(float)(y1-y2)*(float)(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 };
DWORD *pBuffer;  //显存指针
//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 eaten = 0;  //玩家吃AI的数量
int ai_eaten = 0;   //AI吃AI的数量


/*
一款游戏最基本的要求是什么?
1.界面
2.数据初始化
3.更改其中的数据
4.判断数据是否达到一个临界点
5.退出游戏
*/

void start();
void setall();
void  move(BALL* ball);   //如果实参传入的是地址 形参必定是一个指针变量
void draw();
void AI();


int _tmain(int argc, _TCHAR* argv[])
{
	initgraph(WIDTH, HEIGHT);
	//游戏的初始化
	start();
	setall();   //初始化所有数据

	BeginBatchDraw();
	while (true)
	{
		move(&mover);
		draw();
		AI();
		FlushBatchDraw();
		Sleep(10);
	}



	return 0;
}
//AI的位置是否固定  食物的位置又是否固定   随机出现在任何一个位置的
void setall()
{
	srand((unsigned int)time(NULL));  //随机函数种子
	mover.color = RGB(rand() % 256, rand() % 256, rand() % 256);   //rand()%256  随机取值 0-255
	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[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);   //rand()%256  随机取值 0-255
		ai[i].life= 1;
		ai[i].x = rand() % (MAPW - int(ai[i].r + 0.5)) + int(ai[i].r + 0.5);   //AI产生的位置不会出现一个越界
		ai[i].y = rand() % (MAPH - int(ai[i].r + 0.5)) + int(ai[i].r + 0.5);
		ai[i].r = float(rand()%10+10);
	}
	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, "宋体");
}



void start()
{
	setbkcolor(WHITE);
	cleardevice();
	settextcolor(RED);   //函数   设置文字颜色
	setbkmode(TRANSPARENT);    //设置窗口透明
	settextstyle(128, 0, "宋体");   //字符集问题
	outtextxy(100, 40, "球球大作战");
	settextstyle(32, 0, "宋体");
	outtextxy(384, 500, "按任意键开始游戏");
	getch();
}


void  move(BALL* ball)
{
	if (ball->r <= 0)  ball->life = false;   //false 0  true 1

	if (ball->life == false)
	{
		HWND hwnd = GetHWnd();   //获取窗口句柄
		MessageBox(hwnd, "你已经死亡", "游戏结束", 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;

	//玩家吃AI
	for (int i = 0; i < AINUM; i++)
	{
		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 += (ai[i].r*ai[i].r / 2) / ball->r;
				eaten++;
			}
		}
	}
	//食物被吃
	for (int n = 0; n < FNUM; n++)
	{
		if (food[n].eat == 0) continue;
		if (DISTANCE((float)ball->x, (float)ball->y, (float)food[n].x, (float)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 -= 3, mx += 3; }   //获取键盘的值
	if (GetAsyncKeyState(87) & 0x8000)  { ball->y -= 3, my += 3; }
	if (GetAsyncKeyState(83) & 0x8000)  { ball->y += 3, my-= 3; }
	if (GetAsyncKeyState(68) & 0x8000)  { ball->x += 3, mx -= 3; }
	/*awsd*/
	setorigin(mx, my);   //坐标修正
}


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;
		}
	}
	//画出AI
	for (int i = 0; i < AINUM; i++)
	{
		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++)
	{
		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));

	SetWorkingImage();  //恢复之前的绘图界面
	putimage(mover.x + int(0.5*WIDTH) - 150, mover.y - int(0.5*HEIGHT), 150, 100, &map, 0, 0);


}


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) < 2 / 3.0*ai[i].r + mover.r)
			{
				ai[i].r += (mover.r*mover.r) / ai[i].r;
				mover.life = 0;
				mover.r = 0;
			}
		}
		//AI吃AI
		for (int j = 0; j < AINUM;j++)
		{
			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_eaten++;
				}
			}
		}

		double min_DISTANCE = 100000;
		int min = -1;
		//AI靠近AI
		for (int k = 0; k < AINUM; k++)
		{
			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 += 2;
				else ai[i].x-=2;
			}
			else
			{
				if (ai[i].y < ai[min].y) ai[i].y += 2;
				else ai[i].y -= 2;
			}
		}

		for (int n = 0; n < FNUM; n++)
		{
			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;
			}
		}




	}
}


发布了114 篇原创文章 · 获赞 120 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/alzzw/article/details/103463844