C语言雷霆战机开发

目录

 

一、实验目的:

二、实验环境

三、实验内容及实验原理

1.需求分析

2.概念设计

3.流程设计

4.详细设计

(1)结构体

(2)链表

(3)控制方向

(4)绘图体系

(4)飞机,子弹图片的跟随移动

(5)时间差

(6)我方飞机飞行边界

(7)敌机重生的坐标

(8)透明图问题

(9)文字输出

(10)移动的背景图效果

(11)击杀判定与撞机判定

(12)boss

(13)背景音乐和爆炸音乐同时出现

(14)子弹击中敌机后消失

(15)Game Over

四、心得体会与建议


效果:

C语言雷霆战机开发_第1张图片C语言雷霆战机开发_第2张图片C语言雷霆战机开发_第3张图片

 

 

百度云盘:链接:https://pan.baidu.com/s/1_sNwa06In_9CQ6MRV1HoKA 密码:xc71

一、实验目的:

制作雷霆战机的简化版小游戏。

二、实验环境

环境:VS2013,VC++6.0,C/C++语言

三、实验内容及实验原理

1.需求分析

 

 

 C语言雷霆战机开发_第4张图片C语言雷霆战机开发_第5张图片

2.概念设计

C语言雷霆战机开发_第6张图片

 

3.流程设计

 

 

 C语言雷霆战机开发_第7张图片C语言雷霆战机开发_第8张图片

 

 C语言雷霆战机开发_第9张图片

 

 

 

 

4.详细设计

(1)结构体

使用结构来方便定义飞机的各个状态,如横纵坐标,和为使用链表创造数据结构。

 

创建结构体:

typedef struct Node

{

int x;

int y;

struct Node *pnext;

}NODE;

 

这里定义了横纵坐标(数据域内容),和指针(指针域内容)。

使用结构体:

NODE *p_MP = NULL;

p_MP = (NODE*)malloc(sizeof(NODE));

p_MP->x = WINDOW_WIDTH / 2 - pw / 2;

p_MP->y = WINDOW_HEIGHT-100;

p_MP->pnext = NULL;

 

这里就仅仅举个例子,代码中p_MP是定义为全局变量的,不和后面成员赋值的放在一起。定义成指针类型和为p_MP分配内存使用堆而不是直接定义在栈里,都是为了和定义子弹保持格式一致,因为子弹需要使用链表。

 

(2)链表

创建链表来控制子弹的产生,与子弹的移动。之所以选择链表是因为它比数组更方便插入和修改。

 

创建链表:

NODE* p_new = (NODE*)malloc(sizeof(NODE));

p_new->x = p_MP->x + 35;

p_new->y = p_MP->y - 45;

p_new->pnext = p_bullet->pnext;

p_bullet->pnext = p_new;

这里我使用单向链表就可以了。

 

使用链表:

我把上面的代码封装成一个函数,这样每次需要创建子弹时只要调用函数。这里p_new代表一个中间载体,我只是使用它最后的结果来赋值给全局变量p_bullet,所以它可以是局部变量。

 C语言雷霆战机开发_第10张图片

p_new与p_bullet的意思:

我使用p_new来当载体,就像交换a,b值,使用一个temp记录a的值。这里p_bullet假设为第一个位置,它的pnext指向第二个位置,而我要往第一个和第二个位置插入一个位置。所以我使用p_bullet->pnext = p_new从第一个位置指向我们插入的位置,使用p_new->pnext = p_bullet->pnext;来让我们插入的位置指向第二个位置。这样我们就在第一、二个位置之间插入了一个新的位置,并使链表变长。

 

 

P指针递增链表:

NODE* P = p_bullet->pnext;

while (P != NULL){

fillroundrect(P->x, P->y, P->x + 10, P->y + 35, 10, 30);

P->y -= 5;

P = P->pnext;

}

这是代码中递增子弹链表部分的简化版。从第一个子弹开始,让这个子弹的纵坐标减一个数值,这个数值和Sleep一起决定子弹的飞行速度,然后让P从第一个子弹指向第二个子弹,直到P为空。因为最后一个子弹的指针域是空。这里第一个子弹是最新发出的子弹,最后一个子弹是最早发出的子弹的意思。

 

