组装18 人物动画的简单实现 发出小火球和小火球到目标后爆裂

unit Movies;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, DXDraws, WILIB;
type
TAction = (ActStand, ActWalk, ActRun, ActRushLeft, ActRushRight, ActWarMode,
ActHit, ActHeavyHit, ActBigHit, ActFireHitReady, ActSpell,
ActSitdown, ActStruck, ActDie);
TMagicType = (mtReady, mtFly, mtExplosion,
mtFlyAxe, mtFireWind, mtFireGun,
mtLightingThunder, mtThuder, mtExploBujauk,
mtBujaukGroundEffect, mtKyulkai, mtFlyarrow,
mt12, mt13, mt14);
TUseMagicInfo = record
ServerMagicCode: Integer;
MagicSerial: Integer;
Target: Integer;
EffectType: TMagicType;
EffectNumber: Integer;
TargX: Integer;
TargY: Integer;
Recusion: Boolean;
AniTime: Integer;
end;
TActionInfo = packed record
start: Word;
frame: Word;
skip: Word;
ftime: Word;
usetick: Word;
end;
THumanAction = packed record
ActStand: TActionInfo;
ActWalk: TActionInfo;
ActRun: TActionInfo;
ActRushLeft: TActionInfo;
ActRushRight: TActionInfo;
ActWarMode: TActionInfo;
ActHit: TActionInfo;
ActHeavyHit: TActionInfo;
ActBigHit: TActionInfo;
ActFireHitReady: TActionInfo;
ActSpell: TActionInfo;
ActSitdown: TActionInfo;
ActStruck: TActionInfo;
ActDie: TActionInfo;
end;
TForm1 = class(TForm)
DXDrawHuman: TDXDraw;
ButtonPlay: TButton;
TimerShow: TTimer;
ListBoxAction: TListBox;
ListBoxDirect: TListBox;
ListBoxSex: TListBox;
ListBoxJob: TListBox;
ListBoxDress: TListBox;
MemoResult: TMemo;
ButtonStop: TButton;
ListBoxHair: TListBox;
Edit1: TEdit;
Label1: TLabel;
Edit2: TEdit;
Label2: TLabel;
Label3: TLabel;
Edit3: TEdit;
EditX: TEdit;
EditY: TEdit;
Label4: TLabel;
Label5: TLabel;
Edit4: TEdit;
Edit5: TEdit;
Label6: TLabel;
Label7: TLabel;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure DXDrawHumanInitialize(Sender: TObject);
procedure ButtonPlayClick(Sender: TObject);
procedure TimerShowTimer(Sender: TObject);
procedure PlayScence(MSurface: TDirectDrawSurface);
procedure ButtonStopClick(Sender: TObject);
procedure GetEffectBase(mag, mtype: integer; var wimg: TWILImages; var idx:
integer);
private
{ Private declarations }
public
{ Public declarations }
end;
const
HUMANFRAME = 600;
DR_UP = 0;
DR_UPRIGHT = 1;
DR_RIGHT = 2;
DR_DOWNRIGHT = 3;
DR_DOWN = 4;
DR_DOWNLEFT = 5;
DR_LEFT = 6;
DR_UPLEFT = 7;
HA: THumanAction = (
ActStand: (start: 0; frame: 4; skip: 4; ftime: 200; usetick: 0);
ActWalk: (start: 64; frame: 6; skip: 2; ftime: 180; usetick: 2);
ActRun: (start: 128; frame: 6; skip: 2; ftime: 200; usetick: 3);
ActRushLeft: (start: 128; frame: 3; skip: 5; ftime: 200; usetick: 3);
//先左手
ActRushRight: (start: 131; frame: 3; skip: 5; ftime: 200; usetick: 3);
//先右手
ActWarMode: (start: 192; frame: 1; skip: 0; ftime: 200; usetick: 0);
//ActHit: (start: 200; frame: 5; skip: 3; ftime: 140; usetick: 0);
ActHit: (start: 200; frame: 6; skip: 2; ftime: 140; usetick: 0);
ActHeavyHit: (start: 264; frame: 6; skip: 2; ftime: 140; usetick: 0);
ActBigHit: (start: 328; frame: 8; skip: 0; ftime: 120; usetick: 0);
//这里指的烈火蓄力的动作?
ActFireHitReady: (start: 192; frame: 1; skip: 0; ftime: 140; usetick: 0);
ActSpell: (start: 392; frame: 6; skip: 2; ftime: 200; usetick: 0);
ActSitdown: (start: 456; frame: 2; skip: 0; ftime: 240; usetick: 0);
ActStruck: (start: 472; frame: 3; skip: 5; ftime: 140; usetick: 0);
ActDie: (start: 536; frame: 4; skip: 4; ftime: 200; usetick: 0)
);
//一个人物模型就是599张图片
WORDER: array[0..1, 0..599] of byte = (//男女角色有些不同?
(
//站立0-63
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
//走64-127
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
//跑128-191
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
//战斗准备 8个方向,192-199
0, 1, 1, 1, 0, 0, 0, 0,
//攻击动作Hit 200-263
1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1,
//攻击动作HeavyHit 264 - 327
0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1,
//攻击动作BigHit 328- 391
1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,
1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0,
//魔法攻击动作Spell 392- 455
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1,
//挖,蹲下的动作Sitdown 每个方向2帧 456-471
0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0,
//被攻击后仰的动作Struck 每个方向3帧 472- 535
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
//死亡的动作 每个方向4帧 536-599
0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1
),
(
//站立0-63
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
//走64-127
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
//跑128-191
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,
//战斗准备 8个方向,192-199
1, 1, 1, 1, 0, 0, 0, 0,
//攻击动作Hit 200-263
1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1,
//攻击动作HeavyHit 264 - 327
0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0,
1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1,
//攻击动作BigHit 328- 391
1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0,
1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0,
//魔法攻击动作Spell 392- 455
0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1,
1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1,
0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1,
//挖,蹲下的动作Sitdown 每个方向2帧 456-471
0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0,
//被攻击后仰的动作Struck 每个方向3帧 472- 535
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
//死亡的动作 每个方向4帧 536-599
0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1,
0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1
)
);
EffectBase: array[0..30] of integer = (
0, //0 火球术
200, //1 治愈术
400, //2 大火球
600, //3 施毒术
0, //4 攻杀剑术
900, //5 抗拒火环
920, //6 地狱火
940, //7 疾光电影 没有SPELL效果
20, //8 雷电术, Magic2
940, //9 灵魂火符
940, //10 幽灵盾 没有SPELL效果
940, //11 神圣战甲术 没有SPELL效果
0, //12 刺杀剑术
1380, //13 困魔咒
1500, //14 召唤骷髅
1520, //15 隐身术
940, //16 集体隐身术 没有SPELL效果
1560, //17 诱惑之光
1590, //18 瞬息移动
1620, //19 火墙
1650, //20 爆裂火焰
1680, //21 地狱雷光
0, //22 半月弯刀
0, //23 烈火剑法
0, //24 野蛮冲撞
3960, //25 心灵启示
1790, //26 群体治疗术
0, //27 召唤神兽 Magic2
3880, //28 魔法盾
3920, //29 圣言术
3840 //30 冰咆哮
);
HitEffectBase: array[0..4] of integer = (
800,
1410,
1700,
3480,
3390
);
EXPLOSIONBASE = 170;
FLYBASE = 10;
type
TActor = class
m_btSex: Byte;
m_btJob: Byte;
m_btDress: Byte;
m_btDir: Byte;
m_btAtc: TAction;
m_nCurrX: Integer;
m_nCurrY: Integer;
m_nStartFrame: Integer;
m_nEndFrame: Integer;
m_dwFrameTime: LongWord;
m_dwStartTime: LongWord;
m_nMaxTick: Integer;
m_nCurTick: Integer;
m_nCurrentFrame: Integer;
m_BodySurface: TDirectDrawSurface;
m_nPx: Integer;
m_nPy: Integer;
m_btHair: Byte;
m_nHairOffset: Integer;
m_HairSurface: TDirectDrawSurface;
m_nHairPx: Integer;
m_nHairPy: Integer;
m_btWeapon: Byte;
m_nWeaponOffset: Integer;
m_WeaponSurface: TDirectDrawSurface;
m_nWeaponPx: Integer;
m_nWeaponPy: Integer;
m_nWpord: Integer;
//刀光效果
m_boHitEffect: Boolean;
m_nHitEffectNumber: Integer;
//施法效果
m_boUseMagic: Boolean;
m_CurMagic: TUseMagicInfo;
m_nCurEffFrame: Integer;
m_nSpellFrame: Integer;
constructor Create;
destructor Destroy;
procedure CalcActorFrame;
procedure Run;
procedure LoadSurface;
procedure DrawChr(dsurface: TDirectDrawSurface; dx, dy: integer);
end;
TMagicEff = class
m_boActive: Boolean;
ServerMagicId: Integer;
MagOwner: TObject;
TargerActor: TObject;
ImgLib: TWILImages;
EffectBase: Integer;
MagExplionBase: Integer;
px, py: Integer;
rx, ry: Integer;
Dir16, OldDir16: Byte;
TargetX, TargetY: Integer;
TargetRx, TargerRy: Integer;
FlyX, FlyY, OldFlyX, OldFlyY: Integer;
FlyXf, FlyYf: Real;
Repetition: Boolean;
FixedEffect: Boolean;
MagicType: Integer;
NextEffect: TMagicEff;
ExplosionFrame: Integer;
NextFrameTime: Integer;
Light: Integer;
Start: Integer;
CurFrame: Integer;
Frame: Integer;
private
m_dwFrameTime: LongWord;
M_dwStartTime: LongWord;
repeattime: LongWord;
steptime: LongWord;
fireX, fireY: Integer;
firedisX, firedisY: Integer;
newfiredisX, newfiredisY: Integer;
fireMyselfX, fireMyselfY: Integer;
prevdisX, prevdisY: Integer;
protected
procedure GetFlyXY(ms: Integer; var fx, fy: integer);
public
constructor Create(id, effnum, sx, sy, tx, ty: Integer; mtype: TMagicType;
Recusion: Boolean; anitime: Integer);
destructor Destroy; override;
function Run: Boolean; dynamic;
function Shift: Boolean; dynamic;
procedure DrawEff(surface: TDirectDrawSurface); dynamic;
end;
var
Form1: TForm1;
Actor1: TActor;
MagicEff1: TMagicEff;
g_mainWil: TWILImages;
g_WHumImgImages: TWILImages;
g_WHairImgImages: TWILImages;
g_WWeaponImages: TWILImages;
g_WMagicImages: TWILImages;
g_WMagic2Images: TWILImages;
g_cacheSurface: TDirectDrawSurface;
g_MySelf: TAction;
bmpIndex: Integer;
movetick: Boolean;
m_dwMoveTime: LongWord;
implementation
{$R *.dfm}
function ToDXD7Color(Color: TColor): TColor;
var
R, G, B: Integer;
begin
R := Color and $FF;
G := (Color and $FF00) shr 8;
B := (Color and $FF0000) shr 16;
Result := R shl 16 or G shl 8 or B;
end;
function _MAX(n1, n2: integer): integer;
begin
if n1 > n2 then
Result := n1
else
Result := n2;
end;
//计算飞的方向16,有16个方向?是将8个方向再次细化?
function GetFlyDirection16(sx, sy, ttx, tty: integer): Integer;
var
fx, fy: Real;
begin
fx := ttx - sx;
fy := tty - sy;
sx := 0;
sy := 0;
Result := 0;
if fx = 0 then
begin
if fy < 0 then
Result := 0 //上
else
Result := 8; //下
exit;
end;
if fy = 0 then
begin
if fx < 0 then
Result := 12 //左
else
Result := 4; //右
exit;
end;
if (fx > 0) and (fy < 0) then
begin
Result := 4;
if - fy > fx / 4 then
Result := 3;
if - fy > fx / 1.9 then
Result := 2;
if - fy > fx * 1.4 then
Result := 1;
if - fy > fx * 4 then
Result := 0;
end;
if (fx > 0) and (fy > 0) then
begin
Result := 4;
if fy > fx / 4 then
Result := 5;
if fy > fx / 1.9 then
Result := 6;
if fy > fx * 1.4 then
Result := 7;
if fy > fx * 4 then
Result := 8;
end;
if (fx < 0) and (fy > 0) then
begin
Result := 12;
if fy > -fx / 4 then
Result := 11;
if fy > -fx / 1.9 then
Result := 10;
if fy > -fx * 1.4 then
Result := 9;
if fy > -fx * 4 then
Result := 8;
end;
if (fx < 0) and (fy < 0) then
begin
Result := 12;
if - fy > -fx / 4 then
Result := 13;
if - fy > -fx / 1.9 then
Result := 14;
if - fy > -fx * 1.4 then
Result := 15;
if - fy > -fx * 4 then
Result := 0;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
TimerShow.Enabled := False;
bmpIndex := -1;
ListBoxJob.ItemIndex := 0;
ListBoxSex.ItemIndex := 0;
ListBoxDress.ItemIndex := 0;
ListBoxAction.ItemIndex := 0;
ListBoxDirect.ItemIndex := 0;
g_WHumImgImages := TWILImages.Create;
g_WHairImgImages := TWILImages.Create;
g_WWeaponImages := TWILImages.Create;
g_WMagicImages := TWILImages.Create;
g_WMagic2Images := TWILImages.Create;
Actor1 := TActor.Create;
MagicEff1 := nil;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
g_WHumImgImages.Destroy;
g_WHairImgImages.Destroy;
g_WWeaponImages.Destroy;
g_WMagicImages.Destroy;
g_WMagic2Images.Destroy;
g_cacheSurface.Free;
Actor1.Destroy;
if MagicEff1 <> nil then
MagicEff1.Free;
end;
procedure TForm1.DXDrawHumanInitialize(Sender: TObject);
begin
g_WHumImgImages.DDraw := DXDrawHuman.DDraw;
g_WHumImgImages.FileName := 'E:\mirClient\Mir1.76\Data\Hum.wil';
g_WHumImgImages.Initialize;
g_WHairImgImages.DDraw := DXDrawHuman.DDraw;
g_WHairImgImages.FileName := 'E:\mirClient\Mir1.76\Data\Hair.wil';
g_WHairImgImages.Initialize;
g_WWeaponImages.DDraw := DXDrawHuman.DDraw;
g_WWeaponImages.FileName := 'E:\mirClient\Mir1.76\Data\Weapon.wil';
g_WWeaponImages.Initialize;
g_WMagicImages.DDraw := DXDrawHuman.DDraw;
g_WMagicImages.FileName := 'E:\mirClient\Mir1.76\Data\Magic.wil';
g_WMagicImages.Initialize;
g_WMagic2Images.DDraw := DXDrawHuman.DDraw;
g_WMagic2Images.FileName := 'E:\mirClient\Mir1.76\Data\Magic2.wil';
g_WMagic2Images.Initialize;
end;
procedure TForm1.ButtonPlayClick(Sender: TObject);
begin
TimerShow.Enabled := True;
MemoResult.Text := ListBoxJob.Items[ListBoxJob.ItemIndex] + ' ' +
ListBoxSex.Items[ListBoxSex.ItemIndex] + ' ' +
ListBoxDress.Items[ListBoxDress.ItemIndex] + ' ' +
ListBoxAction.Items[ListBoxAction.ItemIndex] + ' ' +
ListBoxDirect.Items[ListBoxDirect.ItemIndex];
Actor1.m_nCurrX := StrToIntDef(EditX.Text, 400);
Actor1.m_nCurrY := StrToIntDef(EditY.Text, 300);
Actor1.m_btWeapon := StrToIntDef(Edit1.Text, 0);
if Actor1.m_btWeapon > 33 then
Actor1.m_btWeapon := 0;
Actor1.m_nHitEffectNumber := StrToIntDef(Edit2.Text, 0);
if Actor1.m_nHitEffectNumber > 5 then
Actor1.m_nHitEffectNumber := 0;
Actor1.m_CurMagic.EffectNumber := StrToIntDef(Edit3.Text, 0);
if Actor1.m_CurMagic.EffectNumber > 31 then
Actor1.m_CurMagic.EffectNumber := 0;
if Actor1.m_CurMagic.EffectNumber > 0 then
begin
with Actor1.m_CurMagic do
begin
ServerMagicCode := 1;
MagicSerial := 1;
Target := 1;
EffectType := mtFly;
TargX := StrToIntDef(Edit4.Text,100);
TargY := StrToIntDef(Edit5.Text,100);;
Recusion := False;
AniTime := 80;
end;
end;
case ListBoxSex.ItemIndex of
0: Actor1.m_btSex := 0;
1: Actor1.m_btSex := 1;
else
Actor1.m_btSex := 0;
end;
case ListBoxJob.ItemIndex of
0: Actor1.m_btJob := 0;
1: Actor1.m_btJob := 1;
2: Actor1.m_btJob := 2;
else
Actor1.m_btJob := 0;
end;
case ListBoxDress.ItemIndex of
0: Actor1.m_btDress := 0;
1: Actor1.m_btDress := 1;
2: Actor1.m_btDress := 2;
3:
begin
case ListBoxJob.ItemIndex of
0: Actor1.m_btDress := 3;
1: Actor1.m_btDress := 4;
2: Actor1.m_btDress := 5;
else
Actor1.m_btDress := 0;
end;
end;
4:
begin
case ListBoxJob.ItemIndex of
0: Actor1.m_btDress := 6;
1: Actor1.m_btDress := 7;
2: Actor1.m_btDress := 8;
else
Actor1.m_btDress := 0;
end;
end;
else
Actor1.m_btDress := 0;
end;
case ListBoxAction.ItemIndex of
0: Actor1.m_btAtc := ActStand;
1: Actor1.m_btAtc := ActWalk;
2: Actor1.m_btAtc := ActRun;
3: Actor1.m_btAtc := ActRushLeft;
4: Actor1.m_btAtc := ActRushRight;
5: Actor1.m_btAtc := ActWarMode;
6: Actor1.m_btAtc := ActHit;
7: Actor1.m_btAtc := ActHeavyHit;
8: Actor1.m_btAtc := ActBigHit;
9: Actor1.m_btAtc := ActFireHitReady;
10: Actor1.m_btAtc := ActSpell;
11: Actor1.m_btAtc := ActSitdown;
12: Actor1.m_btAtc := ActStruck;
13: Actor1.m_btAtc := ActDie;
else
Actor1.m_btAtc := ActStand;
end;
case ListBoxDirect.ItemIndex of
0: Actor1.m_btDir := DR_UP;
1: Actor1.m_btDir := DR_UPRIGHT;
2: Actor1.m_btDir := DR_RIGHT;
3: Actor1.m_btDir := DR_DOWNRIGHT;
4: Actor1.m_btDir := DR_DOWN;
5: Actor1.m_btDir := DR_DOWNLEFT;
6: Actor1.m_btDir := DR_LEFT;
7: Actor1.m_btDir := DR_UPLEFT;
else
Actor1.m_btDir := DR_UP;
end;
case ListBoxHair.ItemIndex of
0: Actor1.m_btHair := 0;
1: Actor1.m_btHair := 1;
2: Actor1.m_btHair := 2;
3: Actor1.m_btHair := 3;
4: Actor1.m_btHair := 4;
5: Actor1.m_btHair := 5;
6: Actor1.m_btHair := 6;
else
Actor1.m_btHair := 0;
end;
Actor1.CalcActorFrame;
end;
procedure TForm1.TimerShowTimer(Sender: TObject);
begin
DXDrawHuman.Surface.Fill(clBlack);
PlayScence(DXDrawHuman.Surface);
DXDrawHuman.Flip;
end;
constructor TActor.Create;
begin
m_BodySurface := nil;
m_nHairOffset := -1;
m_btHair := 0;
m_HairSurface := nil;
m_nWeaponOffset := -1;
m_btWeapon := 0;
m_WeaponSurface := nil;
m_nCurrentFrame := -1;
m_nPx := 0;
m_nPy := 0;
end;
destructor TActor.Destroy;
begin
end;
procedure TActor.CalcActorFrame;
begin
m_nHairOffset := HUMANFRAME * m_btHair;
m_boUseMagic := FALSE;
m_boHitEffect := FALSE;
m_nCurrentFrame := -1;
case m_btAtc of
ActStand:
begin
m_nStartFrame := HA.ActStand.start + m_btDir * (HA.ActStand.frame +
HA.ActStand.skip);
m_nEndFrame := m_nStartFrame + HA.ActStand.frame - 1;
m_dwFrameTime := HA.ActStand.ftime;
m_dwStartTime := GetTickCount;
end;
ActWalk:
begin
m_nStartFrame := HA.ActWalk.start + m_btDir * (HA.ActWalk.frame +
HA.ActWalk.skip);
m_nEndFrame := m_nStartFrame + HA.ActWalk.frame - 1;
m_dwFrameTime := HA.ActWalk.ftime;
m_dwStartTime := GetTickCount;
m_nMaxTick := HA.ActWalk.UseTick;
m_nCurTick := 0;
end;
ActRun:
begin
m_nStartFrame := HA.ActRun.start + m_btDir * (HA.ActRun.frame +
HA.ActRun.skip);
m_nEndFrame := m_nStartFrame + HA.ActRun.frame - 1;
m_dwFrameTime := HA.ActRun.ftime;
m_dwStartTime := GetTickCount;
m_nMaxTick := HA.ActRun.UseTick;
m_nCurTick := 0;
end;
ActRushLeft:
begin
m_nStartFrame := HA.ActRushLeft.start + m_btDir * (HA.ActRushLeft.frame
+ HA.ActRushLeft.skip);
m_nEndFrame := m_nStartFrame + HA.ActRushLeft.frame - 1;
m_dwFrameTime := HA.ActRushLeft.ftime;
m_dwStartTime := GetTickCount;
m_nMaxTick := HA.ActRushLeft.UseTick;
m_nCurTick := 0;
end;
ActRushRight:
begin
m_nStartFrame := HA.ActRushRight.start + m_btDir *
(HA.ActRushRight.frame + HA.ActRushRight.skip);
m_nEndFrame := m_nStartFrame + HA.ActRushRight.frame - 1;
m_dwFrameTime := HA.ActRushRight.ftime;
m_dwStartTime := GetTickCount;
m_nMaxTick := HA.ActRushRight.UseTick;
m_nCurTick := 0;
end;
ActWarMode:
begin
m_nStartFrame := HA.ActWarMode.start + m_btDir * (HA.ActWarMode.frame +
HA.ActWarMode.skip);
m_nEndFrame := m_nStartFrame + HA.ActWarMode.frame - 1;
m_dwFrameTime := HA.ActWarMode.ftime;
m_dwStartTime := GetTickCount;
m_nMaxTick := HA.ActWarMode.UseTick;
end;
ActHit:
begin
m_nStartFrame := HA.ActHit.start + m_btDir * (HA.ActHit.frame +
HA.ActHit.skip);
m_nEndFrame := m_nStartFrame + HA.ActHit.frame - 1;
m_dwFrameTime := HA.ActHit.ftime;
m_dwStartTime := GetTickCount;
m_boHitEffect := TRUE;
end;
ActHeavyHit:
begin
m_nStartFrame := HA.ActHeavyHit.start + m_btDir * (HA.ActHeavyHit.frame
+ HA.ActHeavyHit.skip);
m_nEndFrame := m_nStartFrame + HA.ActHeavyHit.frame - 1;
m_dwFrameTime := HA.ActHeavyHit.ftime;
m_dwStartTime := GetTickCount;
end;
ActBigHit:
begin
m_nStartFrame := HA.ActBigHit.start + m_btDir * (HA.ActBigHit.frame +
HA.ActBigHit.skip);
m_nEndFrame := m_nStartFrame + HA.ActBigHit.frame - 1;
m_dwFrameTime := HA.ActBigHit.ftime;
m_dwStartTime := GetTickCount;
end;
ActFireHitReady:
begin
m_nStartFrame := HA.ActFireHitReady.start + m_btDir *
(HA.ActFireHitReady.frame +
HA.ActFireHitReady.skip);
m_nEndFrame := m_nStartFrame + HA.ActFireHitReady.frame - 1;
m_dwFrameTime := HA.ActFireHitReady.ftime;
m_dwStartTime := GetTickCount;
end;
ActSpell:
begin
m_nStartFrame := HA.ActSpell.start + m_btDir * (HA.ActSpell.frame +
HA.ActSpell.skip);
m_nEndFrame := m_nStartFrame + HA.ActSpell.frame - 1;
m_dwFrameTime := HA.ActSpell.ftime;
m_dwStartTime := GetTickCount;
m_nCurEffFrame := 0;
m_boUseMagic := TRUE;
m_nSpellFrame := 10; //默认为10帧 而SPELL 动作只有6帧
if m_CurMagic.EffectNumber = 26 then
begin
m_nSpellFrame := 20;
end;
end;
ActSitdown:
begin
m_nStartFrame := HA.ActSitdown.start + m_btDir * (HA.ActSitdown.frame +
HA.ActSitdown.skip);
m_nEndFrame := m_nStartFrame + HA.ActSitdown.frame - 1;
m_dwFrameTime := HA.ActSitdown.ftime;
m_dwStartTime := GetTickCount;
end;
ActStruck:
begin
m_nStartFrame := HA.ActStruck.start + m_btDir * (HA.ActStruck.frame +
HA.ActStruck.skip);
m_nEndFrame := m_nStartFrame + HA.ActStruck.frame - 1;
m_dwFrameTime := HA.ActStruck.ftime;
m_dwStartTime := GetTickCount;
end;
ActDie:
begin
m_nStartFrame := HA.ActDie.start + m_btDir * (HA.ActDie.frame +
HA.ActDie.skip);
m_nEndFrame := m_nStartFrame + HA.ActDie.frame - 1;
m_dwFrameTime := HA.ActDie.ftime;
m_dwStartTime := GetTickCount;
end;
end;
end;
procedure TActor.Run;
var
prv: integer;
begin
prv := m_nCurrentFrame;
if (m_nCurrentFrame < m_nStartFrame) or (m_nCurrentFrame > m_nEndFrame) then
m_nCurrentFrame := m_nStartFrame;
if GetTickCount - m_dwStartTime > m_dwFrameTime then //帧时间到
begin
if m_nCurrentFrame < m_nEndFrame then
begin
if m_boUseMagic then
begin
if (m_nCurEffFrame = m_nSpellFrame - 2) then //定到最后一帧似乎效果好点?
begin
Inc(m_nCurrentFrame);
Inc(m_nCurEffFrame);
m_dwStartTime := GetTickCount;
end
else
begin
if m_nCurrentFrame < m_nEndFrame - 1 then
//定在倒数第二帧,等待效果帧上来
Inc(m_nCurrentFrame);
Inc(m_nCurEffFrame);
m_dwStartTime := GetTickCount;
end;
end
else
begin
Inc(m_nCurrentFrame); //增加帧
m_dwStartTime := GetTickCount;
end;
end
else //到行为动作的尾帧
begin
begin
// m_nCurrentFrame := m_nStartFrame;
// m_dwStartTime := GetTickCount;
end;
end;
end;
if m_boUseMagic then
begin
if m_nCurEffFrame = m_nSpellFrame - 1 then //魔法起手式到最后一帧了
begin
if m_CurMagic.ServerMagicCode > 0 then
begin
with m_CurMagic do
MagicEff1 := TMagicEff.Create(ServerMagicCode,
EffectNumber,
m_nCurrX, m_nCurrY,
TargX, TargY,
EffectType,
Recusion,
AniTime);
form1.MemoResult.Text := ' MagicEff1 ';
end;
m_CurMagic.ServerMagicCode := 0;
end;
end;
if prv <> m_nCurrentFrame then
begin
// m_dwLoadSurfaceTime := GetTickCount;
LoadSurface;
end;
end;
procedure TActor.LoadSurface;
begin
m_BodySurface := g_WHumImgImages.GetCachedImage(HUMANFRAME * (m_btDress * 2 +
m_btSex) +
m_nCurrentFrame, m_nPx, m_nPy);
if m_nHairOffset >= 0 then
m_HairSurface := g_WHairImgImages.GetCachedImage(m_nHairOffset +
m_nCurrentFrame, m_nHairPx, m_nHairPy)
else
m_HairSurface := nil;
m_WeaponSurface := g_WWeaponImages.GetCachedImage(HUMANFRAME * (m_btWeapon * 2
+
m_btSex) +
m_nCurrentFrame, m_nWeaponPx, m_nWeaponPy);
end;
procedure TActor.DrawChr(dsurface: TDirectDrawSurface; dx, dy: integer);
var
idx, ax, ay: integer;
d: TDirectDrawSurface;
wimg: TWILImages;
begin
if (m_nCurrentFrame >= 0) and (m_nCurrentFrame <= 599) then
m_nWpord := WORDER[m_btSex, m_nCurrentFrame];
if (m_nWpord = 0) and (m_WeaponSurface <> nil) then //武器在身体后
dsurface.Draw(dx + m_nWeaponPx, dy + m_nWeaponPy,
m_WeaponSurface.ClientRect,
m_WeaponSurface, True);
if m_BodySurface <> nil then
dsurface.Draw(dx + m_nPx, dy + m_nPy, m_BodySurface.ClientRect,
m_BodySurface, True);
if m_HairSurface <> nil then
dsurface.Draw(dx + m_nHairPx, dy + m_nHairPy, m_HairSurface.ClientRect,
m_HairSurface, True);
if (m_nWpord = 1) and (m_WeaponSurface <> nil) then //武器在身体前
dsurface.Draw(dx + m_nWeaponPx, dy + m_nWeaponPy,
m_WeaponSurface.ClientRect,
m_WeaponSurface, True);
//刀光效果
if m_boHitEffect and (m_nHitEffectNumber > 0) then
begin
form1.GetEffectBase(m_nHitEffectNumber - 1, 1, wimg, idx);
idx := idx + m_btDir * 10 + (m_nCurrentFrame - m_nStartFrame);
if wimg <> nil then
d := wimg.GetCachedImage(idx, ax, ay);
if d <> nil then
dsurface.Drawadd(Rect(dx + ax, dy + ay, dx + ax + d.Width, dy + ay +
d.Height),
d.ClientRect,
d, True, 255);
end;
//施法效果?
if m_boUseMagic and (m_CurMagic.EffectNumber > 0) then
begin
if m_nCurEffFrame in [0..m_nSpellFrame - 1] then
begin
form1.GetEffectBase(m_CurMagic.EffectNumber - 1, 0, wimg, idx);
idx := idx + m_nCurEffFrame;
if wimg <> nil then
d := wimg.GetCachedImage(idx, ax, ay);
if d <> nil then
dsurface.Drawadd(Rect(dx + ax, dy + ay, dx + ax + d.Width, dy + ay +
d.Height),
d.ClientRect,
d, True, 255);
end;
end;
end;
procedure TForm1.PlayScence(MSurface: TDirectDrawSurface);
begin
{
movetick := False;
if GetTickCount - m_dwMoveTime > 60 then
begin
m_dwMoveTime := GetTickCount;
movetick := True;
end;
if movetick then
begin
Actor1.Run;
end;
}
Actor1.Run;
Actor1.DrawChr(MSurface, Actor1.m_nCurrX, Actor1.m_nCurrY);
if MagicEff1 <> nil then
begin
MagicEff1.Run;
MagicEff1.DrawEff(MSurface);
end;
end;
procedure TForm1.ButtonStopClick(Sender: TObject);
begin
TimerShow.Enabled := False;
end;
procedure TForm1.GetEffectBase(mag, mtype: integer; var wimg: TWILImages; var
idx:
integer);
begin
wimg := nil;
idx := 0;
case mtype of
1:
begin
wimg := g_WMagicImages;
idx := HitEffectBase[mag];
end;
0:
begin
case mag of
8, 27:
begin
wimg := g_WMagic2Images; //Magic2.wil
if mag in [0..30] then
idx := EffectBase[mag];
end;
else
begin
wimg := g_WMagicImages;
if mag in [0..30] then
idx := EffectBase[mag];
end;
end;
end;
end;
end;
procedure TMagicEff.GetFlyXY(ms: Integer; var fx, fy: integer);
begin
end;
constructor TMagicEff.Create(id, effnum, sx, sy, tx, ty: Integer; mtype:
TMagicType;
Recusion: Boolean; anitime: Integer);
var
tax, tay: Integer;
begin
case mtype of
mtReady:
begin
end;
mtFly, mtBujaukGroundEffect, mtExploBujauk:
begin
Start := 0;
Frame := 6;
CurFrame := Start;
FixedEffect := False;
Repetition := Recusion;
ExplosionFrame := 10;
end;
mt12:
begin
start := 0;
Frame := 6;
CurFrame := Start;
FixedEffect := False;
Repetition := Recusion;
ExplosionFrame := 1;
end;
mtExplosion, mtThuder, mtLightingThunder:
begin
start := 0;
Frame := -1;
CurFrame := Start;
FixedEffect := True;
Repetition := False;
ExplosionFrame := 10;
end;
mtFlyAxe:
begin
start := 0;
Frame := 3;
CurFrame := Start;
FixedEffect := False;
Repetition := Recusion;
ExplosionFrame := 3;
end;
mtFlyarrow:
begin
start := 0;
Frame := 1;
CurFrame := Start;
FixedEffect := False;
Repetition := Recusion;
ExplosionFrame := 1;
end;
end;
ServerMagicId := id;
TargerActor := nil;
if effnum > 0 then
form1.GetEffectBase(effnum - 1, 0, ImgLib, EffectBase);
// ImgLib := g_WMagicImages;
// EffectBase := effnum; //传递过来的参数
TargetX := tx;
TargetY := ty;
fireX := sx;
fireY := sy;
OldFlyX := sx;
OldFlyY := sy;
FlyX := sx;
FlyY := sy;
FlyXf := sx;
FlyYf := sy;
MagExplionBase := EffectBase + EXPLOSIONBASE;
Light := 1;
if fireX <> TargetX then
tax := Abs(TargetX - fireX)
else
tax := 1;
if fireY <> TargetY then
tay := Abs(TargetY - fireY)
else
tay := 1;
if Abs(fireX - TargetX) > Abs(fireY - TargetY) then
begin
firedisX := Round((TargetX - fireX) * (500 / tax));
firedisY := Round((TargetY - fireY) * (500 / tax));
end
else
begin
firedisX := Round((TargetX - fireX) * (500 / tay));
firedisY := Round((TargetY - fireY) * (500 / tay));
end;
NextFrameTime := 80;
m_dwFrameTime := GetTickCount; //建立的帧时间点,
M_dwStartTime := GetTickCount;
steptime := GetTickCount;
repeattime := anitime;
Dir16 := GetFlyDirection16(sx, sy, tx, ty);
OldDir16 := Dir16;
NextEffect := nil;
m_boActive := True;
prevdisX := 99999;
prevdisY := 99999;
end;
destructor TMagicEff.Destroy;
begin
inherited Destroy;
end;
function TMagicEff.Run: Boolean;
begin
Result := Shift;
if Result then
if GetTickCount - M_dwStartTime > 10000 then //魔法效果超时
Result := False //运行失败
else
Result := True;
end;
function TMagicEff.Shift: Boolean;
function OverThrough(olddir, newdir: Integer): Boolean;
begin
Result := False;
if Abs(olddir - newdir) >= 2 then
begin
Result := True;
if ((olddir = 0) and (newdir = 15)) or ((olddir = 15) and (newdir = 0))
then
Result := False;
end;
end;
var
i, rrx, rry, ms, stepx, stepy, newstepx, newstepy, nn: Integer;
tax, tay, shx, shy, passdir16: Integer;
stepxf, stepyf: Real;
crash: Boolean;
begin
Result := True;
if Repetition then
begin
if GetTickCount - steptime > LongWord(NextFrameTime) then
begin
steptime := GetTickCount;
Inc(CurFrame);
if CurFrame > Start + Frame - 1 then
CurFrame := Start; //重复模式,回到开始帧图
end;
end
else
begin
if (Frame > 0) and (GetTickCount - steptime > LongWord(NextFrameTime)) then
begin
steptime := GetTickCount;
Inc(CurFrame);
if CurFrame > Start + Frame - 1 then
begin
CurFrame := Start + Frame - 1; //不重复模式,定在最后一帧
Result := False; //修改返回标志。
end;
end;
end;
if (not FixedEffect) then //不修正效果,其实是飞行中的效果
begin
crash := False;
begin
ms := GetTickCount - m_dwFrameTime;
m_dwFrameTime := GetTickCount;
if FlyX <> TargetX then
tax := Abs(TargetX - FlyX)
else
tax := 1;
if FlyY <> TargetY then
tay := Abs(TargetY - FlyY)
else
tay := 1;
if Abs(FlyX - TargetX) > Abs(FlyY - TargetY) then
begin
newfiredisX := Round((TargetX - FlyX) * (500 / tax));
newfiredisY := Round((TargetY - FlyY) * (500/ tax));
end
else
begin
newfiredisX := Round((TargetX - FlyX) * (500 / tay));
newfiredisY := Round((TargetY - FlyY) * (500/ tay));
end;
if firedisX < newfiredisX then
firedisX := firedisX + _MAX(1, (newfiredisX - firedisX) div 10);
if firedisX > newfiredisX then
firedisX := firedisX - _MAX(1, (firedisX - newfiredisX) div 10);
if firedisY < newfiredisY then
firedisY := firedisY + _MAX(1, (newfiredisY - firedisY) div 10);
if firedisY > newfiredisY then
firedisY := firedisY - _MAX(1, (firedisY - newfiredisY) div 10);
stepxf := (firedisX / 700) * ms;
stepyf := (firedisY / 700) * ms;
FlyXf := FlyXf + stepxf;
FlyYf := FlyYf + stepyf;
FlyX := Round(FlyXf);
FlyY := Round(FlyYf);
OldFlyX := FlyX;
OldFlyY := FlyY;
passdir16 := GetFlyDirection16(FlyX, FlyY, TargetX, TargetY);
if ((Abs(TargetX - FlyX) <= 15) and (Abs(TargetY - FlyY) <= 15)) or
((Abs(TargetX - FlyX) >= prevdisX) and (Abs(TargetY - FlyY) >=
prevdisY))
or OverThrough(OldDir16, passdir16) then
begin
crash := True;
form1.MemoResult.Text := ' crash := True';
end
else
begin
prevdisX := Abs(TargetX - flyx);
prevdisY := Abs(TargetY - FlyY);
end;
OldDir16 := passdir16;
end ;
if crash then
begin
FixedEffect := True;
Start := 0;
Frame := ExplosionFrame;
CurFrame := Start;
Repetition := False;
end;
end;
if FixedEffect then
begin
if Frame = -1 then
Frame := ExplosionFrame;
FlyX := TargetX;
FlyY := TargetY;
end;
end;
procedure TMagicEff.DrawEff(surface: TDirectDrawSurface);
var
img: Integer;
d: TDirectDrawSurface;
shx, shy: Integer;
begin
if m_boActive and ((Abs(FlyX - fireX) > 15) or (Abs(FlyY - fireY) > 15) or
FixedEffect) then
begin
if not FixedEffect then
begin //飞行动画
img := EffectBase + FLYBASE + Dir16 * 10;
d := ImgLib.GetCachedImage(img + CurFrame, px, py);
if d <> nil then
begin
// surface.Draw(FlyX + px, FlyY + py, d.ClientRect, d, True);
surface.Drawadd(
Rect(FlyX + px, FlyY + py, FlyX + px + d.Width, FlyY + py + d.Height),
d.ClientRect,
d, True, 255);
end;
end
else
begin //爆炸动画
img := MagExplionBase + CurFrame;
d := ImgLib.GetCachedImage(img, px, py);
if d <> nil then
begin
// surface.Draw(FlyX + px, FlyX + py, d.ClientRect, d, True);
surface.Drawadd(
Rect(FlyX + px, FlyY + py, FlyX + px + d.Width, FlyY + py + d.Height),
d.ClientRect,
d, True, 255);
end;
end;
end;
end;
end.
总结:
1,变量,记得给赋值,类里面的变量,可以在CREAT里面进行赋。
也许有的变量不需要赋初始值,是个中间量。 但是也不能判断是不是赋值过了就拿来运算了。
开始这个总是显示不正常,看了一遍又一遍,折腾1小时,找不出问题,最后发现是flyXf 没有被赋初始值,
应该是可以通过 DEBUG 来看变量发现, 但是我现在还不会DUBUG ~~~
2,下一步,实现角色的移动动画,走,跑一个地图单元,而不是在原地的走跑的动画。
3,同时进行 DEBUG 的简单学习,设置断点?设置看变量?

浙公网安备 33010602011771号