显示不动的游戏精灵:
大家看到,我的游戏里每幅精灵图片都是由很多个方向和脚步不同的精灵构成的。
由于我没有用任何斜视角,所以精灵图片有4个方向:上下左右。
先看看我是怎样显示所有的玩家的:
void DrawPlayerWait()
{
static int tFrame=0;
tFrame++;
if(tFrame>=21)
tFrame=0;
for(int i=0;i<GetPlayerNum();i++)
{
if(player.roles[i].IsVisible && player.roles[i].IsDead==FALSE)
{
player.roles[i].StepFrame=tFrame/7+1;
SetRect(&BltRect,(player.roles[i].StepFrame-1)*32,
(player.roles[i].FaceTo-1)*48,
(player.roles[i].StepFrame*32),
(player.roles[i].FaceTo*48));
ClipBlt(lpDDSBack,player.roles[i].NowPos.Line*32-ScreenMapX,
player.roles[i].NowPos.Row*32-ScreenMapY,
lpDDSRolePlayer[player.roles[i].MovePicID],
BltRect,TRUE);
}
}
}
tFrame是帧数。
If(tFrame>=21)tFrame=0;这句是什么意思呢?
看看我游戏里的"玩家"的图片都是96*192的大小,每幅图包含了3个不同的脚步
我每隔7帧才换一次"脚步",注意一点,我在游戏中设定每秒刷新33次!
如果你觉得7帧不合适还可以自己修改!不过要把上面的IF语句的条件也要做相应的修改。
那个for循环中的GetPlayerNum()函数是得到当前玩家角色的数目(具体实现请看后面)
再下来的if语句是判断这个角色是否可见,如果是,则画之。
SetRect是WinAPI的一个函数,就是设定一个矩形,注意是怎么计算的:
先插入一句:player是一个类为
class Player
{
public:
long money;//金钱
PlayerEquip pe[MAX_EQUIP];//玩家所有的物品,这个结构有ID(编号),Count(数量)
Role roles[MAX_ROLES];//这个是一个结构。里面包含了角色的所有信息
};
Player player;
(player.roles[i].StepFrame-1)*32,这是要显示精灵图片的矩形的左端
注意我设定的StepFrame是从1到3,所以这里要减1
(player.roles[i].FaceTo-1)*48是要显示精灵图片的矩形的上端
注意我设定的FaceTo,想想精灵图片,从上到下的FaceTo依次为下,左,上,右
我定义下为1,左为2…所以要减1
当然后面两个参数就是要显示精灵图片的矩形的右端和下端了!
注意:如果为了提高点速度,可以这样写
(player.roles[i].StepFrame-1)*32ó (player.roles[I].StepFrame-1)<<5,
(player.roles[i].FaceTo-1)*48 ó(player.roles[I].FaceTo-1)<<5+(player.roles[I].FaceTo-1)<<4
"<<"是左移位,移动n位就相当于乘上2的n次方
同理">>"是右移,移动n位就相当于除上2的n次方
好了,现在得到了矩形了,要把这个矩形里的东西放到屏幕上显示
显示的坐标为:
player.roles[I].NowPos.Line*32-ScreenMapX 和
player.roles[I].NowPos.Row*32-ScreenMapY
解释一下:
player.roles[I].NowPos是一个TilePos类(上面有声明),想想地图的格式,就知道为什么要乘上32了吧?(和显示地图的原理是一样的!还有一点,这类游戏的人物只能在地图小块中出现!和其他的游戏有不同,至于为什么会这样,到了下面就会知道了!)
减去一个ScreenMapX的意思是什么?
慢慢来:记住游戏里所有的坐标都是以大地图为参考的!
象这样:

图中蓝色部分表示地图,橙色部分表示显示屏,绿色的就表示精灵
注意,精灵坐标也是以地图为参考的!
这下知道了吧?
大家可能还有一个问题就是如果精灵不在屏幕上呢?
这不用担心,ClipBlt这个函数会把不在屏幕的东西裁剪掉的!
好了,这样就可以把不移动的精灵给显示出了!
对于显示敌人和NPC一样的道理,不过有一点点小问题:看看游戏里的敌人图片,是不是有大有小?
这就要分开考虑了,但是原理都是一样的