(3)控制方向

if (kbhit()){

key = getch();

switch (key){

case 72://上

p_MP->y -= 5;

break;

}

}

这里我就举个向上前进的例子。这个khbit是conio.h头文件里的库函数,表示从输入缓冲区读取。如果按了上键,我们只用改变飞机的纵坐标就可以了,这个改变的程度决定决定了飞机的按一下前进多少,和while循环内Sleep函数(决定单位时间内你能按几次)一起决定飞机的移速(单位时间内前进的距离)。

 

(4)绘图体系

我使用EasyX库绘图体系,当然也可以用WIN32API的绘图体系,不过我试着做了一段时间,那个太麻烦了。

 

...

int main(){

initgraph(640, 480); //创建一个640*480大小的窗口

...

BeginBatchDraw(); //批量绘图,使你的图不闪来闪去。用在循环外

while(1)

{

cleardevice(); //清屏,要不然不要的图还在

...

FlushBatchDraw(); //把要绘制的图都绘制出来,用在循环内,要绘制的最后一张图以下

...

Sleep(...); //控制刷新频率等

}

EndBatchDraw(); //结束批量绘制

closegraph(); //关闭绘图窗口

return 0;

}

 

以上是基础的绘图框架。

 

(4)飞机,子弹图片的跟随移动

putimage(p_MP->x, p_MP->y, &i_MPS, NOTSRCERASE);

putimage(p_MP->x, p_MP->y, &i_MP, SRCINVERT);

 

我将飞机的图片贴到飞机的活动位置,而不是一个固定位置,这样只要改变飞机的坐标数值,图片自然跟随贴图。

 

 透明图片教程:[easyx游戏开发]---实现透明背景效果

 

(5)时间差

截取1:

p_bullet = (NODE*)malloc(sizeof(NODE));

p_bullet->pnext = NULL;

b1 = GetTickCount();

截取2: //MP单位时间发射子弹的数量

b2 = GetTickCount();

//不能等于,有偏差

if (b2 - b1 >= 600)

{

AddNode(0);

b1 = b2;

}

这里我使用时间差来控制飞机射速。每次检查时间差是否通过判定,如果通过就增加子弹并将b2的值赋予b1,来更新时间差。

 

 

同理我也用来控制敌机的飞行速度。

if (b4- b3 >= 50){

if (p_AP->y < WINDOW_HEIGHT) p_AP->y += 3;

else{

p_AP->y = 0;

p_AP->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);

}

b3 = b4;

}

这里的else部分是为了重生新的敌机。这个游戏的敌机1、2是只使用两个敌机不断重生来营造出新的飞机不断来临的画面。

 

(6)我方飞机飞行边界

if (p_MP->x<(WINDOW_WIDTH / 2 - WIDTH / 2))

p_MP->x = (WINDOW_WIDTH / 2 - WIDTH / 2);

这是左边界的例子。我们使用if函数不让它飞机的横坐标出现负值。

 

(7)敌机重生的坐标

敌机重生有两种情况:一是被我方飞机击杀,二是飞出了下边界。

 

纵坐标重赋值不需要因这两种情况分类讨论:p_AP->y = 0;

而横坐标按我的理解需要分情况讨论:

 

我的理解:如果飞机被击毁,使用情况一方法让它在非原横坐标附件重生,要不然由于时间差很小导致生成随机数可能相近,而出现这敌机老在原位置重生,出来我机不动就能打死的bug。如果飞机飞出边界,那么它可能还在原来x位置重生也没什么,你敌机在飞出边界前没打中,而在重生后打中也只是打中一次,它下一次重生又不在这个位置了。但你都想用情况一方法也行。

 

 

情况一,被击毁:while (1)

{

mid = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);

if (abs(mid - p_AP->x) > aw)

{

p_AP->x = mid;

break;

}

}

情况二:飞出边界:

p_AP->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);

 

 

(8)透明图问题

