VC6.0 MFC 单文档 飞机躲避模型

飞机躲避模型

一、设计要求

屏幕中有很多粒子,飞行速度和方向各不相同(可以用随机数产生每个粒子的飞行速度和方向),用户可以用上下左右键控制一个飞机,躲避所有粒子不被击中,坚持时间越长得分越多。

二、设计步骤

1、新建一个MFC单文档应用程序,如下图所示。
在这里插入图片描述
在这里插入图片描述
2、新建一个类,如下图所示。
在这里插入图片描述
3、定义粒子结构体并添加一些成员变量,如下图所示。
在这里插入图片描述
4、然后在构造函数里对部分成员变量初始化,代码如下。

CFeiJiDuoBi::CFeiJiDuoBi()
{
	m_YD.x = 50;
	m_YD.y = 850;
	m_kx = 800.0/10000;
	m_ky = -800.0/10000;//单位“米”

	m_FJYD.x = m_YD.x + 5000*m_kx;
	m_FJYD.y = m_YD.y + 5000*m_ky;
	m_fjh = 700;
	m_fjw = 400;
	m_fjl = 200;
    m_nLZ = 20;
	m_lzr = 100;

	dt = 0.1;
	m_FS = 0;

	CreateLiZi();//创建随机20个粒子
}

5、添加Draw函数,并调用后面我们需要用到的如下图所示。
在这里插入图片描述
代码如下:

void CFeiJiDuoBi::Draw(CDC *p)
{
	CString str;
	CFont ft;
	pDC = p;
	DrawArea();//画区域边界
	DrawFeiJi();//画飞机
	DrawLiZi();//画粒子

	str.Format("得分:%d 分",m_FS);
	ft.CreatePointFont(400,_T("隶书"),NULL);
	pDC->SelectObject(&ft);
	pDC->SetTextColor(RGB(0,0,0));
	pDC->TextOut(900,150,str);
}

6、首先将游戏区域、粒子、飞机画出来,如下图所示。

(1)画游戏区域
在这里插入图片描述
代码如下:

//画游戏区域
void CFeiJiDuoBi::DrawArea()
{
	int x,y,r;
	x = m_YD.x;
	y = m_YD.y;
	r = 10000*m_kx;
	pDC->Rectangle(x,y,x+r,y-r);//左下角为矩形起点
}

(2)画粒子
在这里插入图片描述
代码如下:

//画粒子
void CFeiJiDuoBi::DrawLiZi()
{
	int i;
	int x,y,r;
	for (i = 0; i < m_nLZ; i++)
	{
		x = m_LZ[i].pt.x;
		y = m_LZ[i].pt.y;
		r = m_lzr*m_kx;
		CBrush brush,*pOldBrush;
		brush.CreateSolidBrush(RGB(0,0,0));
		pOldBrush = pDC->SelectObject(&brush);
		pDC->Ellipse(x-r,y-r,x+r,y+r);
		brush.DeleteObject();
		pDC->SelectObject(pOldBrush);
	}
}

(3)画飞机
在这里插入图片描述
代码如下:

//画飞机
void CFeiJiDuoBi::DrawFeiJi()
{
	int x,y,r;
	CPoint p1,p2,p3;//画飞机头的3个点(当三角形处理)
	x = m_FJYD.x + m_fjw*m_kx;
	y = m_FJYD.y + m_fjh*m_ky;

	CBrush brush,*pOldBrush;
	brush.CreateSolidBrush(RGB(255,0,0));
	pOldBrush = pDC->SelectObject(&brush);
	pDC->MoveTo(m_FJYD);
	pDC->Rectangle(m_FJYD.x,m_FJYD.y,x,y);//画飞机身(当矩形处理)
	brush.DeleteObject();
	pDC->SelectObject(pOldBrush);

	p1.x = m_FJYD.x - m_lzr*m_kx;
	p1.y = m_FJYD.y + m_fjh*m_ky;

	p2.x = m_FJYD.x + m_fjw*m_kx/2;
	p2.y = m_FJYD.y + m_fjh*m_ky + m_fjw*m_ky/2 + m_lzr*m_ky;

	p3.x = m_FJYD.x + m_fjw*m_kx + m_lzr*m_kx;
	p3.y = m_FJYD.y + m_fjh*m_ky;

	pDC->MoveTo(p1);
	pDC->LineTo(p2);
	pDC->LineTo(p3);
	pDC->LineTo(p1);//画飞机头(三角形)

	pDC->MoveTo(m_FJYD);
	x = m_FJYD.x - m_fjl*m_kx;
	y = m_FJYD.y - m_fjl*m_ky;
	pDC->LineTo(x,y);//画飞机左翼

	x = m_FJYD.x + m_fjw*m_kx;
	y = m_FJYD.y;
	pDC->MoveTo(x,y);
	x += m_fjl*m_kx;
	y -= m_fjl*m_ky;
	pDC->LineTo(x,y);//画飞机右翼	
}

7、然后创建粒子,如下图所示。

代码如下:

//创建粒子
void CFeiJiDuoBi::CreateLiZi()
{
	int i;
	int x,y;
	for(i = 0; i < m_nLZ; i++)
	{
		x = rand()%(10000 - 2*m_lzr);
 		y = rand()%(10000 - 2*m_lzr);
		m_LZ[i].pt.x = m_YD.x + (x + m_lzr)*m_kx;
		m_LZ[i].pt.y = m_YD.y + (y + m_lzr)*m_ky;

		m_LZ[i].vx = rand()%200;//速度设在-300到-200和200到300之间
		m_LZ[i].vy = rand()%200;

		if(m_LZ[i].vx < 100)
			m_LZ[i].vx -= 300;
		else
			m_LZ[i].vx += 100;
				
		if(m_LZ[i].vy < 100)
			m_LZ[i].vy -= 300;
		else
			m_LZ[i].vy += 100;	
	}
}

