MFC实现简单飞机大战(含游戏声音) 您所在的位置:网站首页 游戏类图之二维潜艇游戏 MFC实现简单飞机大战(含游戏声音)

MFC实现简单飞机大战(含游戏声音)

2024-07-09 15:22| 来源: 网络整理| 查看: 265

1 实验内容

本实验主要是实现简单的飞机大战游戏,包含游戏声音、碰撞后爆炸效果,有大小敌机等。所用到的知识点如下:

1.贴图技术

2.飞机类、子弹类实现

3.位图移动

4.碰撞判断,实现爆炸效果

5.插入声音

此实验的大概设计:游戏画面保持有一架大敌机,五架小敌机,一架战机,30颗子弹。如果子弹击落了敌机,那么敌机对象不会被delete,而仅仅是改变它的位置,让它重新从上面飞下,姑且可以叫做“假摧毁”吧。同理,子弹飞出界面或打到敌机,该子弹对象也不会被delete,而是从底部重新上升。击落敌机时会有爆炸效果;战机被敌机摧毁会有更大的爆炸效果,且游戏会停1秒再继续。

2 实验环境

win10+vs2015

3 实验步骤 3.1 添加游戏资源

从网上下载自己喜欢的飞机和子弹图片(.png文件),下载游戏背景音乐(.wav文件),把上述资源导入本工程的res文件,复制res文件到Debug文件中,这样便可以直接打开zsr_简单飞机大战.exe

打开res文件,可以看到下图(当然啦,飞机、子弹和游戏声音选你喜欢的就行啦,不用跟我的一样):

上图中倒数第二个黑色的飞机就是我的程序图标。

3.2 修改程序图标

点击[这里]了解一下。

3.3 设置类

右键‘项目’,点击‘添加类’,就可以添加类啦。本实验设置4个类:大敌机(DADIJI),小敌机(XIAODIJI),战机(ZHANJI),子弹(ZIDAN)。并且在类中实现贴图。

3.3.1 大敌机类(DADIJI)

添加大敌机类,类名为'DADIJI'。并在类中添加数据成员和成员函数,修改构造函数。具体如下:

//在类中加入: CImage m_hero;//图片类对象 int diji_x;//图片横坐标 int diji_y;//图片轴坐标 void JIDRAW(CDC *cDC) { //设定大敌机的大小 m_hero.Draw(*cDC, diji_x, diji_y, 100, 50);//图片的宽为100,高50 } //修改构造函数 DADIJI::DADIJI() { //加载图片 CString imgPath = _T("res\\LXPlane.png"); m_hero.Load(imgPath); //初始化大敌机的位置 diji_x = 300; diji_y = 0; } 3.3.2 小敌机类(XIAODIJI)

添加内容和大敌机类似,如下:

//类中加入: CImage m_hero; int diji_x; int diji_y; //设定小敌机的大小 void JIDRAW(CDC *cDC) { m_hero.Draw(*cDC, diji_x, diji_y, 50,50); //小敌机宽50,高50 } //修改构造函数: XIAODIJI::XIAODIJI() { //加载图片 CString imgPath = _T("res\\BluePlane.png"); m_hero.Load(imgPath); //设定小敌机的初始位置 diji_x = 30; diji_y = 0; } 3.3.3 战机类(ZHANJI)

修改内容和大敌机差不多。这里说明一下,我的战机位置也用了diji_x和diji_y来表示,其实为了代码的可读性,这里用zhanji_x和zhanji_y比较好。(但我比较懒,这里就不修改了。)具体改动的代码如下:

//在类中加入: CImage m_hero; int diji_x; int diji_y; CImage m_hero1; //设定战机的大小 void JIDRAW(CDC *cDC) { m_hero.Draw(*cDC, diji_x, diji_y, 80, 80); } //加入爆炸效果函数 void JIDRAW1(CDC *cDC, int x, int y) { m_hero1.Draw(*cDC, x, y, 100, 100);//战机被敌机碰撞将变成爆炸状 } //修改构造函数: ZHANJI::ZHANJI() { //加载战机图片 CString imgPath = _T("res\\XPlane.png"); m_hero.Load(imgPath); //加载爆炸图片 CString imgPath1 = _T("res\\ZHANJIBAOZHA.png"); m_hero1.Load(imgPath1); //设定战机的初始位置 diji_x = 330; diji_y = 500; } 3.3.4 子弹类(ZIDAN)

这里的解释,和战机类的解释一样。具体代码如下:

