C++学习 2018-12-7

1.继续完成飞机大战

1.继续完成back背景类

1.要贴图的话就需要先导入资源文件,选择 解决方案中的资源文件,右键添加->资源->BitMap,找到要添加的位图文件。

1)这里涉及到一个问题,我们需要保证我们的可执行文件能够在我们自己的电脑上运行,也能够在他人的电脑上运行,因此,在添加资源文件时,需要注意资源文件的路径问题(最好修改为相对路径)。

2.设计back类的成员,设计为两个 HBITMAP 成员来保存背景图,并且定义背景的横纵坐标。
3.back类需要有三个成员函数:

1)初始化背景
2)移动背景
3)显示背景

1)初始化背景需要进行加载位图,将加载的背景位图赋值给两个位图句柄;
2)移动背景需要判断背景的y坐标,若y>550,则将y置零(背景位图大小为550x380);
3)显示背景需要创建兼容性dc,再将位图选择进兼容性dc,再复制位图;

#include "Back.h"


CBack::CBack(void)
{
	x = 0;									// 初始化成员
	y = 0;
	m_hBmpBackDown = 0;
	m_hBmpBackUp = 0;
}

CBack::~CBack(void)
{
	::DeleteObject(m_hBmpBackUp);			// 删除位图,释放空间
	::DeleteObject(m_hBmpBackDown);
}

void CBack::InitBack(HINSTANCE h_ins)
{
	m_hBmpBackDown = ::LoadBitmap(h_ins, MAKEINTRESOURCE(IDB_BACK));		// 加载位图
	m_hBmpBackUp = ::LoadBitmap(h_ins, MAKEINTRESOURCE(IDB_BACK));
}

void CBack::MoveBack()
{
	if(y > 550)							// 向下一直移动背景图,x、y为背景图左上角坐标
		y = 0;
	else
	{
		y++;
	}
}

void CBack::ShowBack(HDC dc)
{
	HDC map_dc = ::CreateCompatibleDC(dc);							// 创建兼容性dc
	::SelectObject(map_dc, m_hBmpBackUp);							// 选择 上背景图 句柄
	::BitBlt(dc, x, y-550, 280, 550, map_dc, 0, 0, SRCCOPY);		// 将 上背景图 拷贝到dc中
	::SelectObject(map_dc, m_hBmpBackDown);							// 选择 下背景图 句柄
	::BitBlt(dc, x, y, 380, 550, map_dc, 0, 0, SRCCOPY);			// 将 下背景图 拷贝到dc中
	::DeleteDC(map_dc);												// 删除兼容性dc
}
4.完成back类之后,需要调用back类来显示背景。

1)在PlaneApp中创建 back类对象;
2)PlaneApp类中重写 OnCreateGame、OnGameShow、OnGameRun以及OnGameKeyDown 四个虚函数;
3)在 OnCreateGame 函数中调用 back 的初始化函数 back.InitBack(m_h_ins) ,参数为GameApp中定义的实例句柄;
4)在 OnCreateGame 函数中设置一个控制背景移动速度的定时器,定时器编号在 CommonInclude 文件中定义为宏:#define BACK_MOVE_TIMER_ID 1
5)在 OnGameShow 函数中先获得dc,再调用 back.ShowBack(dc) 来显示背景;
6)在 OnGameRun 函数中判断输入的消息是否为控制背景移动的定时器 BACK_MOVE_TIMER_ID,若是,则 back.MoveBack();

7)完整的PlaneApp.cpp

#include "PlaneApp.h"


IMPLEMENT(CPlaneApp)

CPlaneApp::CPlaneApp(void)
{
}


CPlaneApp::~CPlaneApp(void)
{
}

void CPlaneApp::OnCreateGame()
{
	// 1.初始化背景
	back.InitBack(m_h_ins);

	// 2.启动定时器
	::SetTimer(m_hwnd, BACK_MOVE_TIMER_ID, 100, 0);
}

void CPlaneApp::OnGameShow()
{
	HDC dc = GetDC(m_hwnd);							// GetDC对应ReleaseDC

	back.ShowBack(dc);
	
	::ReleaseDC(m_hwnd, dc);
}

void CPlaneApp::OnGameRun(WPARAM w_param)
{
	if(w_param == BACK_MOVE_TIMER_ID)
	{
		back.MoveBack();
	}

	this->OnGameShow();
}

void CPlaneApp::OnGameKeyDown(WPARAM w_param)
{
}

2.完成Player类来显示玩家飞机

1.创建一个 Player类,该类不用继承任何其他类。
2.定义该类的成员 HBITMAP m_hBmpPlayer、int m_nGunnerStyle、int x、int y 分别表示飞机的位图句柄、子弹的风格(暂时无用,可以不设置)以及飞机位图的左上角坐标。
3.该类的成员函数与back类类似,有三个:InitPlayer、MovePlayer以及ShowPlayer。
4.在Player的构造函数中,我们让飞机的起始位置在窗口的下部中间位置,可设置 x=160,y=490。
5.InitPlayer 函数用来加载飞机位图。
6.MovePlayer 函数用来移动飞机(即改变飞机左上角的位置)。
7.ShowPlayer 函数用来显示飞机。

