组装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 的简单学习,设置断点?设置看变量?