//在类中加入: CImage m_hero; CImage m_hero1; int diji_x; int diji_y //设置子弹的大小; void JIDRAW(CDC *cDC) { m_hero.Draw(*cDC, diji_x, diji_y, 20, 20); } //设置爆炸效果 void JIDRAW1(CDC *cDC,int x,int y) { m_hero1.Draw(*cDC, x, y, 50, 50);//子弹碰到敌机,将会变成爆炸状 } 修改构造函数: ZIDAN::ZIDAN() { //加载子弹图片 CString imgPath = _T("res\\zidan.png"); m_hero.Load(imgPath); //加载爆炸图片 CString imgPath1 = _T("res\\baozha.png"); m_hero1.Load(imgPath1); 设定子弹初始位置 diji_x = 320; diji_y = 600; } 3.4 游戏重要变量 //在view类中加入下面变量: DADIJI DA1;//大敌机1台 XIAODIJI XIAO1[5];//保持游戏界面有小敌机5台 ZIDAN ZI[30];//保持游戏界面有子弹30颗 ZHANJI ZHAN;//战机一台 3.5 设计游戏开始界面 //修改view中的Oncreat()函数,如下: int Czsr_简单飞机大战View::OnCreate(LPCREATESTRUCT lpCreateStruct) { if (CView::OnCreate(lpCreateStruct) == -1) return -1; // TODO: 在此添加您专用的创建代码 PlaySound(_T("res\\youxi.wav"), NULL, SND_FILENAME | SND_ASYNC|SND_LOOP);//循环播放背景音乐 this->SetTimer(1, 100, NULL);//设置一个定时器 int x_num = 30; for (int j3 = 0;j3 < 5;j3++) { XIAO1[j3].diji_x += x_num;//开始时,小飞机的横坐标相隔30 x_num += 30; XIAO1[j3].diji_y -= x_num;//开始时,小飞机的纵坐标相隔30,起到延迟出现的效果 } int num = 0; for (int j2 = 0;j2 < 30;j2++) { ZI[j2].diji_y-= num;//开始时,子弹的纵坐标相隔25,起到延迟出现的效果 ZI[j2].diji_x = ZHAN.diji_x+30;//子弹的横坐标在战机的正中间 num += 25; ; } return 0; } 3.6 位图移动和碰撞

看到3.5的修改中已经设置了一个计时器,这里响应Ontimer()函数,如下:

//设计ontimer()函数(如下): void Czsr_简单飞机大战View::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 CDC *cDC = this->GetDC(); //获得当前窗口的DC GetClientRect(&m_client); //获得窗口的尺寸 CRect rect; GetClientRect(rect); cDC->FillSolidRect(rect, RGB(255, 255, 255)); ZHAN.JIDRAW(cDC);//画战机 //子弹 for (int j1 = 0;j1 < 30;j1++) { if (ZI[j1].diji_x < DA1.diji_x+100&& ZI[j1].diji_x >DA1.diji_x - 100&&ZI[j1].diji_y < DA1.diji_y+50&& ZI[j1].diji_y >DA1.diji_y - 50)//判断子弹是否和大战机碰撞 { int xx = DA1.diji_x; int yy = DA1.diji_y; ZI[j1].JIDRAW1(cDC,xx,yy );//若两者产生碰撞,则出现爆炸效果 ZI[j1].diji_y = ZHAN.diji_y; ZI[j1].diji_x = ZHAN.diji_x + 30;//发生爆炸的子弹,重新回到战机的子弹口 DA1.diji_x = rand() % 400; //大敌机从上面的随机位置重新出现 while (DA1.diji_xXIAO1[i1].diji_x - 50 && ZI[j1].diji_y XIAO1[i1].diji_y - 50)//判断每台小敌机是否和子弹碰撞 { int xx1 = XIAO1[i1].diji_x; int yy1 = XIAO1[i1].diji_y; XIAO1[i1].diji_x = rand() % 400;//若碰撞,小敌机重新从上面的随机位置降落 while (XIAO1[i1].diji_xXIAO1[j].diji_x -50 && ZHAN.diji_y < XIAO1[j].diji_y + 50 && ZHAN.diji_y >XIAO1[j].diji_y - 50)//判断战机是否和小战机碰撞 { int xxx = ZHAN.diji_x; int yyy = ZHAN.diji_y; ZHAN.JIDRAW1(cDC, xxx, yyy);//若碰撞,发生战机爆炸 Sleep(500);//停止500ms XIAO1[j].diji_x = rand() % 400; while (DA1.diji_x 690)//若小敌机走出游戏界面,则重新随机降落 { XIAO1[j].diji_x = rand() % 400; while(XIAO1[j].diji_xDA1.diji_x - 100 && ZHAN.diji_y < DA1.diji_y + 80 && ZHAN.diji_y >DA1.diji_y - 80)//判断战机是否和大敌机发生碰撞 { int xxx = ZHAN.diji_x; int yyy = ZHAN.diji_y; ZHAN.JIDRAW1(cDC, xxx, yyy);//若碰撞,战机爆炸,大敌机重新随机降落 Sleep(500);//停止500ms DA1.diji_x = rand() % 400; while (DA1.diji_x 0) ZHAN.diji_x -= 10; } else { if (nChar == 39)//向右移 if (ZHAN.diji_x


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有