Player类的实现

#include "Player.h"


CPlayer::CPlayer(void)
{
	m_hBmpPlayer = 0;
	m_nGunnerStyle = 0;
	x = 160;
	y = 490;
}

CPlayer::~CPlayer(void)
{
	::DeleteObject(m_hBmpPlayer);
}

void CPlayer::InitPlayer(HINSTANCE hIns)
{
	m_hBmpPlayer = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_HERO));
}

void CPlayer::MovePlayer(int FX)
{
	if(FX == VK_LEFT)				// 因为VK_LEFT是宏定义,且其实质上是一个int型的数,FX用来表示接受到的按键消息
	{
		if(x > 0)
			x -= 2;
	}

	if(FX == VK_RIGHT)
	{
		if(x < 320)
			x += 2;
	}

	if(FX == VK_DOWN)
	{
		if(y < 490)
			y += 2;
	}

	if(FX == VK_UP)
	{
		if(y > 0)
			y -= 2;
	}
}

void CPlayer::ShowPlayer(HDC dc)
{
	HDC map_dc = ::CreateCompatibleDC(dc);
	::SelectObject(map_dc, m_hBmpPlayer);
	::BitBlt(dc, x, y, 60, 60, map_dc, 0, 0, SRCAND);
	::DeleteDC(map_dc);
}
8.显示玩家飞机

1)在PlaneApp中创建player类对象;
2)在 OnCreateGame 函数中初始化玩家飞机,player.InitPlayer(m_h_ins);
3)为玩家飞机移动设置一个定时器,编号为 PLAYER_MOVE_TIMER_ID;
4)在 OnGameShow 函数中调用 player.ShowPlayer(dc) 来显示玩家飞机;
5)在 OnGameRun 函数中判断传入的消息是否是 PLAYER_MOVE_TIMER_ID,若是再判断输入的按键是哪个按键。

6)增加飞机后的PlaneApp实现类如下:

#include "PlaneApp.h"


IMPLEMENT(CPlaneApp)

CPlaneApp::CPlaneApp(void)
{
}


CPlaneApp::~CPlaneApp(void)
{
}

void CPlaneApp::OnCreateGame()
{
	// 1.初始化背景
	back.InitBack(m_h_ins);

	// 2.初始化玩家飞机
	player.InitPlayer(m_h_ins);
	
	// 3.启动所有的定时器
	::SetTimer(m_hwnd, BACK_MOVE_TIMER_ID, 100, 0);
	::SetTimer(m_hwnd, PLAYER_MOVE_TIMER_ID, 1, 0);
}

void CPlaneApp::OnGameShow()
{
	HDC dc = GetDC(m_hwnd);

	back.ShowBack(dc);
	player.ShowPlayer(dc);
	
	::ReleaseDC(m_hwnd, dc);
}

void CPlaneApp::OnGameRun(WPARAM w_param)
{
	if(w_param == PLAYER_MOVE_TIMER_ID)
	{
		if(::GetAsyncKeyState(VK_LEFT))
			player.MovePlayer(VK_LEFT);
		if(::GetAsyncKeyState(VK_RIGHT))
			player.MovePlayer(VK_RIGHT);
		if(::GetAsyncKeyState(VK_DOWN))
			player.MovePlayer(VK_DOWN);
		if(::GetAsyncKeyState(VK_UP))
			player.MovePlayer(VK_UP);
	}

	if(w_param == BACK_MOVE_TIMER_ID)
	{
		back.MoveBack();
	}

	this->OnGameShow();
}

void CPlaneApp::OnGameKeyDown(WPARAM w_param)
{

3.显示飞机子弹

1.与显示背景和玩家飞机几乎完全相同,先创建一个子弹类Gunner,不用继承其他类。
2.公有成员有:子弹位图句柄HBITMAP m_hBmpGunner、子弹的横纵坐标。
3.成员函数也是三个:InitGuuner、MoveGunner、ShowGunner。
4.在Gunner的构造函数中设置句柄为null,横纵坐标为飞机的上面一点。
5.在初始化函数 InitGuuner 中载入图像。
6.暂时不对移动子弹函数进行设计,先让子弹能够显示出来。
7.在显示函数 ShowGunner 中将子弹位图拷贝到dc上。
8.具体实现代码:
#include "Gunner.h"


CGunner::CGunner(void)
{
	m_hBmpGunner = 0;
	x = 187;
	y = 481;
}

CGunner::~CGunner(void)
{
	::DeleteObject(m_hBmpGunner);
}

void CGunner::	(HINSTANCE hIns, int new_x, int new_y)
{
	m_hBmpGunner = ::LoadBitmap(hIns, MAKEINTRESOURCE(IDB_GUNNER));
}

void CGunner::MoveGunner()
{
}

void CGunner::ShowGunner(HDC dc)
{
	HDC map_dc = ::CreateCompatibleDC(dc);
	::SelectObject(map_dc, m_hBmpGunner);
	::BitBlt(dc, x, y, 6, 9, map_dc, 0, 0, SRCCOPY);
	::DeleteDC(map_dc);
}

4.下一步我们需要将子弹进行自主移动。

--------------------------------未完待续---------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值