《学VC、编游戏》重点算法解疑·狩猎谋生
《学VC、编游戏》重点算法解疑·狩猎谋生 153页的lookit(int i)的lookit我想破了头也不知道它是什么意思,Cqtml真是可爱,也不知道他是怎么想到这个lookit这个词的,ZJDZ我倒知道是"主角动作",可ZJDW呢,是"动物主角吗"??
函数的入口参数是i,对lookit()的理解宜放在152的OnTimer()中进行,OnTimer()函数体中,在i属于(0,rs)的循环里完成了2个动作,多对象显示SetObj()和今天要谈到的碰撞检测(当然说碰撞检测未免失准,更准确的说法是碰撞检测及检测到碰撞后的对象处理方案,如打斗双方都停下来,不再manmove(),还要有双方的ZS改变,这个算法不是很科学,会导致人边走边打的效果,后面会分析到)即Lookit(),分别对应OnTimer()函数体中的二大语句块,OnTimer()的时间间隔是150ms,有人担心计算机在150ms的时间里能执行完OnTimer()体内这么多的语句吗?(这个不要担心了,1000,10000个SetObj()+Lookit()都可以)如果能的话,计算机能不能保证实际执行OnTimer()所花的每个时间间隔都是150ms?(这要看计算机的精确度了),函数的入口参数i和Lookit()体内的q都是属于(0,rs)的,为什么要定义二个循环变量,会不会产生矛盾呢?不会的,当i==q==3时,man[i]=man[q]=第四个对象man[3],就像前面的Sort()体内的a,b作为下标表达数组man[]一样(关于Sort()的分析点这里),普通应用下,只要开一个循环变量就可以了,而特殊应用下,比如这里的处理2个lb的多个man之间的碰撞关系时,就要开二个"线程"了,Lookit()函数体内,首先if man[i].lb=0,不是人返回,这样就把man[i]的表数(或者说表"对象")范围给封死了,即man[i].lb只能为0,表人,所有man[i].lb<>0的对象不能参与循环体内的二大块代码而直接跳到循环体外(注意不是函数体外),man[i]当然可以取man[i].lb<>0的值,但是对这段函数有意义的只有man[i].lb=0的情况,即这段函数代码对man[i].lb<>0不起作用,所以在OnTimer()中,无论i循环到了多少,对Lookit()有用的只要man[i].lb=0的取值情况,实际上只有一种取值情况,那就是man[i]==man[0],因为man[i].lb=0是man[i]==man[0]的充分条件,知道了man[i]只能表人,再来看man[q],q是在Lookit()体内循环的,man[q]的表数范围也作了一些限制,man[i]表人,man[q]就对应地表"兽",这是算法的要求,算法就是要比较活动对象(2种:人与兽)的碰撞关系的,对man[q]的表对象范围的限制工作是如何在程序中进行的呢?if q==i(注意语言中等号与赋值符的区别),跳出循环,经过这句以后,对Lookit()有意思的只有man[q]<>man[i]的man取值情况,即man[q]不能为man[0],q不能取man[q].lb=0时的man[q]值,这句使man[q]不能表人,接下来一句使man[q]不能表景,于是man[q]就只能表兽了,前面谈到Lookit()的算法不好,会导致人物边走边打的效果,那是因为作者仅仅检测图片的边缘是否相撞来判断对象是否相撞,这样人物与怪物一上一下时,不用我再说了吧?下面再来说半透明函数AlphaBlend(),首先要明确AlphaBlend()与前面的Sort()在多对象显示过程中完成的作用是不一样的(你可能会觉得这里拿二者放在一起有点莫明其妙,实际上对二者的比较是很有意义的,因为它们都要参与SetObj()),要时时记得AlphaBlend()是一个把源DC贴到目标DC,半透明效果发生在目标DC的过程,而Sort()并不实际做贴图的工作,Sort()只是根据y坐标决定贴图时的先后,是概念级的东西,并不跟AlphaBlend()一样做实际的贴图工作,它的作用就是要达成一种以玩家面向为准,近的先显示,远的后显示的效果(实际贴图中就是根据man[i]经过Sort()后的y坐标,y值大的man[i]先贴,y值小的man[i]后贴,于是会形成遮盖效果),至于被遮盖的那一部分是不是要半透明显示及如何进行半透明显示或者进行其它效果的显示,Sort()并不负责,而这个工作是由AlphaBlend()完成的,157页已经说明AlphaObj()只是对SetObj()多对象显示的一种修正,加入了半透明显示的API,即AlphaBlend(),这种修正是如何进行的呢,修正后实际上形成了二个函数