由于EasyX绘图体系和WIN32绘图体系都不支持直接使用png格式的图片,所以我这样做。

putimage(p_MP->x, p_MP->y, &i_MPS, NOTSRCERASE);

putimage(p_MP->x, p_MP->y, &i_MP, SRCINVERT);

 

i_MPS是贴的是掩码图,i_MP是贴的是精灵图,值NOTSRCERASESRCINVERT是三元光栅操作符。

(9)文字输出

TCHAR s_boss1hp[100];

_stprintf(s_boss1hp, _T("【Boss】HP:%d"), boss1hp);

outtextxy((WINDOW_WIDTH / 2 + WIDTH / 2) + 45, 200, s_boss1hp);

 

outtextxy这是EasyX的文字输出函数。

 

(10)移动的背景图效果

截取一:

putimage((WINDOW_WIDTH / 2 - WIDTH / 2), 0, WIDTH, WINDOW_HEIGHT, &i_backxing, left, 0, SRCCOPY);

 截取二:

case 75://左

p_MP->x -= 5;

left -= 5;

break;

截取三:

if (left < 0)

left = 0;

if (left>1280 - WIDTH)

left = 1280 - WIDTH;

 

使用putimage的重载函数,关键在于这个left变量,决定从图片的什么位置开始选区区域,之后我们在khbit部分按左右是让left的值改变,最后再规定一下它的边界。

 

 

同理,开场动画第一关图片从中间打开也是这样子。

 

(11)击杀判定与撞机判定

击杀就是子弹坐标与飞机坐标之差在一个特定范围,

如:

if ((P->y - p_AP->y) < ah && (P->y - p_AP->y) >= 0 && (P->x - p_AP->x) < aw -3 && (P->x - p_AP->x) >= -7)

 

因为是使用子弹坐标,所以我把这个判定部分放到了P递增链表内。

 

 

后面的撞机判定就离开了子弹,所以我就可以单独放到P递增链表外面。

(12)boss

bossshow

我使用bossshow这个整型变量来当boss出现以及子弹递增里区分boss战斗和普通敌机战斗的开关。

boss出现的例子:

if (boss1show==1)

{

Boss1show();

}

我初始化bossshow的值为0,当击毁十架敌机时bossshow的值赋值为1,当boss被击杀后bossshow的值赋值为0。

 

 

 

boss1image

我为boss出场设计了一个入场的动画,通过boss1image这个变量,和移动背景同样的原理让boss的图片从上往下移动,营造出入场的效果。并通过这个变量让boss出场时免疫子弹攻击。

出场的例子:

putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1S, NOTSRCERASE);

putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1, SRCINVERT);

 

 

boss1hp

这个变量用来判断boss处于何种状态来在boss不同的状态赋予boss不同的效果。

if (boss1hp >14) //血量大于14,贴正常图片

else if(boss1hp >= 9 && boss1hp <=14) //9和14之间图片,触发攻击武器,并交替正常图片和反相图片来营造闪烁的效果

 

(13)背景音乐和爆炸音乐同时出现

只使用PlaySound()函数或mciSendString()函数时,无法做到同时播放两个音乐,播放新的旧的就停止。

 

后来发现使用这两个函数不冲突时,我就使用mciSendString函数来播放背景音乐,爆炸音效由PlaySound()函数控制。

 

(14)子弹击中敌机后消失

一个子弹只杀死一架敌机,所以在不出现boss时,判断子弹与敌机位置时,是使用

if(){},else if(){},else{},而不是if(){if(){}},else{}。

 

当判定通过时,把当前子弹的纵坐标移走到屏外,就营造出子弹消失的效果。

 

(15)Game Over

定义MP_HP来使游戏结束画面出现。

初始化赋值为1,当撞机或被打中时,我方飞机MP_HP赋值为0,if判断出现游戏结束画面。

 

、心得体会与建议

开始的时候在CSDN看到有一个java版的雷霆战机,然后就想用C/C++做一个简单的。

 

查了好多地方,C语言中文网上的kbhit阻塞式键盘输入,CSDN上EasyX库制作透明效果的图片,潭州课堂的链表讲解,网易云上的EasyX库简单游戏开发,PlaySound函数怎么切换歌曲...

 

