当前位置:首页 > 趣味小程序 > 正文内容

【C++图形化编程】飞机大战2——运动与碰撞检测

亿万年的星光3年前 (2021-11-13)趣味小程序7520

上一篇中,简单实现了飞机大战的基本框架,这篇文章继续完善,使其可以进行游戏。

#include <graphics.h>
#include <conio.h>
#include <math.h>
#include <stdio.h>

// 引用 Windows Multimedia API
#pragma comment(lib,"Winmm.lib")

#define High 800  // 游戏画面尺寸
#define Width 590

IMAGE img_bk; // 背景图片
float position_x,position_y; // 飞机位置
float bullet_x,bullet_y; // 子弹位置
float enemy_x,enemy_y; // 敌机位置
IMAGE img_planeNormal1,img_planeNormal2; // 正常飞机图片
IMAGE img_planeExplode1,img_planeExplode2; // 爆炸飞机图片
IMAGE img_bullet1,img_bullet2; // 子弹图片
IMAGE img_enemyPlane1,img_enemyPlane2; // 敌机图片
int isExpolde = 0; // 飞机是否爆炸
int score = 0; // 得分

void startup()
{
	mciSendString("open game_music.mp3 alias bkmusic", NULL, 0, NULL);//打开背景音乐
	mciSendString("play bkmusic repeat", NULL, 0, NULL);  // 循环播放
	initgraph(Width,High);
	loadimage(&img_bk, "background.jpg");
	loadimage(&img_planeNormal1, "planeNormal_1.jpg");
	loadimage(&img_planeNormal2, "planeNormal_2.jpg");
	loadimage(&img_bullet1, "bullet1.jpg");
	loadimage(&img_bullet2, "bullet2.jpg");
	loadimage(&img_enemyPlane1, "enemyPlane1.jpg");
	loadimage(&img_enemyPlane2, "enemyPlane2.jpg");
	loadimage(&img_planeExplode1, "planeExplode_1.jpg");
	loadimage(&img_planeExplode2, "planeExplode_2.jpg");
	position_x = Width*0.5;
	position_y = High*0.7;
	bullet_x = position_x;
	bullet_y = -85;
	enemy_x = Width*0.5;
	enemy_y = 10;	
	BeginBatchDraw();	
}

void show()
{
	putimage(0, 0, &img_bk);	// 显示背景	
	if (isExpolde==0)
	{
		putimage(position_x-50, position_y-60, &img_planeNormal1,NOTSRCERASE); // 显示正常飞机	
		putimage(position_x-50, position_y-60, &img_planeNormal2,SRCINVERT);

		putimage(bullet_x-7, bullet_y, &img_bullet1,NOTSRCERASE); // 显示子弹	
		putimage(bullet_x-7, bullet_y, &img_bullet2,SRCINVERT);
		putimage(enemy_x, enemy_y, &img_enemyPlane1,NOTSRCERASE); // 显示敌机	
		putimage(enemy_x, enemy_y, &img_enemyPlane2,SRCINVERT);
	}
	else
	{
		putimage(position_x-50, position_y-60, &img_planeExplode1,NOTSRCERASE); // 显示爆炸飞机	
		putimage(position_x-50, position_y-60, &img_planeExplode2,SRCINVERT);
	}
	outtextxy(Width*0.48, High*0.95, "得分:");
	char s[5];
	sprintf(s, "%d", score);
	outtextxy(Width*0.55, High*0.95, s);
	FlushBatchDraw();
	Sleep(2);
}

void updateWithoutInput()
{
	if (isExpolde==0)
	{		
		if (bullet_y>-25)
			bullet_y = bullet_y-2;
		
		if (enemy_y<High-25)
			enemy_y = enemy_y+0.5;
		else
			enemy_y = 10;		
		if (abs(bullet_x-enemy_x)+abs(bullet_y-enemy_y) < 80)  // 子弹击中敌机
		{
			enemy_x = rand()%Width;
			enemy_y = -40;
			bullet_y = -85;	
			mciSendString("close gemusic", NULL, 0, NULL); // 先把前面一次的音乐关闭
			mciSendString("open gotEnemy.mp3 alias gemusic", NULL, 0, NULL); // 打开音乐
			mciSendString("play gemusic", NULL, 0, NULL); // 仅播放一次
			score++;
			if (score>0 && score%5==0 && score%2!=0)
			{
				mciSendString("close 5music", NULL, 0, NULL); // 先把前面一次的音乐关闭
				mciSendString("open 5.mp3 alias 5music", NULL, 0, NULL); // 打开音乐
				mciSendString("play 5music", NULL, 0, NULL); // 仅播放一次
			}
			if (score%10==0)
			{
				mciSendString("close 10music", NULL, 0, NULL); // 先把前面一次的音乐关闭
				mciSendString("open 10.mp3 alias 10music", NULL, 0, NULL); // 打开音乐
				mciSendString("play 10music", NULL, 0, NULL); // 仅播放一次
			}
		}
		
		if (abs(position_x-enemy_x)+abs(position_y-enemy_y) < 150)  // 敌机击中我们
		{
			isExpolde = 1;
			mciSendString("close exmusic", NULL, 0, NULL); // 先把前面一次的音乐关闭
			mciSendString("open explode.mp3 alias exmusic", NULL, 0, NULL); // 打开音乐
			mciSendString("play exmusic", NULL, 0, NULL); // 仅播放一次		
		}
	}
}

