小球遇屏幕边界反弹(VC6.0—MFC)

小球遇屏幕边界反弹(VC++6.0——MFC)

题目:在视图中画个圆,设定好圆的初始运动速度,碰到边框后可以反弹。
步骤
1、打开VC6.0,点击屏幕左上角“文件(F)”,选择“新建(N)… Ctrl_N”。
2、在弹出的对话框中,选择“工程 >> MFC AppWizard(exe)”,选择创建工程的位置并给工程命名,点击“确定”。
3、选择“单文档(S)”,点击“完成”,点击“确定”,如下图所示。
在这里插入图片描述
4、画一个填充圆,如下图所示。
在这里插入图片描述
代码如下:

void CExercise1View::DrawCircle(CDC *pDC, CPoint Center, int radius)
{
	CBrush brush, *pOldBrush; //旧画刷的指针
	brush.CreateSolidBrush(RGB(255,0,0));
	pOldBrush = pDC->SelectObject(&brush);
	pDC->Ellipse(Center.x - radius,Center.y - radius,Center.x + radius,Center.y + radius);
	brush.DeleteObject();
	pDC->SelectObject(pOldBrush);
}

5、定义一个圆的结构体,如下图所示。
在这里插入图片描述
代码如下:

typedef struct
{
	POINT center; //定义圆心
	int radius; //定义半径
	int vx,vy; //定义小球速度v大小和方向
}MyCircle; //定义圆对象

/****************************************************************************************************************/
在OnDraw()中调用圆:
DrawCircle(pDC,CPoint(m_circle.center.x,m_circle.center.y),m_circle.radius);

6、添加菜单并COMMAND,如下图所示。
在这里插入图片描述
7、碰撞检测条件判定,如下图所示。
在这里插入图片描述
代码如下:

void CExercise1View::CircleMoveAdjust(MyCircle &circle, RECT rect) //&为引用
{
	if(circle.center.y + circle.radius >= rect.bottom)
	{
		circle.vy = -circle.vy;
	} //碰底
	if(circle.center.x + circle.radius >= rect.right)
	{
		circle.vx = -circle.vx;
	} //碰右
	if(circle.center.y - circle.radius <= rect.top)
	{
		circle.vy = -circle.vy;
	} //碰顶
	if(circle.center.x - circle.radius <= rect.left)
	{
		circle.vx = -circle.vx;
	} //碰左
	return;
}

8、初始化小球位置、半径大小及速度大小,如下图所示。
在这里插入图片描述
代码如下:

CExercise1View::CExercise1View()
{
	// TODO: add construction code here
	m_circle.center.x = 300; m_circle.center.y = 200;
	m_circle.radius = 10;
	m_circle.vx = m_circle.vy = 10; //球的水平和竖直两个方向的分速度,速度v=10*sqrt(2)
   //当小球速度和半径相等的话,碰撞检测是非常准确的
}

9、在OnTimer()中实现定时控制,如下图所示。
在这里插入图片描述
代码如下:

void CExercise1View::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	GetClientRect(&m_rect); //获得屏幕显示区域大小结构体
	CircleMoveAdjust(m_circle,m_rect);
	m_circle.center.x += m_circle.vx;
	m_circle.center.y -= m_circle.vy; //改变当前小球的位置
	Invalidate(true);
	CView::OnTimer(nIDEvent);
}

10、运行结果,如下图所示。
在这里插入图片描述

在这里插入图片描述
可随意拖动改变屏幕大小,都能使小球遇到屏幕边界时反弹。

MFC可以利用CDC类提供的绘图函数来进行小球的绘制操作。反弹可以通过控制小球的移动方向和速度,在小球碰到边界时改变方向实现。具体实现步骤如下: 1. 定义小球的结构体包括小球在窗口中的位置、半径、运动方向和速度等属性。 ```c++ struct Ball { int x, y; // 小球中心坐标 int r; // 小球半径 int dx, dy; // 小球运动方向 int speed; // 小球运动速度 }; ``` 2. 在窗口的OnPaint函数中进行小球的绘制操作,使用CDC::Ellipse函数绘制一个实心圆来表示小球。 ```c++ CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here // Do not call CWnd::OnPaint() for painting messages // 创建画刷对象 CBrush brush(RGB(255, 0, 0)); // 选择画刷对象 CBrush* pOldBrush = dc.SelectObject(&brush); // 绘制小球 dc.Ellipse(ball.x - ball.r, ball.y - ball.r, ball.x + ball.r, ball.y + ball.r); // 恢复画刷对象 dc.SelectObject(pOldBrush); ``` 3. 在窗口的OnTimer函数中控制小球运动和碰撞检测。根据小球的位置和运动方向、速度可以计算出小球下一时刻的位置,如果小球超出窗口的边界,则改变运动方向。 ```c++ void CMyMFCBallDlg::OnTimer(UINT_PTR nIDEvent) { // TODO: Add your message handler code here and/or call default ball.x += ball.dx * ball.speed; ball.y += ball.dy * ball.speed; // 检测小球是否超出窗口边界 if (ball.x - ball.r < 0 || ball.x + ball.r > m_clientRect.right) { ball.dx = -ball.dx; } if (ball.y - ball.r < 0 || ball.y + ball.r > m_clientRect.bottom) { ball.dy = -ball.dy; } // 刷新窗口 Invalidate(); CDialogEx::OnTimer(nIDEvent); } ``` 4. 在窗口的OnInitDialog函数中设置定时器,开启小球运动。 ```c++ BOOL CMyMFCBallDlg::OnInitDialog() { CDialogEx::OnInitDialog(); // TODO: Add extra initialization here SetTimer(1, 50, NULL); // 初始化小球 ball.x = m_clientRect.right / 2; ball.y = m_clientRect.bottom / 2; ball.r = 20; ball.dx = 1; ball.dy = 1; ball.speed = 5; return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } ``` 这样就可以实现小球在窗口中运动,并在碰到边界反弹。可以根据实际需要调整小球运动速度、窗口大小和小球的大小等参数。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值