8、为了让飞机和粒子动起来,我们再添加两个函数,如下图所示。
(1)通过键盘上下左右键控制飞机的运动。
在这里插入图片描述
代码如下:

//移动飞机
void CFeiJiDuoBi::MoveFeiJi(int n)
{
	switch(n)
	{
	case 37:
		if(m_FJYD.x > m_YD.x + m_lzr*m_kx)
			m_FJYD.x -= 2*m_lzr*m_kx;
		break;
	case 38:
		if(m_FJYD.y > m_YD.y + 10000*m_ky - m_fjh*m_ky - m_fjw*m_ky/2 - m_lzr*m_ky)
			m_FJYD.y += 2*m_lzr*m_ky;
		break;
	case 39:
		if(m_FJYD.x < m_YD.x + 10000*m_kx - m_lzr*m_kx - m_fjw*m_kx)
			m_FJYD.x += 2*m_lzr*m_kx;
		break;
	case 40:
		if(m_FJYD.y < m_YD.y + m_lzr*m_ky)
			m_FJYD.y -= 2*m_lzr*m_ky;
		break;
	}
}

(2)移动粒子(遇边界反弹),在OnTimer中调用,如下图所示。
在这里插入图片描述
代码如下:

//移动粒子
void CFeiJiDuoBi::MoveLiZi()
{
	int i;
	for(i = 0; i < m_nLZ; i++)
	{
		m_LZ[i].pt.x += m_LZ[i].vx*dt*m_kx;
		m_LZ[i].pt.y += m_LZ[i].vy*dt*m_ky;
	}
}

9、碰撞函数,如下图所示。

(1)碰撞粒子、飞机——游戏结束
在这里插入图片描述
代码如下:

//碰撞粒子、飞机—游戏结束
int CFeiJiDuoBi::PengZhuangLiZiFeiJi()
{
	int i;
	int x,y,x1,y1;
	CPoint p;
	x = m_FJYD.x; 
	y = m_FJYD.y;
	x1 = m_FJYD.x + m_fjw*m_kx;
	y1 = m_FJYD.y + m_fjh*m_ky + m_fjw*m_ky/2;
	for(i = 0; i < m_nLZ; i++)
	{
		p.x = m_LZ[i].pt.x;
		p.y = m_LZ[i].pt.y;
		if( ((p.x >= x && p.x <= x1) ||(p.x >= x1 && p.x <= x)) && ((p.y >= y && p.y <= y1)||(p.y >= y1 && p.y <= y)) )
			return 1;//待会儿在OnTimer中调用并判断
	}
	return 0;
}

(2)碰撞粒子、边界——粒子反弹
在这里插入图片描述
代码如下:

//碰撞粒子、边界—粒子反弹
void CFeiJiDuoBi::PengZhuangLiZiBianJie()
{
	int i;
	int x,y,r;
	for(i = 0; i < m_nLZ; i++)
	{
		x = m_LZ[i].pt.x;
		y = m_LZ[i].pt.y;
		r = m_lzr*m_kx;

		if(x <= m_YD.x + r)
			m_LZ[i].vx = fabs(m_LZ[i].vx);
		if( x >= m_YD.y - r)
			m_LZ[i].vx = -fabs(m_LZ[i].vx);
		
		if(y <= m_YD.x + r)
			m_LZ[i].vy = -fabs(m_LZ[i].vy);
		if(y >= m_YD.y - r)
			m_LZ[i].vy = fabs(m_LZ[i].vy);
	}
}

10、上面代码已经写好了,现在只需添加一个菜单并在CPlaneView里调用即可实现本设计的要求。

11、添加菜单并建立类向导,如下图所示。
在这里插入图片描述
在这里插入图片描述
代码如下:

void CPlaneView::OnMStart() 
{
	// TODO: Add your command handler code here
	SetTimer(1,500,NULL);
}

void CPlaneView::OnMStop() 
{
	// TODO: Add your command handler code here
	KillTimer(1);
}

12、在CPlaneView里将“FeiJiDuoBi.h”头文件嵌入进来,并添加成员对象,如下图所示。
在这里插入图片描述
13、在OnDraw函数里调用,代码如下。

void CPlaneView::OnDraw(CDC* pDC)
{
	CPlaneDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	m_FJDB.Draw(pDC);
}

14、添加键盘消息响应函数和时钟函数,如下图所示。
在这里插入图片描述
代码如下:

void CPlaneView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	m_FJDB.MoveFeiJi(nChar);
	Invalidate(TRUE);
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CPlaneView::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	m_FJDB.MoveLiZi();
	m_FJDB.PengZhuangLiZiBianJie();
	
	if(1 == m_FJDB.PengZhuangLiZiFeiJi())
	{
		KillTimer(1);
		CString str; 
		str.Format("游戏结束!"); 
		AfxMessageBox(str);
	}
	else
		m_FJDB.m_FS++;
	Invalidate(true);
	CView::OnTimer(nIDEvent);
}

三、界面截图
在这里插入图片描述
在这里插入图片描述

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值