想做出什么就查什么,凑来凑去,各个部分的知识也像羽翼一样丰满起来了,终于做出了基本的样子。

 

增加游戏内容后,bug就会很多,有很多没有想到的地方就出现了,有的变量冲突,有的程序流程发生改变而使有些if分支出错,需要重新划分或增加一些条件。

 

这个调bug就调了一周。

 

果然做项目还是最好的学习方式。

#include
#include
#include
#include
#include
#include
#include
#pragma comment(lib,"winmm.lib")




typedef struct Node
{
	int x;
	int y;
	struct Node *pnext;
}NODE;

#define WINDOW_WIDTH 1024
#define WINDOW_HEIGHT 680
#define WIDTH 480

//我机图片尺寸
#define pw 86
#define ph 82

//敌机图片尺寸
#define aw 70
#define ah 70

#define boss1w 192
#define boss1h 290


//敌机重出现的y坐标
#define APStart -ah-20





NODE *p_bullet = NULL;
//MyPlane
NODE *p_MP = NULL;
//AttackPlane
NODE* p_AP = NULL;
//子弹时间差
NODE* p_AP2 = NULL;
DWORD b1, b2, b3, b4, b5, b6;

IMAGE i_MP,i_MPS,i_AP,i_APS;
IMAGE i_backeve, i_backxing, i_backduicheng, i_backguan,i_backcontrol,i_backgo;
IMAGE i_boss1_1, i_boss1_1S, i_boss1_2, i_boss1_2S;

//backxing的左右移动
int left = (WINDOW_WIDTH / 2 - WIDTH / 2);
//分数
int score = 0;
//击毁敌机的数量
int kill = 0;
//boss是否出现
int boss1show = 0;
//boss1贴图开关
int boss1image = 0;
int boss1hp = 20;

int line1_x = WINDOW_WIDTH / 2 - 20;
int line1_y = boss1h;
int line2_x = WINDOW_WIDTH / 2 + 20;
int line2_y = boss1h;

//Beam只播放一次
int test = 1;
int MP_HP = 1;



void CreateList()
{
	p_MP = (NODE*)malloc(sizeof(NODE));
	p_MP->x = WINDOW_WIDTH / 2 - pw / 2;
	p_MP->y = WINDOW_HEIGHT-100;
	p_MP->pnext = NULL;


	p_bullet = (NODE*)malloc(sizeof(NODE));
	p_bullet->pnext = NULL;
	b1 = GetTickCount();


	p_AP = (NODE*)malloc(sizeof(NODE));
	srand((unsigned)time(NULL));
	p_AP->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);
	p_AP->y = APStart;
	p_AP->pnext = NULL;
	b3 = GetTickCount();

	p_AP2 = (NODE*)malloc(sizeof(NODE));
	p_AP2->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);
	p_AP2->y = -350;
	p_AP2->pnext = NULL;
	b5 = GetTickCount();
}

