这几天跟同学讨论了一下关于rpg中人物移动的问题
我们用方向键来控制人物的移动,开始的设想是,人物图片大小为32x32,在四个方向上,人物的状态都是停,左脚,停,右脚,所以每动一次方向键,人物移动8个像素,人物的状态改变一次,这样当移动32个像素时,人物就走完了四个状态,从界面上开起来就像是在移动,开始的代码如下,以向左走为例
case VK_LEFT:
if(despos.x > 0)
{
despos.x -= 8; //画图的坐标点,由于向左移动,Y轴不变
srcpos.x = size.cx * flagleft++; //这两句是找到所需图片位置的,
srcpos.y = size.cy;
//以下省略,画图过程
}
虽然这样也能实现,但是给我们的感觉就是移动太快,看起来很不舒服,所以就考虑使用定时器,本来考虑使用GetTickCount用来把桢数精确定位到33ms的,但觉得SetTimer函数就行了,所以就选用了
SetTimer,首先考虑的是键盘与定时器如何协同工作,于是就想让定时器不断刷屏,同时键盘操作改变人物状态,当然此时画图是在定时器函数里画,代码如下
case WM_TIMER
switch(wParam)
{
case TIMER_ID1:
Invalidate(FALSE);
CPaintDC dc(this);
//以下省略,画图过程
break;
}
break;
case WM_KEYDOWN:
switch(wParam)
{
case VK_LEFT:
if(despos.x > 0)
{
despos.x -= 8;
srcpos.x = size.cx * flagleft++;
srcpos.y = size.cy;
}
}
break;
可这样做后发现与第一种方法没什么差别,其实由于刷屏太快,人眼已经感觉不出来了,这是我们参考了
RPG Maker里的一些做法,我们发现,当我们只按一下方向左键时,人物移动了32个像素,而且只经过了三个阶
段:停--左脚--停(假设这里是先出的左脚),而对于连续按键时,由于刷屏速度太快,我们就认为在真正走的
时候就只有左脚--右脚这两个状态,于是我们就当人物连续移动时连续画16次左脚或右脚,而忽略中间过程,而
对于只按一次键的情况,就用连续画16次左脚在停的方法表示,显然这是错误的,事实上我们得出的结果也并不
理想,图像出现明显的卡现象,而且图像特别扭,这不是因为快的问题,而是图像根本不连续,于是我们又用四
张不同的位图来在RPG Maker里模拟人物的移动,发现当一直按键时,人物在四个状态间变化,而不是我们先前设
想的左脚--右脚,于是我们把停也加进代码,只是对停止重绘一次,而左右脚仍画16次,并且我们在键盘消息里
调用OnTimer消息,这样就不用一直在重画,同时按一次键就移动32个像素,定时器里绘制代码如下
srcpos.x = size.cx * flagleft;
//绘制图像
flagleft++;
for(int i = 0; i < 16; i++)
{
despos.x -= 2;
srcpos.x = size.cx * flagleft;
sprite.Set(&overlap, despos, srcpos, size);
//绘制图像
}
但是这样还是不行,在停和走之间仍旧有明显的卡现象,于是我们就想干脆把停也重画16次,于是把代码
该成如下:
for(int i = 0; i < 16; i++)
{
despos.x -= 2;
sprite.Set(&overlap, despos, srcpos, size);
//绘制图像
}
虽然觉得这样可能仍旧有问题,但是运行出来发现效果非常不错,可是在这里我们对于停也进行了移动32
像素的处理,于是就又想在for循环里面判断一下,如果是停就不移动,可做出来发现效果很不理想,移动中间停
滞的太严重,干脆就采用都移动32个像素吧,这样看起来才自然,于是就用了先前的做法。
这只是一个初步的测试,具体的代码应该也会在这几天全部写出来,再可能就是考虑战斗的问题了。