void updateWithInput()
{

}

void gameover()
{
	EndBatchDraw();
	getch();
	closegraph();
}

int main()
{
	startup();  // 数据初始化	
	while (1)  //  游戏循环执行
	{
		show();  // 显示画面
		updateWithoutInput();  // 与用户输入无关的更新
		updateWithInput();     // 与用户输入有关的更新
	}
	gameover();     // 游戏结束、后续处理
	return 0;
}



继续。与用户输入有关的操作

#include <graphics.h>
#include <conio.h>
#include <math.h>
#include <stdio.h>

// 引用 Windows Multimedia API
#pragma comment(lib,"Winmm.lib")

#define High 800  // 游戏画面尺寸
#define Width 590

IMAGE img_bk; // 背景图片
float position_x,position_y; // 飞机位置
float bullet_x,bullet_y; // 子弹位置
float enemy_x,enemy_y; // 敌机位置
IMAGE img_planeNormal1,img_planeNormal2; // 正常飞机图片
IMAGE img_planeExplode1,img_planeExplode2; // 爆炸飞机图片
IMAGE img_bullet1,img_bullet2; // 子弹图片
IMAGE img_enemyPlane1,img_enemyPlane2; // 敌机图片
int isExpolde = 0; // 飞机是否爆炸
int score = 0; // 得分

void startup()
{
	mciSendString("open game_music.mp3 alias bkmusic", NULL, 0, NULL);//打开背景音乐
	mciSendString("play bkmusic repeat", NULL, 0, NULL);  // 循环播放
	initgraph(Width,High);
	loadimage(&img_bk, "background.jpg");
	loadimage(&img_planeNormal1, "planeNormal_1.jpg");
	loadimage(&img_planeNormal2, "planeNormal_2.jpg");
	loadimage(&img_bullet1, "bullet1.jpg");
	loadimage(&img_bullet2, "bullet2.jpg");
	loadimage(&img_enemyPlane1, "enemyPlane1.jpg");
	loadimage(&img_enemyPlane2, "enemyPlane2.jpg");
	loadimage(&img_planeExplode1, "planeExplode_1.jpg");
	loadimage(&img_planeExplode2, "planeExplode_2.jpg");
	position_x = Width*0.5;
	position_y = High*0.7;
	bullet_x = position_x;
	bullet_y = -85;
	enemy_x = Width*0.5;
	enemy_y = 10;	
	BeginBatchDraw();	
}

void show()
{
	putimage(0, 0, &img_bk);	// 显示背景	
	if (isExpolde==0)
	{
		putimage(position_x-50, position_y-60, &img_planeNormal1,NOTSRCERASE); // 显示正常飞机	
		putimage(position_x-50, position_y-60, &img_planeNormal2,SRCINVERT);

		putimage(bullet_x-7, bullet_y, &img_bullet1,NOTSRCERASE); // 显示子弹	
		putimage(bullet_x-7, bullet_y, &img_bullet2,SRCINVERT);
		putimage(enemy_x, enemy_y, &img_enemyPlane1,NOTSRCERASE); // 显示敌机	
		putimage(enemy_x, enemy_y, &img_enemyPlane2,SRCINVERT);
	}
	else
	{
		putimage(position_x-50, position_y-60, &img_planeExplode1,NOTSRCERASE); // 显示爆炸飞机	
		putimage(position_x-50, position_y-60, &img_planeExplode2,SRCINVERT);
	}
	outtextxy(Width*0.48, High*0.95, "得分:");
	char s[5];
	sprintf(s, "%d", score);
	outtextxy(Width*0.55, High*0.95, s);
	FlushBatchDraw();
	Sleep(2);
}