void GameBackInit()
{
	loadimage(&i_MP, L"mp.jpg");
	loadimage(&i_MPS, L"mpbit.jpg");
	loadimage(&i_backeve, L"backeve.jpg");
	loadimage(&i_backxing, L"backtaikong.jpg");
	loadimage(&i_AP, L"AP.jpg", aw, ah);
	loadimage(&i_APS, L"APS.jpg", aw, ah);
	loadimage(&i_backduicheng, L"backduicheng.jpg");
	loadimage(&i_backguan, L"backguan.jpg", WIDTH, WINDOW_HEIGHT);
	loadimage(&i_backcontrol, L"backcontrol.jpg",WINDOW_WIDTH,WINDOW_HEIGHT);
	loadimage(&i_boss1_1, L"boss1_1.jpg");
	loadimage(&i_boss1_1S, L"boss1_1S.jpg");
	loadimage(&i_boss1_2, L"boss1_2.jpg");
	loadimage(&i_boss1_2S, L"boss1_1S.jpg");
	loadimage(&i_backgo, L"Gameover.jpg", WINDOW_WIDTH, WINDOW_HEIGHT);


	putimage(0, 30, &i_backeve);
	Sleep(1000);
	PlaySound(L"baozou.wav", NULL, SND_FILENAME | SND_ASYNC);

	putimage(0, 0, &i_backcontrol);
	outtextxy(600, 540, L"【PRESS】 按任意键进入游戏");
	system("pause");

	mciSendString(L"open bgmusic.mp3 alias bg", NULL, 0, NULL);
	mciSendString(L"play bg repeat", NULL, 0, NULL);

	putimage((WINDOW_WIDTH / 2 - WIDTH / 2), 0, WIDTH, WINDOW_HEIGHT, &i_backguan, 0, 0, SRCCOPY);
	putimage(0, 0, (WINDOW_WIDTH / 2 - WIDTH / 2), WINDOW_HEIGHT, &i_backduicheng, 0, 100, SRCCOPY);
	putimage((WINDOW_WIDTH / 2 + WIDTH / 2), 0, (WINDOW_WIDTH / 2 - WIDTH / 2), WINDOW_HEIGHT, &i_backduicheng, 1200 - (WINDOW_WIDTH / 2 - WIDTH / 2), 100, SRCCOPY);
	//字体出现的高度
	int text_h = WINDOW_HEIGHT/2;
	Sleep(300);
	BeginBatchDraw();
	for (int i = 0; i < text_h; i++)
	{
		clearrectangle((WINDOW_WIDTH / 2 - WIDTH / 2), 0, (WINDOW_WIDTH / 2 + WIDTH / 2), WINDOW_HEIGHT);
		putimage((WINDOW_WIDTH / 2 - WIDTH / 2), 0-i, WIDTH, text_h , &i_backguan, 0, 0, SRCCOPY);
		putimage((WINDOW_WIDTH / 2 - WIDTH / 2), text_h + i, WIDTH, WINDOW_HEIGHT - (text_h + i), &i_backguan, 0, text_h, SRCCOPY);
		putimage((WINDOW_WIDTH / 2 - WIDTH / 2), text_h - i, WIDTH, 2*i, &i_backxing, left, text_h-i, SRCCOPY);
		FlushBatchDraw();
		Sleep(5);
	}
	EndBatchDraw();

	
	Sleep(100);


}


void Boss1show()
{
	
	p_AP->y = WINDOW_HEIGHT + 100;
	p_AP2->y = WINDOW_HEIGHT + 100;

	if (boss1hp >14)
	{
		putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1S, NOTSRCERASE);
		putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1, SRCINVERT);
	}
	else if(boss1hp >= 9 && boss1hp <=14)
	{
		
		if (boss1hp % 2 == 0)
		{
			setlinecolor(0x996666);
			setlinestyle(PS_DOT, 3);
			line(line1_x, line1_y, line1_x, WINDOW_HEIGHT);
			line(line2_x, line2_y, line2_x, WINDOW_HEIGHT);

			putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_2S, NOTSRCERASE);
			putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_2, SRCINVERT);
			
		}
		else
		{
			setlinecolor(0xCC6666);
			setlinestyle(PS_DOT, 3);
			line(line1_x, line1_y, line1_x, WINDOW_HEIGHT);
			line(line2_x, line2_y, line2_x, WINDOW_HEIGHT);

			
			putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1S, NOTSRCERASE);
			putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_1, SRCINVERT);
		}
		
		
	}
	else
	{
		
		if (test == 1)
		{
			PlaySound(L"Beam.wav", NULL, SND_FILENAME | SND_ASYNC);
			test++;
		}
		setlinecolor(0xFF6666);
		setlinestyle(PS_DASH, 5);
		line(line1_x, line1_y, line1_x, WINDOW_HEIGHT);
		line(line2_x, line2_y, line2_x, WINDOW_HEIGHT);
		line(WINDOW_WIDTH / 2 - boss1w / 2, boss1h -90, 482, boss1h + 50);
		line(WINDOW_WIDTH / 2 + boss1w / 2, boss1h - 90, 542, boss1h + 50);
		putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_2S, NOTSRCERASE);
		putimage(WINDOW_WIDTH / 2 - boss1w / 2, -boss1h + boss1image, &i_boss1_2, SRCINVERT);
		if ((boss1hp!=8)&&(p_MP->x - line1_x) > -pw && (p_MP->x - line2_x)<0&& (p_MP->y - line1_y)>-ph)			MP_HP = 0;
	}

	
	if(boss1image<=boss1h )	boss1image+=2;

}

