学VC 编游戏 重点算法解疑系列文档 - 走四方

对manmove()和bianfw()的理解

 

manmove()实际上实现的作用是计算man[i](i的值由manmove()的入口参数i的当前值取得)的man[i].xix,man[i],yiy当前值,man[i].xix,man[i],yiy的变化过程是这样的:如果程序刚加载,此时人物的x0,y0,xix,yiy值都由程序赋于(具体赋于的初值在源程序中的位置不用我明说了吧?),人物初始动作为站,用户点击鼠标后程序意义上给man[i]目标位置分量x0,y0后,man[i].xix,man[i].yiy以一定的水平方向上和垂直方向上的偏移步长不断向x0,y0偏移靠拢,如果一开始人物正在走动的情况也是一样的,接着第一种情况来说,如果用户在这个不断变化的过程中(此时xix,yiy没有最终偏移到x0,y0或者说xix,yiy偏移到x0,y0前)点击了鼠标,新的x0,y0将重新形成,此时xix,yiy的值仍然是点击鼠标的那一瞬间的xix,yiy的值,也就是说,那时的xix,yiy将保留作为当前xix,yiy值,这没有什么不可理解的,因为xix,yiy都是变量,它们的值是可以动态变化的man[i].xix,man[i].yiy决定了在透明贴图函数中man[i]当前P值(P也是man[i]的一个分量,P值的不断递进会不断更新MemDC中的内容,贴到屏幕上就会导致人物动画了)对应的图片经过GetPic()后形成bit再关联到MemDC然后贴到dc.mdc的贴图位置,也就是man[i]的当前位置,可见这个当前位置(即man[i].xix,man[i].yiy这2个结构分量)是不断变化的(因为它们是变量,这没有什么不可理解的),从xix,yiy递进到x0,y0,递进形式可表达为:xix=xix+水平方向上的步长,yiy=yiy+垂直方向上的步长,xix<=x0,yiy<=y0,,说完了manmove(),再来说bianfw(),在谈完这二个函数后,你将会明白manmove()与bianfw()的真正含义了,而不再会被它们的函数名称(manmove:人物移动,bianfw:人物方位转换)迷惑了,你也将明白这二个函数在完成精灵(精灵是游戏开发术语之一,指一切活动对象,第5章的精灵专指主角人物,第6,7章开始引入了其它的精灵,即书中说的"对象",包括活动对象人和兽,静态对象石,树等)移动中各自完成的作用及作用上的区别,及它们在完成精灵移动中存在的必要,bianfw()实际上实现的作用是从对应的图片目录下取得特定相关的一组图以形成人物动画,这样图通过P由m0到m1的递变组合形成动画(静物不参与bianfw(),请自行在源程序中找到屏蔽静物P递进的语句),人物的取图操作需要三个方面的量才能完成:人物角色,人物动作,人物方位(动物也一样,动物的角色就是指不同的动物),只有这三个都确定了,取图操作才能进行,任何一个量少了,将取不得确定的一组图(取图即计算P的初值和终值),下面我们来分析一下bianfw()是如何具体进行取图操作的,人物取图的三个量,人物的角色实际上已经指定(自己去找man[i].js=0的位置吧),人物的姿式在bianfw()体内已指定为man[i].zs=0(走动),只有人物的方位未确定了,程序中用了检测点man[i].x0,man[i].y0与点man[i].xix,man[i].yiy之间的连线指向的方法来确定人物方位,上面说了取图即是确定动画图片组的初值m0和终值m1,得出的m0和m1将在下面的程序中用于P的递进,这样我们就讲完了这二个函数了,另外,作者在编程实现鼠标控制精灵移动时所用的算法不科学,(经过上面的分析,我们知道作者的算法是设置二个函数manmove()和bianfw(),前者用于计算man[i].xix,man[i].yiy形成贴图位置,后面从目录下取特定的一组图形成动画)实际执行"01.走四方.exe"时你会发现,具体表现请参照我以前写的一篇文档"Demo缺陷分析"(因为是以前刚看这本书时写的,可能不够科学,请参照一下这个地址http://articles.gameres.com/Program/Abstract/Thinking/CharacterMove.htm的一篇技术文档吧)..

为什么会形成这些现象呢?因为现象不止一种,对每一种现象的程序根源的分析都是要花很多文字的,我这里只针对人物到达目标后点还在走动的现象(或者人物到达目标点后当前动画还未播放到"走"的最后一帧而卡在那里的现象)谈谈自己新的理解,用意仅仅激发读者的思考,它的科学性我不能保证,说错了还望高手斧正,上面说到作者使用二个函数来构建精灵移动算法,二者作为二个独立的函数过程一前一后共处于对象显示函数SetObj()函数体内(SetObj()是后来出现的对象显示函数,拿它来分析"走四方"这一章的主角显示是可行的),但是它们的作用仅仅是进行概念级的计算,并不实际向暂存区贴图,虽然这样,最终的贴图效果显然还是由这二个函数直接影响着的,因为某一瞬间(这一瞬间P取了一个确定值)形成的MemDC的贴图位置是由这二个函数之一的manmove()得出的,MemDC的图形内容(由P当前的取值决定)是由这二个函数之一的bianfw()决定的,P再不断地由m0递进到m1反映到贴图函数中就形成了动画,这二个函数显然影响最终的在程序界面上的贴图效果,即鼠标控制精灵移动的最终显示效果(鼠标点击的实质是重新给man[i].x0,man[i].y0),我们要追寻这二个函数影响下的最终贴图过程(这个贴图过程在源程序中可能表现为一个贴图函数),就要在源程序中找到这个贴图函数,这个贴图函数显然就是TransparentBlt2(),我们知道函数是以它的CPU执行时间和参数压入堆栈所占空间来衡量对系统的资源消耗的,manmove()和bianfw()在SetObj()体内是串式执行的,是一前一后的,二者执行所花的时间上没有任何的联系,即一方的时间长短不会影响另一方,二者在系统时间消费上完全是互不相干的,可能manmove()多些,也可能bianfw()多些,当然也可能是相等的,反正就是不可预料的,那么,当manmove()与bianfw()在SetObj()体内得出它们各自的计算结果而被TransparentBlt2()调用时,它们执行所花的时间上的不相等会不会导致TransparentBlt2()效果的异样呢?举个例子,当人物移动到了man[0].x0和man[0].y0的那一瞬间(这是manmove()计算的作用,显然人物此时应立马由走转为站的状态,这就要求人物由走转为站之前的最后一帧恰好是人物"走"动画图片的最后一张,图片当前P的是函数bianfw()作用而来的),此时人物的图片播放(就是bianfw()计算出的当前的P值)是不是刚好就播放到了"走"动作动画的最后一张呢,如果还没有(manmove()完成时的当前系统时间比bianfw()小),那么最终的效果就是上面第二段开头说到的"人物到达目标点后当前动画还未播放到'走'的最后一帧而卡在那里的现象",如果超过了(manmove()完成时的当前系统时间比bianfw()多),那么最终的效果就是上面第二段开头说到的"人物到达目标后点还在走动的现象"..

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值