{------------------------------------------------------------------------------}
// 数据结构定义
{------------------------------------------------------------------------------}
type
procedure THumanActor.Draw(Surface: IDirectDrawSurface7; X, Y, Width, Height: Integer);
var
Index: Word;
begin
// 绘制武器,允许的范围 [0..33] (WeaponOrder = 0)
if (WeaponOrder = 0) and (Weapon > 0) and (Weapon < MAX_WEAPON) then
G_WilWeapon.DrawEx(WeaponOffset + FrameIndex, Surface, X, Y,
CLIENT_WIDTH, CLIENT_HEIGHT, True);
function THumanActor.CalcNextDirection: Boolean; //计算下一个方向为什么要返回boolean??walk(),run()中会看到作判断用
var
NewDir: Byte;
begin //这里比较容易理解吧:坐标系统跟数学坐标不一样
if (MovX = -1) and (MovY = -1) then NewDir := DIR_UPLEFT else
if (MovX = -1) and (MovY = 0) then NewDir := DIR_LEFT else
if (MovX = -1) and (MovY = 1) then NewDir := DIR_DOWNLEFT else
if (MovX = 0) and (MovY = -1) then NewDir := DIR_UP else
if (MovX = 0) and (MovY = 1) then NewDir := DIR_DOWN else
if (MovX = 1) and (MovY = -1) then NewDir := DIR_UPRIGHT else
if (MovX = 1) and (MovY = 0) then NewDir := DIR_RIGHT else
if (MovX = 1) and (MovY = 1) then NewDir := DIR_DOWNRIGHT else
raise Exception.Create('CalcNextDirection');
Result := NewDir <> Direction; //比较计算出的新方向与当前方向,,看是不是相等,,到此为止实际上函数的作用已经完成了,但是还要加入一个附加处理
if Result then Direction := NewDir; //附加处理:如果不等(为真),,那么置当前dir为newdir
end;
procedure THumanActor.Walk(X, Y: Integer); //x,,y为目标位置
begin
if CurrentAction <> HUMANACTION_STAND then Exit; //走之前一定要是站立状态
MovX := Min(1, Max(-1, X - MapX)); //movx,,movy是上次 Walk, Run Action 的偏移值,这个语句值得深究,我们来推导一下
if min(1,max())= 取max then,,max只能取0,,负数,,因此在max内部,,要么为0,不能是-1(为0时,此时x-mapx=-1,x=mapx-1),,要么为负(此时x-mapx<-1,,x<mapx-1)
也即x<=mapx-1
实际意义就是用户点了(这里只讨论x方向)人物当前x坐标前一个方向
if min(1,max())= 取1 then, , max内部只能取2,,或2以上(max不能是1),,因此x-mapx是,,即x>=mapx+2,,此时x在水平方向总是要比mapx大二个或二个地图格以上
if (MovX = 0) and (MovY = 0) then Exit; 用户点了站立的位置,,相当于不走,exit,,即walk()函数不发挥作用
if CalcNextDirection then ReCalcFrames; //如果方向改变了,,那么也要重新计算帧
if not CurrentMap.CanMove(MapX + MovX, MapY + MovY) then Exit; //如果地图不能走当然也就不能继续walk()了
CurrentAction := HUMANACTION_WALK;
ReCalcFrames; //动作由站立改为走也要重新计算帧,,也就是说,,recalcframes,,,的影响因素有二个1,动作,,2方向
end;
procedure THumanActor.Run(X, Y: Integer); x,,y为目标位置
begin
if CurrentAction <> HUMANACTION_STAND then Exit; //跑之前一定要是站立状态
MovX := Min(1, Max(-1, X - MapX));
MovY := Min(1, Max(-1, Y - MapY));
if (MovX = 0) and (MovY = 0) then Exit; //用户点了站立的位置,,相当于不跑
if CalcNextDirection then ReCalcFrames;
if not CurrentMap.CanMove(MapX + MovX, MapY + MovY) then Exit;
if not CurrentMap.CanMove(MapX + MovX * 2, MapY + MovY * 2) then
begin
Walk(X, Y);
Exit; //这里为什么不要recalcframe,,因为包括在walk(x,y)中了
end;
CurrentAction := HUMANACTION_RUN; //这句语句的上面计算run产生的地图位移,下面就是产生动画效果
ReCalcFrames;
end;
procedure THumanActor.Hit(X, Y: Integer);
begin
if CurrentAction <> HUMANACTION_STAND then Exit;
MovX := Min(1, Max(-1, X - MapX));
MovY := Min(1, Max(-1, Y - MapY));
if (MovX = 0) and (MovY = 0) then Exit;