📄 actor.pas
字号:
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1
)
);
implementation
function GetBodyImageOffset(appr: Integer): Integer;
var
nrace, npos: Integer;
begin
Result := 0;
nrace := appr div 10;
npos := appr mod 10;
case nrace of
0: Result := npos * 280; //8橇贰烙
1: Result := npos * 230;
2, 3, 7..16: Result := npos * 360; //10橇贰烙 扁夯
4: begin
Result := npos * 360; //
if npos = 1 then Result := 600; //厚阜盔面
end;
5: Result := npos * 430; //粱厚
6: Result := npos * 440; //林付脚厘,龋过,空
17: Result := npos * 350; //脚荐
90: case npos of
0: Result := 80; //己巩
1: Result := 168;
2: Result := 184;
3: Result := 200;
end;
end;
end;
{ THumanActor }
procedure THumanActor.Draw(BackDxFastBlt: TDxFastBlt; X, Y, Width, Height: Integer);
var
Index: word;
DxFastBlt: TDxFastBlt;
begin
// 绘制武器,允许的范围 [0..33] (WeaponOrder = 0)
if WeaponOrder = 0 then begin
DxFastBlt := ShuJi.Surfaces[WeaponOffset + FrameIndex];
if DxFastBlt <> nil then
BackDxFastBlt.DrawC(DxFastBlt, X, Y, 1.0);
end;
// 绘制身体
DxFastBlt := ShuJi.Surfaces[BodyOffset + FrameIndex];
if DxFastBlt <> nil then
BackDxFastBlt.DrawC(DxFastBlt, X, Y, 1.0);
// 绘制血条
DxFastBlt := ShuJi.Surfaces[5684];
if DxFastBlt <> nil then
BackDxFastBlt.DrawC(DxFastBlt, X, Y - 20, 1.0);
// 绘制头发,允许的范围 [0..2]
// if (Hair > 0) and (Hair < MAX_HAIR) then
{ ShuJi.DrawEx(HairOffset + FrameIndex, Surface, X, Y,
CLIENT_WIDTH, CLIENT_HEIGHT, True); }
// 绘制武器,允许的范围 [0..33] (WeaponOrder = 1)
if WeaponOrder = 1 then begin
DxFastBlt := ShuJi.Surfaces[WeaponOffset + FrameIndex];
if DxFastBlt <> nil then
BackDxFastBlt.DrawC(DxFastBlt, X, Y, 1.0);
end;
// TODO: 以下绘制都需用 DrawBlend 效果, 暂用 Blt 代替
// 绘制魔法气泡
// if (State and STATE_BUBBLEDEFENCEUP) <> 0 then
// if (Action = SM_STRUCK) and (CurBubbleStruck < 3) then
// Index := MAGBUBBLESTRUCKBASE + CurBubbleStruck
// else
if CurrentAction = HUMANACTION_HIT then
begin
case Direction of
0: Index := 5600 + (FrameIndex mod 10); //
1: Index := 5610 + (FrameIndex mod 10); //
2: Index := 5620 + (FrameIndex mod 10); //
3: Index := 5630 + (FrameIndex mod 10); //
4: Index := 5640 + (FrameIndex mod 10); //
5: Index := 5650 + (FrameIndex mod 10); //
6: Index := 5660 + (FrameIndex mod 10); //
7: Index := 5670 + (FrameIndex mod 10); //
end;
DxFastBlt := ShuJi.Surfaces[Index];
if DxFastBlt <> nil then
BackDxFastBlt.DrawE(DxFastBlt, X + DxFastBlt.PX, Y + DxFastBlt.PY, 1.0);
{DrawBlend(Surface, X + ShuJi.ImageInfo[Index]^.PX,
Y + ShuJi.ImageInfo[Index]^.PY, Width, Height,
ShuJi.Surfaces[Index],
ShuJi.ImageInfo[Index]^.Width,
ShuJi.ImageInfo[Index]^.Height,
0);}
end;
// 绘制武器破碎效果
if IsWeaponBreaking then
begin
Index := WEAPON_BREAKING_BASE + Direction * 10 + WeaponBreakingFrame;
{G_WilMagic.DrawEx(Index, Surface, X, Y, CLIENT_WIDTH, CLIENT_HEIGHT, True);}
end;
end;
procedure THumanActor.ProcessFrame;
var
CurrTick: Cardinal;
NewIndex: Integer;
begin
inherited;
CurrTick := GetTickCount;
case CurrentAction of
HUMANACTION_WALK:
begin
ShiftX := MovX * MAPUNIT_WIDTH * Integer((CurrTick - FrameTick)) div (FrameTime * FrameCount);
ShiftY := MovY * MAPUNIT_HEIGHT * Integer((CurrTick - FrameTick)) div (FrameTime * FrameCount);
end;
HUMANACTION_RUN:
begin
ShiftX := MovX * 2 * MAPUNIT_WIDTH * Integer((CurrTick - FrameTick)) div (FrameTime * FrameCount);
ShiftY := MovY * 2 * MAPUNIT_HEIGHT * Integer((CurrTick - FrameTick)) div (FrameTime * FrameCount);
end;
end;
NewIndex := FrameStart + (CurrTick - FrameTick) div (FrameTime);
if NewIndex = FrameIndex then Exit; // 判断是否需要计算帧
FrameIndex := NewIndex;
// TODO: 可能 GetTickCount 会在 49 天内循环回来
if FrameIndex < FrameStart then FrameIndex := FrameStart;
if FrameIndex > FrameEnd then
begin
case CurrentAction of
HUMANACTION_WALK:
begin
Inc(MapX, MovX);
Inc(MapY, MovY);
end;
HUMANACTION_RUN:
begin
Inc(MapX, MovX * 2);
Inc(MapY, MovY * 2);
end;
end;
CurrentAction := HUMANACTION_STAND;
ReCalcFrames;
end;
// 计算武器绘制顺序
WeaponOrder := WEAPONORDERS[Sex, FrameIndex];
// 计算武器破碎效果帧
Inc(WeaponBreakingFrame);
if WeaponBreakingFrame >= 10 then WeaponBreakingFrame := 0;
end;
constructor THumanActor.Create(Map: TMirMap);
begin
inherited;
Appearance := 0;
Job := 1;
Sex := 0;
Hair := 0;
Direction := 5;
Weapon := 0;
IsWeaponBreaking := False;
CurrentAction := HUMANACTION_STAND;
MapX := 23;
MapY := 21;
CurrentMap := Map;
end;
procedure THumanActor.ReCalcFrames;
var
InfoPtr: PActionInfo;
begin
inherited;
case CurrentAction of
0: InfoPtr := @HUMANACTIONS.ActStand;
1: InfoPtr := @HUMANACTIONS.ActWalk;
2: InfoPtr := @HUMANACTIONS.ActRun;
3: InfoPtr := @HUMANACTIONS.ActRushLeft;
4: InfoPtr := @HUMANACTIONS.ActRushRight;
5: InfoPtr := @HUMANACTIONS.ActWarMode;
6: InfoPtr := @HUMANACTIONS.ActHit;
7: InfoPtr := @HUMANACTIONS.ActHeavyHit;
8: InfoPtr := @HUMANACTIONS.ActBigHit;
9: InfoPtr := @HUMANACTIONS.ActFireHitReady;
10: InfoPtr := @HUMANACTIONS.ActSpell;
11: InfoPtr := @HUMANACTIONS.ActSitdown;
12: InfoPtr := @HUMANACTIONS.ActStruck;
13: InfoPtr := @HUMANACTIONS.ActDie;
else
raise Exception.CreateFmt('Unknown Human Action : %d', [CurrentAction]);
end;
// 身体图片偏移值
BodyOffset := 2000 + MAX_HUMANFRAME * (Appearance * 2 + Sex) + Direction * 8;
// 头发图片偏移值
// if (Hair > 0) and (Hair < MAX_HAIR) then
// HairOffset := 2000 MAX_HUMANFRAME * (Hair * 2 + Sex) + Direction * 8;
// 武器图片偏移值
// if (Weapon > 0) and (Weapon < MAX_WEAPON) then
WeaponOffset := 3200 + MAX_HUMANFRAME * (Weapon * 2 + Sex) + Direction * 8;
FrameCount := InfoPtr^.frame;
FrameStart := InfoPtr^.start;
FrameEnd := FrameStart + FrameCount - 1;
FrameTime := InfoPtr^.ftime;
FrameIndex := FrameStart;
FrameTick := GetTickCount;
ShiftX := 0;
ShiftY := 0;
end;
function THumanActor.CalcNextDirection: Boolean;
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;
end;
procedure THumanActor.Walk(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;
if CalcNextDirection then ReCalcFrames;
if not CurrentMap.CanMove(MapX + MovX, MapY + MovY) then Exit;
CurrentAction := HUMANACTION_WALK;
ReCalcFrames;
end;
procedure THumanActor.Run(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;
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;
end;
CurrentAction := HUMANACTION_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;
CalcNextDirection;
CurrentAction := HUMANACTION_HIT;
ReCalcFrames;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -