我想在MFC中创建一个动画人物,实现简单的行走,但是失败了。想问一下大家究竟是哪里出了问题。
这是人物类的头文件
#pragma once
class CMyRole
{
public:
HBITMAP m_hBmp;//创建位图句柄,保存移动的位图
//每帧位图的宽高
int m_iPerFrameWidth;//每帧位图的宽高
int m_iPerFrameHeight;
int m_iPosX, m_iPosY;//坐标
int m_iSpeedX, m_iSpeedY;//水平竖直方向的速度
int m_iFrameNum;//帧数
int m_iCurFrame;//当前帧号
int m_iDirection;//移动方向
//上up为,0,下down为1,Left-2,right-3
public:
int GetPosX() { return m_iPosX; }
int GetPosY() { return m_iPosY; }
void SetSpeedX(int iSpeedX) { m_iSpeedX = iSpeedX; }
void SetSpeedY(int iSpeedY) { m_iSpeedY = iSpeedY; }
void SetDirection(int iDirection) {
m_iDirection = iDirection;
}
void Draw(HDC hDC, int x, int y);//位图绘图
void Update();//位图更新 人物移动过程中位图要进行更新
void Init( UINT uiID, int iPerFrameWidth, int iPerFrameHeight,
int iFrameNum, int iPosX =0,int iPosY =0);//位图初始化
public:
CMyRole();
~CMyRole();
};
人物类的源文件
```c++
#include "pch.h"
#include "CMyRole.h"
CMyRole::CMyRole()
{
}
CMyRole::~CMyRole()
{
}
//位图初始化
void CMyRole:: Init(UINT uiID, int iPerFrameWidth, int iPerFrameHeight,
int iFrameNum, int iPosX , int iPosY )
{
m_hBmp = (HBITMAP)::LoadImage(::GetModuleHandle(NULL), (LPCSTR)uiID,
IMAGE_BITMAP, 0, 0, NULL);
m_iPerFrameWidth = iPerFrameWidth;
m_iPerFrameHeight = iPerFrameHeight;
m_iPosX = iPosX;
m_iPosY = iPosY;
m_iSpeedX = 0;
m_iSpeedY = 0;
m_iCurFrame = 0;
//开始运动时方向向下
m_iDirection = 1;
}
//更新人物位置信息
void CMyRole::Update()
{
m_iPosX = m_iPosX + m_iSpeedX;
m_iPosY = m_iPosY + m_iSpeedY;
}
void CMyRole::Draw(HDC hDC, int x, int y)
{ //创建兼容DC
HDC hBufDC = ::CreateCompatibleDC(hDC);
::SelectObject(hBufDC, m_hBmp);
::TransparentBlt(hDC, x, y, m_iPerFrameWidth, m_iPerFrameWidth, hBufDC,
m_iDirection * m_iPerFrameWidth, m_iCurFrame * m_iPerFrameHeight, m_iPerFrameWidth,
m_iPerFrameWidth, RGB(225, 225, 225));
m_iCurFrame = (m_iCurFrame + 1) % m_iFrameNum;
::DeleteDC(hBufDC);
}
这是在对话框类中的部分代码
```c++
//添加人物
void CFamousPersonDlg::OnAdd()
{
// TODO: 在此添加命令处理程序代码
// TODO: 在此添加命令处理程序代码
::SetTimer(this->m_hWnd,10, 40, NULL);//10为定时器的ID,定时器要响应
//WM_TIMER消息响应
Init();
}
//WM_TIMER消息响应
void CFamousPersonDlg::OnTimer(UINT_PTR nIDEvent)//传入的参数为定时器ID
{
switch (nIDEvent)
{
case 10: {
//更新调用
update();
Paint(); }
default: {break; }
}
CDialogEx::OnTimer(nIDEvent);
}
//鼠标一直按下处理函数,重新绘制背景和角色
void CFamousPersonDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//初始速度设为0
m_MyRole.SetSpeedX(0);
m_MyRole.SetSpeedY(0);
if ('W' == nChar)
{
m_MyRole.SetSpeedY(-5);
m_MyRole.SetDirection(0);
}
else if ('S' == nChar)
{
m_MyRole.SetSpeedY(5);
m_MyRole.SetDirection(1);
}
else if ('A' == nChar)
{
m_MyRole.SetSpeedX(-5);
m_MyRole.SetDirection(2);
}
else if ('D' == nChar)
{
m_MyRole.SetSpeedX(5);
m_MyRole.SetDirection(3);
}
CDialogEx::OnKeyDown(nChar, nRepCnt, nFlags);
}
//鼠标左键函数
void CFamousPersonDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
//开始键,打开提示
if (point.x >= 28 && point.x <= 202 && point.y >= 483 && point.y <= 643) {
HDC hDC = ::GetDC(this->m_hWnd);
HBITMAP hBmp = (HBITMAP)::LoadImage(::GetModuleHandle(NULL), (LPCSTR)IDB_BITMAP6, IMAGE_BITMAP, 0, 0, NULL);
HDC hMDC = ::CreateCompatibleDC(hDC);
::SelectObject(hMDC, hBmp);
::BitBlt(hDC, 0, 0, 1044, 800, hMDC, 0, 0, SRCCOPY);
::DeleteDC(hMDC);
::ReleaseDC(this->m_hWnd, hDC);
}
//音乐键
if (point.x >= 671 && point.x <= 842 && point.y >= 485 && point.y <= 656) {
PlaySound(TEXT("C:\\背景音乐.wav"), NULL, SND_FILENAME | SND_ASYNC);
}
//游戏开始
if (point.x >= 290 && point.x <= 544 && point.y >= 538 && point.y <= 652) {
PaintBG(0, 0);
}
CDialogEx::OnLButtonDown(nFlags, point);
}
//画背景
void CFamousPersonDlg::PaintBG(int x, int y)
{
HDC hDC = ::GetDC(this->m_hWnd);
HBITMAP hBmp = (HBITMAP)::LoadImage(::GetModuleHandle(NULL), (LPCSTR)IDB_BITMAP2, IMAGE_BITMAP, 0, 0, NULL);
HDC hMDC = ::CreateCompatibleDC(hDC);
::SelectObject(hMDC, hBmp);
::BitBlt(hDC, x, y,1044,800,hMDC,0,0,SRCCOPY);
::DeleteDC(hMDC);
::ReleaseDC(this->m_hWnd, hDC);
}
//画静态人物
void CFamousPersonDlg::PaintRole(int x, int y)
{
HDC hDC = ::GetDC(this->m_hWnd);
HBITMAP hBmp = (HBITMAP)::LoadImage(::GetModuleHandle(NULL), (LPCSTR)IDB_BITMAP3, IMAGE_BITMAP, 0, 0, NULL);
HDC hMDC = ::CreateCompatibleDC(hDC);
::SelectObject(hMDC, hBmp);
::TransparentBlt(hDC,x,y, 80, 106, hMDC, 0, 0, 80, 110, RGB(0, 0, 0));
//::BitBlt(hDC, x, y, 794, 551, hMDC, 0, 0, SRCCOPY);
::DeleteDC(hMDC);
::ReleaseDC(this->m_hWnd, hDC);
}
//人物开始运动
void CFamousPersonDlg::OnLookfor()
{
// TODO: 在此添加命令处理程序代码
//设置定时器
CFamousPersonDlg::Init();
::SetTimer(this->m_hWnd, 10, 40, NULL);
}
//数据更新函数
void CFamousPersonDlg::update()
{
m_MyRole.Update();
}
//人物初始化
void CFamousPersonDlg::Init()
{
m_MyRole.Init(IDB_BITMAP8, 80,106, 3, 430, 260);//最后两个参数为初始位置 ,倒数第三个参数是帧数
}
//绘制人物
void CFamousPersonDlg::Paint() {
//每次调用都绘制背景和人物
HDC hDC = ::GetDC(this->m_hWnd);
PaintBG(0, 0);
//绘制人物
m_MyRole.Draw(hDC, m_MyRole.GetPosX(), m_MyRole.GetPosY());
::ReleaseDC(this->m_hWnd,hDC);
}
这是人物图,即代码中的位图8.
感谢大家。
重绘时候有调用Invalidate()或者UpdateWindow()吗,而且绘图要放在OnPaint()里吧
MFC中一个对话框类CDailog1要访问另外一个对话框类CDailog2对象的成员变量,这就需要获得对话框类CDailog2的对象的指针,有好几种方法可以实现,如维护一个单例模式、设置静态变量等。
本文设置以静态变量的方法为例,实现对两个对话框之间数据访问。
一、创建MFC对话框程序
1.首先创建一个MFC对话框应用程序,命名为Test工程.
2.对话框本身有一个主界面(CTestDlg对话框),那我们再添加一个新界面CXXXDlg.
3.在主对话框(CTestDlg)上添加一个picture控件 ,对应变量名为ImageShowRect。
二、在CTestDlg.h文件中,添加对话框指针变量的声明
static CTestDlg *pTestdlg;
三、在CTestDlg .cpp文件中,写上一行初始化代码,直接初始化为空
CTestDlg *CTestDlg::pTestdlg = NULL; //注意要写在类外,不要写在类实现函数里面。
注意:
由于这个指针是静态的,我们需要在类外初始化。
四、然后要在CTestDlg.cpp文件的OnInitDialog()函数里面写上如下一句代码
pTestdlg = this; //为这个之前定义的指针变量赋值为主对话框指针
*说明:
现在我们只要在其他的类里面获得这个静态指针,就可以访问这个类里面的所有数据了~~~~*
五、获得静态指针
假设,我们想在CXXXDlg类中访问CTestDlg类的m_ImageShowRect变量,只需要在CXXXDlg.cpp文件的具体某个功能的实现函数中添加如下代码
void CXXXDlg::showimage()
{
CTestDlg *pdlg = CTestDlg::pTestdlg ;
pdlg->m_ImageShowRect.GetClientRect(&clRect);
...
...
}
说明:
m_ImageShowRect为主对话框TestDlg中picture控件的捆绑变量。
End!