MFC制作的一个简单的跑酷游戏(gdi+)(使用智能指针)

该程序的图片资源是借用网上一位大神的

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;
}


做出来的效果如下


下面是图片资源




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值