MFC自制小游戏中目标移动实现的两种方法
在小游戏开发中,有时会需要目标进行移动,这里介绍两种实现方法,也是自己在写小游戏时遇到的问题,自己也是找到了两种解决方法。
使用贴图的方法实现
这个方法的实现就是通过在Picture Control控件上进行贴图,每次移动时,先添加背景图,然后在添加目标在新位置的图片,这样就可以达到目标移动的效果。
1.添加游戏背景图片
//在头文件中添加
CDC*pDC;
//.cpp文件中添加
void CMainConsoleDlg::ShowMap()
{
CRect rect;
GetDlgItem(IDC_MAP)->GetWindowRect(rect);
ScreenToClient(rect);
pDC = GetDlgItem(IDC_MAP)->GetDC();
BITMAP bmpInfo;
CDC memDc;
CBitmap bmp;
bmp.LoadBitmapW(IDB_EASTSOUTH);//IDB_EASTSOUTH背景图片的ID
bmp.GetObject(sizeof(bmpInfo), &bmpInfo);
memDc.CreateCompatibleDC(pDC);
CBitmap *oldBitmap = memDc.SelectObject(&bmp);
pDC->BitBlt(0, 0, bmpInfo.bmWidth, bmpInfo.bmHeight, &memDc, 0, 0, SRCCOPY);
memDc.SelectObject(oldBitmap);
memDc.DeleteDC();
bmp.DeleteObject();
}
2.在添加背景图片之后,我们需要实现在指定位置添加目标图
void CMainConsoleDlg::ShowPoint(int x, int y)
{
GetDlgItem(IDC_MAP)->GetWindowRect(rect);
ScreenToClient(rect);
pDC = GetDlgItem(IDC_MAP)->GetDC();
BITMAP bmpInfo;
CDC memDc;
CBitmap bmp;
bmp.LoadBitmapW(IDB_BITMAP2);
bmp.GetObject(sizeof(bmpInfo), &bmpInfo);
memDc.CreateCompatibleDC(pDC);
CBitmap *oldBitmap = memDc.SelectObject(&bmp);
pDC->BitBlt(x, y, bmpInfo.bmWidth, bmpInfo.bmHeight, &memDc, 0, 0, SRCCOPY);
pDC->TextOutW(x - 10, y + 16, number);
memDc.SelectObject(oldBitmap);
memDc.DeleteDC();
bmp.DeleteObject();
}
3.生成目标点,进行移动,这里简单的实现一个移动。
void CMainConsoleDlg::MovePoint()
{
for(int i=0;i<20;i++)
{
ShowMap();
ShowPoint(i*5, i*5);
sleep(500);
}
}
使用控件来实现目标移动
虽然使用贴图的方式,可以实现目标的移动,但在一些条件下,这种方法无法满足要求,比如我们需要查看目标的信息(右键点击目标,弹出目标信息),或者为目标增加一些其他动作,这个时候需要我们使用自定义的控件类来实现。
1.创建一个新类,在类中实现一些方法,然后与指定的控件进行绑定,在控件上添加背景图片,我们使控件进行移动,从而达到目标移动的目的,此时就不需要仿佛的去更新背景图片。
这里我们对button按钮进行操作,把目标背景添加到按钮上,使按钮进行移动。自定义的新类继承自cbitmapbutton类,并进行绑定,具体方法参考以下博客:
MFC自定义button控件
在新的类中,增加控件移动函数和鼠标右键触发函数。
void MyButton::MoveTo(int x, int y)
{
CWnd* pParent = GetParent();
if (!pParent) pParent = GetDesktopWindow();
CRect ButtonRect; // Button Dimensions (Parent coords)
GetWindowRect(ButtonRect);
pParent->ScreenToClient(ButtonRect);
CPoint Center = ButtonRect.CenterPoint();
CRect NewButtonRect = ButtonRect; // New position (parent coords)
NewButtonRect += CSize(x - Center.x, y - Center.y);
MoveWindow(NewButtonRect);
RedrawWindow();
}
添加右键触发函数
头文件MyButton.h中添加:afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
MyButton.cpp中添加:
BEGIN_MESSAGE_MAP(RadarButton, CBitmapButton)
ON_WM_RBUTTONUP()//这个就是右键消息函数,必须加上,否则无法触发函数
END_MESSAGE_MAP()
这里我们就实现在右键弹窗时显示一些下拉菜单
void RadarButton::OnRButtonUp(UINT nFlags, CPoint point)
{
CMenu menu, *pmenu1, *pmenu2;
menu.LoadMenu(IDR_MENU1);//IDR_MENU1这是在项目中自定义的一个菜单
pmenu1 = menu.GetSubMenu(0);
pmenu2 = pmenu1->GetSubMenu(0);
CString strMenu;
strMenu.Format(_T("平台型号: %s"), _T("007"));
pmenu2->InsertMenu(1, MF_BYPOSITION, MF_POPUP, strMenu);
strMenu.Format(_T("平台类型: %s"), _T("战斗机"));
pmenu2->InsertMenu(2, MF_BYPOSITION, MF_POPUP, strMenu);
strMenu.Format(_T("国家: %s"), _T("中国"));
pmenu2->InsertMenu(3, MF_BYPOSITION, MF_POPUP, strMenu);
strMenu.Format(_T("用途: %s"), _T("巡航"));
pmenu2->InsertMenu(4, MF_BYPOSITION, MF_POPUP, strMenu);
ClientToScreen(&point);
pmenu1->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, point.x, point.y, this);
}
下拉菜单: