该程序的图片资源是借用网上一位大神的
1.建立一个基于对话框的程序,命名为parkour
使用智能指针需包含头文件memory
2.添加类CCharacter和CScene
#pragma once
#include<vector>
using std::vector;
class CCharacter
{
public:
CCharacter();
~CCharacter();
private:
static const int ELEVATION = 20;//背景土地高度
static const int MAXFRAME = 16;//人物奔跑有16幅画面
private:
Rect m_rect;//绘图位置
int m_curFrame;
vector<std::shared_ptr<Image>>m_imgCharacter;
void MoveFront(Rect rc);//前进
void NextFrame();//下一帧
public:
void DrawCharacter(Graphics& gh,Rect rc);
};
#include "stdafx.h"
#include "Character.h"
CCharacter::CCharacter()
{
CString path;
for (int i = 1; i <= MAXFRAME; i++)
{
path.Format(_T("res\\%d.png"), i);
m_imgCharacter.push_back(std::shared_ptr<Image>(Image::FromFile(path)));
}
m_rect.Width = m_imgCharacter[0]->GetWidth();
m_rect.Height = m_imgCharacter[0]->GetHeight();
m_rect.X = 0;
m_curFrame = 0;
}
CCharacter::~CCharacter()
{
}
void CCharacter::MoveFront(Rect rc)
{//人运动到中心不再运动
int border = (rc.Width - m_rect.Width) / 2;
if (m_rect.X <= border)
m_rect.X += 4;
}
void CCharacter::NextFrame()
{
m_curFrame++;
if (m_curFrame == MAXFRAME)
{
m_curFrame = 0;
}
}
void CCharacter::DrawCharacter(Graphics& gh,Rect rc)
{
m_rect.Y = rc.Height - ELEVATION-m_rect.Height;
gh.DrawImage(m_imgCharacter[m_curFrame].get(), m_rect);
NextFrame();
MoveFront(rc);
}
#pragma once
class CScenee
{
public:
CScenee();
~CScenee();
private:
std::shared_ptr<Image>m_imgStt;//起始背景
std::shared_ptr<Image>m_imgNxt;//滚动背景
int m_bgX;//起始x坐标
bool m_isStart;
void MoveBg();//背景移动
public:
void DrawScene(Graphics& gh,Rect rc);
};
#include "stdafx.h"
#include "Scenee.h"
CScenee::CScenee()
{
m_imgStt = std::shared_ptr<Image>(Image::FromFile(_T("res\\bgStart.jpg")));
m_imgNxt = std::shared_ptr<Image>(Image::FromFile(_T("res\\bgNext.jpg")));
if (!m_imgStt&&!m_imgNxt)
{
return ;
}
m_isStart = true;
m_bgX = 0;
}
CScenee::~CScenee()
{
}
void CScenee::MoveBg()
{
m_bgX -= 6;
}
void CScenee::DrawScene(Graphics& gh, Rect rc)
{
MoveBg();
if (m_bgX <= -rc.Width)
{
m_bgX = 0;
if(m_isStart)
{
m_isStart = false;
}
}
rc.X = m_bgX;
if (m_isStart)
{
gh.DrawImage(m_imgStt.get(), rc);
}
else
{
gh.DrawImage(m_imgNxt.get(), rc);
}
rc.X += rc.Width;
gh.DrawImage(m_imgNxt.get(), rc);
}
背景是用两张图拼接起来的
3.在对话框类中添加私有成员
private:
Rect rc;
void Draw();
CCharacter m_character;
CScenee m_scenee;
初始化中添加如下代码
CRect rect;
GetClientRect(&rect);
rc.X = rect.left;
rc.Y = rect.top;
rc.Width = rect.Width();
rc.Height = rect.Height();
SetTimer(1, 10, NULL);
添加WM_TIMER和Draw()函数
void CparkourDlg::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
Draw();
CDialogEx::OnTimer(nIDEvent);
}
void CparkourDlg::Draw()
{
HDC hdc = ::GetDC(GetSafeHwnd());
CDC* pDC = CClientDC::FromHandle(hdc);//获取窗口DC
CDC m_dcMemory;//缓冲DC
CBitmap bmp;//缓冲位图
bmp.CreateCompatibleBitmap(pDC, rc.Width, rc.Height);//创建位图
m_dcMemory.CreateCompatibleDC(pDC);//缓冲DC初始化
CBitmap* pOldBitmap = m_dcMemory.SelectObject(&bmp);//将位图和缓存DC关联
//gdi+绘图
Graphics gh(m_dcMemory.GetSafeHdc());
//绘图代码
{
m_scenee.DrawScene(gh,rc);
m_character.DrawCharacter(gh,rc);
}
::BitBlt(hdc, 0, 0, rc.Width, rc.Height, m_dcMemory.GetSafeHdc(), 0, 0, SRCCOPY);//将缓存DC的内容复制到屏幕
pDC->DeleteDC();
m_dcMemory.SelectObject(pOldBitmap);
ReleaseDC(&m_dcMemory);
DeleteObject(bmp);
}
4.添加WM_NCHITEST消息
LRESULT CparkourDlg::OnNcHitTest(CPoint point)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
return HTCAPTION;
}
做出来的效果如下
下面是图片资源