【VC++游戏开发#十】2D篇 —— 人工智能(一):滚动地图 & 用鼠标控制人物的走动
2014-01-09 16:09
791 查看
本文由BlueCoder编写 转载请说明出处:http://blog.csdn.net/crocodile__/article/details/18039107
我的邮箱:bluecoder@yeah.net 欢迎大家和我交流编程心得我的微博:BlueCoder_黎小华 欢迎光临^_^
和大家交流一下哈:
我最近,一直在思考一个问题:接下来的游戏效果的模拟,我到底是继续用MFC,还是转向Win32SDK呢?MFC能提供一个现成的框架,还有丰富的类库,很方便,但是效率:不算差也不算高吧,毕竟MFC封装了很多我们用不到的功能;Win32SDK,就不用多说,就是效率好,更接近底层,但是着实没有MFC那么方便。作为一个追求效率的、但又喜欢"偷点儿懒"的我,经过这么一想,就萌出了一个idea:可不可以用C++、Win32SDK效仿MFC框架来架构一个简易的框架呢,使这个框架能结合Win32SDK使用MFC类库,并能用C++面向对象的编程思想来写接下来的游戏效果。这样,就是取二者之长,更加适合windows游戏编程。听起来好像还不错哈,有个好消息是:这个简易的框架,我已经基本上架构好了,正在测试阶段,相信过两天就能发布了——当然,绝对的开源^_^
BlueCoder
2014/01/15注
Hello,大家好^_^漫长的期末考试总算结束,终于有时间继续做自己喜欢的事儿了——今天,继续我们的游戏梦想……
最近,有款端游很受欢迎哈,腾讯推出的一款3D竞技端游——英雄联盟(LOL),想必很多朋友应该玩过吧。不过说实话,我没玩过,但看过室友玩过(因为我不喜欢玩游戏,这似乎听起来挺别扭的——一个喜欢研究游戏开发的,却不喜欢玩儿^_^)
F话不多说了,在这款(或类似的)端游中,我们经常会看见一个场景:用鼠标控制自己的角色走动
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/3984c8e5ead5f3ccef0d64032e0950ec)
[align=left]就像上图所示一样,当你用鼠标点击屏幕任意位置时,这个角色就会自动按照你指定的方向走动,并且能滚动地图[/align][align=left]
[/align][align=left]对,我今天就来和大家谈谈我对这个效果的看法以及实现思路[/align][align=left]
[/align][align=left]下面,进入今天的话题[/align][align=left][/align]一、效果演示
还是先来看看效果截图,一睹为快:
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/e49c57245f6a348b3f9426af65d4eed9)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/97fa0cd3addfa932c18baaf51d7ec640)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/29dcfcd7a6086d67804364cd34a22059)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/c3651ce0cef50f0acdba563a7ed880ba)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/7c08c9a861ed3b71cefa9bb34ea8dcb2)
可以看见,人物总是朝着鼠标点击的位置走动,并且地图也随着智能的滚动,至少初步上,是实现了我们预期的效果二、准备工作
1、准备一张大地图,以及人物在8个方向上走动的分解图2、一首动听的背景音乐3、类视图
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/4807bb8adfbd249638106db703c97466)
三、实现细节
主要的实现细节有两大点:如何让人物根据你鼠标左键点击的位置来判断方向并智能地走动,以及如何智能地滚动背景——下面,我将详细地介绍
1、如何智能地滚动地图背景(这里为了简单起见,只实现了水平方向上的滚动)
1>我的思路是根据人物当前所在的位置来判断(一段伪代码):
if(人物的x坐标处在窗口中央)
{
if(人物向右走 && 地图未达到右边界)
向左滚动地图;
if(人物向左走 && 地图未达到左边界)
向右滚动地图;
}
else
{
此时只需要移动人物;
}
2>再来看一张,BlueCoder为大家绘制的示意图,帮助理解
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/bfbb52e6bac7dc1dadc7292285e12e8a)
[align=center]
[/align][align=left]
[/align][align=left]3>最后看看实现的代码:[/align]
2、如何根据鼠标点击的位置来判断人物移动的方向以及移动速度分量
1>移动速度分量的计算
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/a0c1c79891bcc3835992276a98f8ce65)
结合实际实现代码来理解:
/*
*函数功能:计算人物移动速度(mx、my)
*参数:dest——鼠标左键点击的坐标,目标位置
*/
void CRole::SetMXY(CPoint dest)
{
CPoint org;//原点
int w = m_img.GetWidth() / MAXFRAME;//人物宽度
int h = m_img.GetHeight() / MAXFRAME;//人物高度
//设置原点为人物下边中心位置
org.SetPoint(
m_role.x + w / 2,
m_role.y + h);
/*目标点与原点在垂直于x轴直线上
(这时dest.x == org.x,不能用atan求出angle)*/
if(dest.x == org.x)
{
m_role.mx = 0;
m_role.my = dest.y > org.y ? SPEED : -SPEED;
}
else
{
//求助夹角angle
double angle = atan(1.0 *
(dest.y - org.y ) / (dest.x - org.x));
//根据夹角将速度分解为x轴和y轴上的移动速度
m_role.mx = (int)fabs((cos(angle) * SPEED));
m_role.my = (int)fabs((sin(angle) * SPEED));
//反向
if(dest.x < org.x)
m_role.mx = -m_role.mx;
//反向
if(dest.y < org.y)
m_role.my = -m_role.my;
}
}
2>方向的判断,由于窗口默认的坐标系与实际的笛卡尔坐标系不同,因此需要先将窗口中求得夹角angle转换为笛卡尔坐标系中对应的弧度角
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/c6067cde3fafd5e9a758cac7d7865ea2)
实现代码如下:
//求得移动方向的角度angle(以原点(0, 0)为参照点)
double angle = atan(1.0 * m_role.my / m_role.mx);
//将求得的angle转换为笛卡尔坐标系中对应的弧度角
if(angle > 0)
{
angle = 2*PI - angle;
if(m_role.mx < 0)
{
angle -= PI;
}
}
else if(angle == 0)
{
if(m_role.mx < 0)
{
angle = PI;
}
}
else
{
angle = -angle;
if(m_role.my > 0)
{
angle += PI;
}
}
3>转换后的弧度角在[0, 2π),因此除以(2π / 8) ,再取整,就能得到[0, 15]之间的正整数dtn,根据dtn的值便能确定人物移动的方向(具体如下)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/2c2b35064e50b543d75fab61af8dc86f)
实现代码如下:
/*
将angle分为16等份,除以PI/8,再取整
dtn就是[0, 15]范围中的正整数
*/
int dtn = (int)(angle / (PI / 8));
//求得方向
switch(dtn)
{
case 15:
case 0://东
m_role.dtn = EAST;
break;
case 1:
case 2://东北
m_role.dtn = NORTHEAST;
break;
case 3:
case 4://北
m_role.dtn = NORTH;
break;
case 5:
case 6://西北
m_role.dtn = NORTHWEST;
break;
case 7:
case 8://西
m_role.dtn = WEST;
break;
case 9:
case 10://西南
m_role.dtn = SOUTHWEST;
break;
case 11:
case 12://南
m_role.dtn = SOUTH;
break;
case 13:
case 14://东南
m_role.dtn = SOUTHEAST;
break;
}
也许,你可能这会儿看的有点儿晕(当然,如果能明白,那就最好不过了),没关系
主要是,我觉得很久没写博客了,想做一个较为完整的Demo——按照实际,本节内容应该分为两次讲解,不过,我相信大家能渐渐地明白——我也是这样,慢慢儿琢磨琢磨,总会明白的^
四、代码剖析
老规矩,这次呢,BlueCoder封装了两个类:CScene(地图场景类)和CRole(人物角色类)(代码注有详尽注释,就直接贴出来好了)
1、CScene(负责地图的管理、背景音乐的播放)
1>Scene.h头文件的定义
2>具体的成员函数实现
2、CRole(人物角色的控制)1>Role.h头文件定义
2>具体的成员函数实现( 实现细节 中贴出来的代码就不重复出现在这里了)
3、View窗口类中来管理整个程序的运行逻辑1>头文件重要的定义部分
2>重要的函数实现部分
五、零积分资源下载点击下载源代码工程
呵呵,其实说来惭愧,目前为止,我还没有正式地看过一本有关游戏开发的书籍——都只是在csdn上逛逛博客,当灵感来的时候,就写一写代码,然后发布博文——其实,也主要是上学期太忙,大三的专业课很多,所以导致这个现象……因此呢,我决定好好地看几本书了,等到学业已成之时,再来和大家分享自己的所学所得^_^
最后,还是送上一句话(与大家共勉):
给自己的想法和梦想一次破茧而出的机会,亲手创造属于你自己的幸福
![](https://oscdn.geek-share.com/Uploads/Images/Content/201401/7f86c5f27ac1b50510cae5fc0dbaee10)
加油,EveryBody!!!
我的邮箱:bluecoder@yeah.net 欢迎大家和我交流编程心得我的微博:BlueCoder_黎小华 欢迎光临^_^
和大家交流一下哈:
我最近,一直在思考一个问题:接下来的游戏效果的模拟,我到底是继续用MFC,还是转向Win32SDK呢?MFC能提供一个现成的框架,还有丰富的类库,很方便,但是效率:不算差也不算高吧,毕竟MFC封装了很多我们用不到的功能;Win32SDK,就不用多说,就是效率好,更接近底层,但是着实没有MFC那么方便。作为一个追求效率的、但又喜欢"偷点儿懒"的我,经过这么一想,就萌出了一个idea:可不可以用C++、Win32SDK效仿MFC框架来架构一个简易的框架呢,使这个框架能结合Win32SDK使用MFC类库,并能用C++面向对象的编程思想来写接下来的游戏效果。这样,就是取二者之长,更加适合windows游戏编程。听起来好像还不错哈,有个好消息是:这个简易的框架,我已经基本上架构好了,正在测试阶段,相信过两天就能发布了——当然,绝对的开源^_^
BlueCoder
2014/01/15注
Hello,大家好^_^漫长的期末考试总算结束,终于有时间继续做自己喜欢的事儿了——今天,继续我们的游戏梦想……
最近,有款端游很受欢迎哈,腾讯推出的一款3D竞技端游——英雄联盟(LOL),想必很多朋友应该玩过吧。不过说实话,我没玩过,但看过室友玩过(因为我不喜欢玩游戏,这似乎听起来挺别扭的——一个喜欢研究游戏开发的,却不喜欢玩儿^_^)
F话不多说了,在这款(或类似的)端游中,我们经常会看见一个场景:用鼠标控制自己的角色走动
[align=left]就像上图所示一样,当你用鼠标点击屏幕任意位置时,这个角色就会自动按照你指定的方向走动,并且能滚动地图[/align][align=left]
[/align][align=left]对,我今天就来和大家谈谈我对这个效果的看法以及实现思路[/align][align=left]
[/align][align=left]下面,进入今天的话题[/align][align=left][/align]一、效果演示
还是先来看看效果截图,一睹为快:
可以看见,人物总是朝着鼠标点击的位置走动,并且地图也随着智能的滚动,至少初步上,是实现了我们预期的效果二、准备工作
1、准备一张大地图,以及人物在8个方向上走动的分解图2、一首动听的背景音乐3、类视图
三、实现细节
主要的实现细节有两大点:如何让人物根据你鼠标左键点击的位置来判断方向并智能地走动,以及如何智能地滚动背景——下面,我将详细地介绍
1、如何智能地滚动地图背景(这里为了简单起见,只实现了水平方向上的滚动)
1>我的思路是根据人物当前所在的位置来判断(一段伪代码):
if(人物的x坐标处在窗口中央)
{
if(人物向右走 && 地图未达到右边界)
向左滚动地图;
if(人物向左走 && 地图未达到左边界)
向右滚动地图;
}
else
{
此时只需要移动人物;
}
2>再来看一张,BlueCoder为大家绘制的示意图,帮助理解
[align=center]
[/align][align=left]
[/align][align=left]3>最后看看实现的代码:[/align]
//如果人物x坐标在中央 if(m_role.IsCenter()) { int mx = m_role.GetXMove(); //移动背景 if(mx > 0 && !m_scene.IsRightBorder() || mx < 0 && !m_scene.IsLeftBorder()) { moveRoleX = false; m_scene.MoveScene(-mx); } } //移动人物 m_role.MoveRole(moveRoleX); m_role.NextFrame();
2、如何根据鼠标点击的位置来判断人物移动的方向以及移动速度分量
1>移动速度分量的计算
结合实际实现代码来理解:
/*
*函数功能:计算人物移动速度(mx、my)
*参数:dest——鼠标左键点击的坐标,目标位置
*/
void CRole::SetMXY(CPoint dest)
{
CPoint org;//原点
int w = m_img.GetWidth() / MAXFRAME;//人物宽度
int h = m_img.GetHeight() / MAXFRAME;//人物高度
//设置原点为人物下边中心位置
org.SetPoint(
m_role.x + w / 2,
m_role.y + h);
/*目标点与原点在垂直于x轴直线上
(这时dest.x == org.x,不能用atan求出angle)*/
if(dest.x == org.x)
{
m_role.mx = 0;
m_role.my = dest.y > org.y ? SPEED : -SPEED;
}
else
{
//求助夹角angle
double angle = atan(1.0 *
(dest.y - org.y ) / (dest.x - org.x));
//根据夹角将速度分解为x轴和y轴上的移动速度
m_role.mx = (int)fabs((cos(angle) * SPEED));
m_role.my = (int)fabs((sin(angle) * SPEED));
//反向
if(dest.x < org.x)
m_role.mx = -m_role.mx;
//反向
if(dest.y < org.y)
m_role.my = -m_role.my;
}
}
2>方向的判断,由于窗口默认的坐标系与实际的笛卡尔坐标系不同,因此需要先将窗口中求得夹角angle转换为笛卡尔坐标系中对应的弧度角
实现代码如下:
//求得移动方向的角度angle(以原点(0, 0)为参照点)
double angle = atan(1.0 * m_role.my / m_role.mx);
//将求得的angle转换为笛卡尔坐标系中对应的弧度角
if(angle > 0)
{
angle = 2*PI - angle;
if(m_role.mx < 0)
{
angle -= PI;
}
}
else if(angle == 0)
{
if(m_role.mx < 0)
{
angle = PI;
}
}
else
{
angle = -angle;
if(m_role.my > 0)
{
angle += PI;
}
}
3>转换后的弧度角在[0, 2π),因此除以(2π / 8) ,再取整,就能得到[0, 15]之间的正整数dtn,根据dtn的值便能确定人物移动的方向(具体如下)
实现代码如下:
/*
将angle分为16等份,除以PI/8,再取整
dtn就是[0, 15]范围中的正整数
*/
int dtn = (int)(angle / (PI / 8));
//求得方向
switch(dtn)
{
case 15:
case 0://东
m_role.dtn = EAST;
break;
case 1:
case 2://东北
m_role.dtn = NORTHEAST;
break;
case 3:
case 4://北
m_role.dtn = NORTH;
break;
case 5:
case 6://西北
m_role.dtn = NORTHWEST;
break;
case 7:
case 8://西
m_role.dtn = WEST;
break;
case 9:
case 10://西南
m_role.dtn = SOUTHWEST;
break;
case 11:
case 12://南
m_role.dtn = SOUTH;
break;
case 13:
case 14://东南
m_role.dtn = SOUTHEAST;
break;
}
也许,你可能这会儿看的有点儿晕(当然,如果能明白,那就最好不过了),没关系
主要是,我觉得很久没写博客了,想做一个较为完整的Demo——按照实际,本节内容应该分为两次讲解,不过,我相信大家能渐渐地明白——我也是这样,慢慢儿琢磨琢磨,总会明白的^
四、代码剖析
老规矩,这次呢,BlueCoder封装了两个类:CScene(地图场景类)和CRole(人物角色类)(代码注有详尽注释,就直接贴出来好了)
1、CScene(负责地图的管理、背景音乐的播放)
1>Scene.h头文件的定义
#include<atlimage.h> #include <Mmsystem.h> #pragma comment(lib, "Winmm.lib") class CScene { private: private: CImage m_img;//背景地图png关联的CImage对象 CRect m_rWnd;//view窗口的客户区 int m_ix;//当前背景横坐标(只考虑地图的横向移动) int LEFTBORDER;//左边界 int RIGHTBORDER;//右边界 public: bool InitScene();//初始化 void PaintScene(CDC&);//绘制场景 void SetWndRect(CRect);//设置View窗口的客户区大小 bool IsLeftBorder();//是否到达左边界 bool IsRightBorder();//是否到达右边界 void MoveScene(int);//移动背景 void ReleaseScene();//释放内存资源 public: CScene(void); ~CScene(void); };
2>具体的成员函数实现
//初始化场景 bool CScene::InitScene() { m_img.Load(L"res\\0.png"); if(m_img.IsNull()) { return false; } m_ix = 0; LEFTBORDER = 0; RIGHTBORDER = 0; mciSendString(L"open res\\bgm.wma alias bgm", NULL, 0, NULL); mciSendString(L"play bgm repeat", NULL, 0, NULL); return true; } //设置窗口Rect void CScene::SetWndRect(CRect rect) { m_rWnd = rect; RIGHTBORDER = m_rWnd.Width() - m_img.GetWidth(); } //移动背景 void CScene::MoveScene(int mx) { m_ix += mx; if(m_ix > LEFTBORDER) m_ix = LEFTBORDER; if(m_ix < RIGHTBORDER) { m_ix = RIGHTBORDER; } } //判断背景是否到达左边界 bool CScene::IsLeftBorder() { return m_ix == LEFTBORDER; } //判断背景是否到达右边界 bool CScene::IsRightBorder() { return m_ix == RIGHTBORDER; } //绘制场景 void CScene::PaintScene(CDC &cdc) { cdc.SetStretchBltMode(COLORONCOLOR); m_img.StretchBlt(cdc, m_ix, 0, m_img.GetWidth(), m_rWnd.Height(), SRCCOPY); } //释放内存资源 void CScene::ReleaseScene() { mciSendString(L"close bgm", NULL, 0, NULL); m_img.Destroy(); }
2、CRole(人物角色的控制)1>Role.h头文件定义
#include<atlimage.h> #include<math.h> //定义一个宏PI(π)——用于计算方向 #define PI 3.141592653 //人物移动方向的枚举 enum DIRECTION{SOUTH, WEST, EAST, NORTH, SOUTHWEST, SOUTHEAST, NORTHWEST, NORTHEAST}; typedef struct r { int x; int y;//x、y坐标 int mx; int my;//x、y坐标上移动的速度 int curFrame;//当前帧 DIRECTION dtn;//移动方向 }ROLE; class CRole { private: static const int MAXFRAME = 8;//共8帧 static const int SPEED = 6;//移动速度, 匀速:6 private: CImage m_img;//人物png关联的CImage对象 ROLE m_role;//角色结构体变量 CRect m_moveRange;//人物移动范围 //是否切换当前帧:为了背景滚动与人物走动效果匹配 bool m_change; public: bool InitRole();//初始化 bool IsCenter();//判断人物是否到达中央(x坐标) int GetXMove();//获取当前人物在x轴上的移动速度 void SetRange(CRect);//设置移动范围 void SetMXY(CPoint);//计算mx、my void SetDirection();//计算方向 void MoveRole(bool);//移动人物 void NextFrame();//切换到下一帧 void PaintRole(CDC &);//绘制角色 void ReleaseRole();//释放内存资源 public: CRole(void); ~CRole(void); };
2>具体的成员函数实现( 实现细节 中贴出来的代码就不重复出现在这里了)
//初始化角色 bool CRole::InitRole() { m_img.Load(L"res\\role.png"); if(m_img.IsNull()) { return false; } m_role.curFrame = 0; m_role.dtn = EAST;//初始化方向:东(右) m_role.x = 10; m_role.y = 350; m_role.mx = 0; m_role.my = 0; m_change = true;//一开始允许切换当前帧 return true; } //是否到达客户区中央(x坐标) bool CRole::IsCenter() { int width = m_img.GetWidth() / MAXFRAME; int x = m_role.x + width / 2; int mx = (m_role.mx < 0 ? -1 : 1) * m_role.mx; return x >= m_moveRange.Width() / 2 && x < m_moveRange.Width() / 2 + mx; } //获取当前人物在x轴上的移动速度 int CRole::GetXMove() { return m_role.mx; } /* *函数功能:设置移动范围 *参数:wnd——View窗口的客户区 */ void CRole::SetRange(CRect wnd) { m_moveRange.SetRect( wnd.left, wnd.Height()/2 + 100, wnd.right, wnd.bottom); } /* *函数功能:移动人物 *参数:isXMove——是否移动x坐标 */ void CRole::MoveRole(bool isXMove) { //如果人物在可移动范围中就可以移动 if(m_role.x + m_role.mx>=0 && m_role.x + m_role.mx<= m_moveRange.Width()-m_img.GetWidth()/8 && m_role.y + m_role.my + m_img.GetHeight()/8>= m_moveRange.top && m_role.y + m_role.my<= m_moveRange.bottom-m_img.GetHeight()/8) { if(isXMove) m_role.x += m_role.mx; m_role.y += m_role.my; } } //切换下一帧 void CRole::NextFrame() { m_change = !m_change; if(m_change) { m_role.curFrame++; if(m_role.curFrame == MAXFRAME) { m_role.curFrame = 0; } } } //绘制角色 void CRole::PaintRole(CDC &cdc) { int width = m_img.GetWidth() / MAXFRAME; int height = m_img.GetHeight() / MAXFRAME; m_img.TransparentBlt(cdc, m_role.x, m_role.y, width, height, width * m_role.curFrame, height * m_role.dtn, width, height, RGB(255, 255, 255)); } //释放内存资源 void CRole::ReleaseRole() { m_img.Destroy(); }
3、View窗口类中来管理整个程序的运行逻辑1>头文件重要的定义部分
#define ID_PAINT 100//计时器ID // 特性 private: CScene m_scene;//场景类对象 CRole m_role;//角色类对象 CRect m_rect;//窗口客户区大小
2>重要的函数实现部分
//-----------------WM_PAINT消息_绘图------------------
void CChildView::OnPaint()
{
CPaintDC dc(this); // 用于绘制的设备上下文
//--------------双缓冲贴图--------------------
CDC bufferDC;
CBitmap bufferBmp;
bufferDC.CreateCompatibleDC(NULL);
bufferBmp.CreateCompatibleBitmap(&dc,
m_rect.Width(), m_rect.Height());
bufferDC.SelectObject(bufferBmp);
m_scene.PaintScene(bufferDC);
m_role.PaintRole(bufferDC);
dc.BitBlt(0, 0, m_rect.Width(), m_rect.Height(),
&bufferDC, 0, 0, SRCCOPY);
bufferBmp.DeleteObject();
bufferDC.DeleteDC();
}
//-----------------WM_CREATE消息_初始化------------------
int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if(!m_scene.InitScene() ||
!m_role.InitRole())
{
AfxMessageBox(L"png加载失败");
exit(0);
}
SetTimer(ID_PAINT, 49, NULL);
return 0;
}
//-------------WM_SIZE消息_获取窗口客户区大小--------------
void CChildView::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
GetClientRect(&m_rect);
m_scene.SetWndRect(m_rect);
m_role.SetRange(m_rect);
}
//------WM_LBUTTONDOWN消息_用鼠标左键控制任务的走动-------
void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
{
SetCursor((HCURSOR)LoadImage(NULL, L"res\\hand.cur",
IMAGE_CURSOR, 0, 0, LR_LOADFROMFILE));//修改为自定义光标
m_role.SetMXY(point);
m_role.SetDirection();
CWnd::OnLButtonDown(nFlags, point);
}
//--------------WM_TIMER消息_移动人物和背景---------------
void CChildView::OnTimer(UINT_PTR nIDEvent)
{
bool moveRoleX = true;//是否移动人物的x坐标
//如果人物x坐标在中央 if(m_role.IsCenter()) { int mx = m_role.GetXMove(); //移动背景 if(mx > 0 && !m_scene.IsRightBorder() || mx < 0 && !m_scene.IsLeftBorder()) { moveRoleX = false; m_scene.MoveScene(-mx); } } //移动人物 m_role.MoveRole(moveRoleX); m_role.NextFrame();
InvalidateRect(NULL, false);
CWnd::OnTimer(nIDEvent);
}
//-----------------WM_DESTROY消息_释放内存资源------------------
void CChildView::OnDestroy()
{
CWnd::OnDestroy();
KillTimer(ID_PAINT);
m_scene.ReleaseScene();
m_role.ReleaseRole();
}
五、零积分资源下载点击下载源代码工程
呵呵,其实说来惭愧,目前为止,我还没有正式地看过一本有关游戏开发的书籍——都只是在csdn上逛逛博客,当灵感来的时候,就写一写代码,然后发布博文——其实,也主要是上学期太忙,大三的专业课很多,所以导致这个现象……因此呢,我决定好好地看几本书了,等到学业已成之时,再来和大家分享自己的所学所得^_^
最后,还是送上一句话(与大家共勉):
给自己的想法和梦想一次破茧而出的机会,亲手创造属于你自己的幸福
加油,EveryBody!!!
相关文章推荐
- 【VC++游戏开发#十二】2D篇 —— 人工智能(二):最短路径 & 智能越过障碍 By BlueCoder
- [unity3d]鼠标点击地面人物自动走动(也包含按键wasd&space控制)
- unity3d]鼠标点击地面人物自动走动(也包含按键wasd&space控制)
- Android游戏开发实践之人物移动地图的平滑滚动处理
- [Unity3D]Unity3D游戏开发之史上最简单的鼠标点击控制人物走动实现
- [unity3d]鼠标点击地面人物自动走动(也包含按键wasd&space控制)
- [unity3d]鼠标点击地面人物自动走动(也包含按键wasd&space控制)
- 鼠标点击地面人物自动走动(也包含按键wasd&space控制) .
- 游戏开发之--简单的人物走动和地图移动(一)
- Unity3D游戏开发之史上最简单的鼠标点击控制人物走动实现
- Unity3D游戏开发之史上最简单的鼠标点击控制人物走动实现
- 鼠标点击地面人物自动走动(也包含按键wasd&space控制)
- 【VC++游戏开发#七】2D篇 —— 物理建模(二) 重力模拟:让愤怒的小鸟来感受一次自由落体运动
- cocos2d-x游戏开发(三)无限滚动地图
- [unity3d]鼠标点击地面人物自动走动(也包含按键wasd&space控制)
- Flash游戏开发中的人物走动实现方法
- 鼠标控制人物在地图移动的方法
- 《MFC游戏开发》笔记四 键盘响应和鼠标响应:让人物动起来
- Android游戏开发之主角的移动与地图的平滑滚动
- 【VC++游戏开发#五】2D篇 —— 游戏之二:看看你能坚持多少秒