void AddNode(int flag)
{
	//后插法,更新第二个位置
	if (flag == 0)
	{
		NODE* p_new = (NODE*)malloc(sizeof(NODE));

		p_new->x = p_MP->x + 35;
		p_new->y = p_MP->y - 45;

		p_new->pnext = p_bullet->pnext;
		p_bullet->pnext = p_new;
	}
}



int main()
{
	//create a window
	initgraph(WINDOW_WIDTH, WINDOW_HEIGHT);

	setfillcolor(0xFF9999);

	GameBackInit();

	char key;
	CreateList();
	//批量绘图
	
	BeginBatchDraw();
	while (1)
	{	
		
		//清画板,要不然就成重叠的残影了
		cleardevice();



		putimage((WINDOW_WIDTH / 2 - WIDTH / 2), 0, WIDTH, WINDOW_HEIGHT, &i_backxing, left, 0, SRCCOPY);
		putimage(0, 0, (WINDOW_WIDTH / 2 - WIDTH / 2), WINDOW_HEIGHT, &i_backduicheng, 0, 100, SRCCOPY);
		putimage((WINDOW_WIDTH / 2 + WIDTH / 2), 0, (WINDOW_WIDTH / 2 - WIDTH / 2), WINDOW_HEIGHT, &i_backduicheng, 1200 - (WINDOW_WIDTH / 2 - WIDTH / 2), 100, SRCCOPY);


		putimage(p_MP->x, p_MP->y, &i_MPS, NOTSRCERASE);
		putimage(p_MP->x, p_MP->y, &i_MP, SRCINVERT);
		putimage(p_AP->x, p_AP->y, &i_APS, NOTSRCERASE);
		putimage(p_AP->x, p_AP->y, &i_AP, SRCINVERT);
		putimage(p_AP2->x, p_AP2->y, &i_APS, NOTSRCERASE);
		putimage(p_AP2->x, p_AP2->y, &i_AP, SRCINVERT);
		
		

		//MP单位时间发射子弹的数量
		b2 = GetTickCount();
		//不能等于,有偏差
		if (b2 - b1 >= 600)
		{
			AddNode(0);
			b1 = b2;
		}




		//我方战机子弹递增
		NODE* P = p_bullet->pnext;


		while (P != NULL)
		{
			if (boss1show == 0)
			{

				//确定敌机重生位置不是在原位置
				int mid;
				//10是子弹宽度,但半个子弹打中也算,要不然太难了,就右边是-3,左边是-7
				if ((P->y - p_AP->y) < ah && (P->y - p_AP->y) >= 0 && (P->x - p_AP->x) < aw -3 && (P->x - p_AP->x) >= -7)
				{
					P->y = APStart -100;
					P = P->pnext;
					p_AP->y = APStart;
					kill++;

					PlaySound(L"Bomb.wav", NULL, SND_FILENAME | SND_ASYNC);
					while (1)
					{
						mid = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);
						if (abs(mid - p_AP->x) > aw)
						{
							p_AP->x = mid;
							break;
						}
					}
					

				}
				else if((P->y - p_AP2->y) < ah && (P->y - p_AP2->y) >= 0 && (P->x - p_AP2->x) < aw - 3 && (P->x - p_AP2->x) >= -7)
				{
					P->y = APStart -100;
					P = P->pnext;
					p_AP2->y = APStart;
					kill++;

					while (1)
					{
						mid = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);
						if (abs(mid - p_AP2->x) > aw)
						{
							p_AP2->x = mid;
							break;
						}
					}
					PlaySound(L"Bomb.wav", NULL, SND_FILENAME | SND_ASYNC);
				}
				else
				{
					fillroundrect(P->x, P->y, P->x + 10, P->y + 35, 10, 30);
					P->y -= 5;
					P = P->pnext;
				}
			}
			else if (boss1show == 1)
			{
				if (boss1image > boss1h)
				{
					if ((P->y) < boss1h && (P->y) >= 0 && (P->x - (WINDOW_WIDTH / 2 - boss1w / 2)) < boss1w - 3 && (P->x - (WINDOW_WIDTH / 2 - boss1w / 2)) >= -7)
					{
						P->y = APStart -100;
						P = P->pnext;
						boss1hp--;
						if (boss1hp>9||boss1hp<7)	PlaySound(L"Bomb.wav", NULL, SND_FILENAME | SND_ASYNC);
					}
					else
					{
						fillroundrect(P->x, P->y, P->x + 10, P->y - 35, 10, 30);
						P->y -= 10;
						P = P->pnext;
					}

					TCHAR s_boss1hp[100];
					_stprintf(s_boss1hp, _T("【Boss】HP:%d"), boss1hp);
					outtextxy((WINDOW_WIDTH / 2 + WIDTH / 2) + 45, 200, s_boss1hp);

					if (boss1hp <= 0)
					{
						boss1show = 0;
						kill += 50;
					}
				}
				else
				{
					fillroundrect(P->x, P->y, P->x + 10, P->y + 35, 10, 30);
					P->y -= 5;
					P = P->pnext;
				}
			}
		}





		//AP飞行的速度
		b4 = GetTickCount();
		//不能等于,有偏差
		if (b4- b3 >= 50)
		{
			if (p_AP->y < WINDOW_HEIGHT)
			{
				p_AP->y += 3;
			}
			else
			{
				p_AP->y = 0;
				p_AP->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);
			}
			b3 = b4;
		}




		//AP2飞行的速度
		b6 = GetTickCount();
		//不能等于,有偏差
		if (b6 - b5 >= 50)
		{
			if (p_AP2->y < WINDOW_HEIGHT)
			{
				p_AP2->y += 3;
			}
			else
			{
				p_AP2->y = 0;
				p_AP2->x = rand() % (WIDTH - aw) + (WINDOW_WIDTH / 2 - WIDTH / 2);
			}
			b5 = b6;
		}
		
		



		if (kill==10&& boss1hp > 0) boss1show = 1;




		if (boss1show==1)
		{
			Boss1show();
		}




		if ((p_MP->x - p_AP->x) > -pw && (p_MP->x - p_AP->x)y - p_AP->y)>-ph && (p_MP->y - p_AP->y)x - p_AP2->x) > -pw && (p_MP->x - p_AP2->x)y - p_AP2->y)>-ph && (p_MP->y - p_AP2->y)boss1h&&(p_MP->x-(WINDOW_WIDTH / 2 - boss1w / 2)) >-pw && (p_MP->x-(WINDOW_WIDTH / 2 + boss1w / 2))yy -= 5;
				break;
			case 80://下
				p_MP->y += 5;
				break;
			case 75://左
				p_MP->x -= 5;
				left -= 5;
				break;
			case 77://右
				p_MP->x += 5;
				left += 5;
				break;
			}
		}



		if (p_MP->x<(WINDOW_WIDTH / 2 - WIDTH / 2)) 
			p_MP->x = (WINDOW_WIDTH / 2 - WIDTH / 2);
		if (p_MP->x>(WINDOW_WIDTH / 2 + WIDTH / 2 - pw))
			p_MP->x = (WINDOW_WIDTH / 2 + WIDTH / 2 - pw);
		if (p_MP->y<0 ) 
			p_MP->y = 0;
		if (p_MP->y>WINDOW_HEIGHT - ph) 
			p_MP->y = WINDOW_HEIGHT - ph;


		if (left < 0)
			left = 0;
		if (left>1280 - WIDTH)
			left = 1280 - WIDTH;

	}
	
	EndBatchDraw();
	closegraph();
	return 0;
}

 

 

 

你可能感兴趣的:(game)