void updateWithoutInput()
{
	if (isExpolde==0)
	{		
		if (bullet_y>-25)
			bullet_y = bullet_y-2;
		
		if (enemy_y<High-25)
			enemy_y = enemy_y+0.5;
		else
			enemy_y = 10;		
		if (abs(bullet_x-enemy_x)+abs(bullet_y-enemy_y) < 80)  // 子弹击中敌机
		{
			enemy_x = rand()%Width;
			enemy_y = -40;
			bullet_y = -85;	
			mciSendString("close gemusic", NULL, 0, NULL); // 先把前面一次的音乐关闭
			mciSendString("open gotEnemy.mp3 alias gemusic", NULL, 0, NULL); // 打开音乐
			mciSendString("play gemusic", NULL, 0, NULL); // 仅播放一次
			score++;
			if (score>0 && score%5==0 && score%2!=0)
			{
				mciSendString("close 5music", NULL, 0, NULL); // 先把前面一次的音乐关闭
				mciSendString("open 5.mp3 alias 5music", NULL, 0, NULL); // 打开音乐
				mciSendString("play 5music", NULL, 0, NULL); // 仅播放一次
			}
			if (score%10==0)
			{
				mciSendString("close 10music", NULL, 0, NULL); // 先把前面一次的音乐关闭
				mciSendString("open 10.mp3 alias 10music", NULL, 0, NULL); // 打开音乐
				mciSendString("play 10music", NULL, 0, NULL); // 仅播放一次
			}
		}
		
		if (abs(position_x-enemy_x)+abs(position_y-enemy_y) < 150)  // 敌机击中我们
		{
			isExpolde = 1;
			mciSendString("close exmusic", NULL, 0, NULL); // 先把前面一次的音乐关闭
			mciSendString("open explode.mp3 alias exmusic", NULL, 0, NULL); // 打开音乐
			mciSendString("play exmusic", NULL, 0, NULL); // 仅播放一次		
		}
	}
}

void updateWithInput()
{
	if (isExpolde==0)
	{
		MOUSEMSG m;		// 定义鼠标消息
		while (MouseHit())  //这个函数用于检测当前是否有鼠标消息
		{
			m = GetMouseMsg();
			if(m.uMsg == WM_MOUSEMOVE)
			{
				// 飞机的位置等于鼠标所在的位置
				position_x = m.x;
				position_y = m.y;			
			}
			else if (m.uMsg == WM_LBUTTONDOWN)
			{
				// 按下鼠标左键,发射子弹
				bullet_x = position_x;
				bullet_y = position_y-85;
				mciSendString("close fgmusic", NULL, 0, NULL); // 先把前面一次的音乐关闭
				mciSendString("open f_gun.mp3 alias fgmusic", NULL, 0, NULL); // 打开音乐
				mciSendString("play fgmusic", NULL, 0, NULL); // 仅播放一次
			}
		}	
	}
}

void gameover()
{
	EndBatchDraw();
	getch();
	closegraph();
}

int main()
{
	startup();  // 数据初始化	
	while (1)  //  游戏循环执行
	{
		show();  // 显示画面
		updateWithoutInput();  // 与用户输入无关的更新
		updateWithInput();     // 与用户输入有关的更新
	}
	gameover();     // 游戏结束、后续处理
	return 0;
}


扫描二维码推送至手机访问。

版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

分享给朋友:

相关文章

C++如何在控制台不同区域显示不同颜色

C++如何在控制台不同区域显示不同颜色

0.前言在前面的文章中,我们介绍过让控制台”五彩斑斓“。但是有一个问题,就是使用system(“color A9”)这种方式,这种方式是一种全局的配置,会把原来的颜色给换掉,很难实现不同区域不同颜色的...

【C++图形化编程】flappy bird(3)—碰撞检测(大功告成)

0.前言    前面几篇文章中,我们简单介绍了基础框架和游戏逻辑,这一篇文章我们接着上一篇,继续完善游戏,主要是移动与碰撞逻辑的检测...

【C++图形化编程】EasyX函数~图像操作相关函数

【C++图形化编程】EasyX函数~图像操作相关函数

图像处理相关函数函数或数据类型描述IMAGE保存图像的对象loadimage读取图片文件saveimage保存绘图内容至图片文件getimage从当前绘图设备种获取图像putimage在当前绘图设备上...

【C++图形化编程】EasyX函数~鼠标操作相关函数

在EasyX中,我们可以用控制鼠标的相关函数。FlushMouseMsgBuffer清空鼠标消息缓冲区GetMouseMsg获取一个鼠标消息。如果当前鼠标消息队列中没有,就一直等待PeekMouseM...

C++产生随机数

0.前言想做一个掷骰子的小游戏,需要用到随机数函数,于是查了一些资料,整理了一下。1.随机数函数C++产生随机数需要用到rand()和srand()函数。期中,(1)rand()叫随机数发生器,所在头...

C++小游戏—简单飞机大战(1)

C++小游戏—简单飞机大战(1)

前面文章简单实现了弹球操作,这篇文章我们介绍一下如何实现简单的飞机大战操作。这篇文章我们要实现的效果如下:第一步:整体思路在某个点画出飞机的形状获取用户按下哪个按键根据按键移动飞机的位置按空格键发射子...