⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 actor.pas

📁 很多人想要研究的真彩传奇2客户端,一般来说传奇2的客户端是256色的,现在出了个飞尔真彩传奇,想必很吸引大家的眼球.现在把我收藏的拿出来一起共享
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit Actor;

interface

uses SysUtils, Windows, Math, DirectDraw, Globals, MirWil, MirMap, ObjFastBlt;


{------------------------------------------------------------------------------}
// 常量定义
{------------------------------------------------------------------------------}
const
  MAX_HUMANFRAME = 600; // 人类动画总帧数 [0..599]
  MAX_HAIR = 3; // 头发种类数     [0..2]
  MAX_WEAPON = 34; // 武器种类数     [0..34]

  WEAPON_BREAKING_BASE = 3750; // 武器破碎效果索引基址,每个方向10帧,共80帧 (magic.wil)
  MAGIC_BUBBLE_BASE = 0; // 魔法气泡效果索引基址 (magic.wil)

  STATE_BUBBLEDEFENCEUP = $00100000; // 魔法气泡

  // Actor 方向常量
  DIR_UP = 0;
  DIR_UPRIGHT = 1;
  DIR_RIGHT = 2;
  DIR_DOWNRIGHT = 3;
  DIR_DOWN = 4;
  DIR_DOWNLEFT = 5;
  DIR_LEFT = 6;
  DIR_UPLEFT = 7;


{------------------------------------------------------------------------------}
// 数据结构定义
{------------------------------------------------------------------------------}
type

  // 动作定义
  PActionInfo = ^TActionInfo;
  TActionInfo = record
    start: word; // 开始帧
    frame: word; // 帧数
    skip: word; // 跳过的帧数
    ftime: word; // 每帧的延迟时间(毫秒)
    usetick: byte; // (意义未知)
  end;

  // 玩家的动作定义
  PHumanAction = ^THumanAction;
  THumanAction = record
    ActStand: TActionInfo; //1
    ActWalk: TActionInfo; //8
    ActRun: TActionInfo; //8
    ActRushLeft: TActionInfo;
    ActRushRight: TActionInfo;
    ActWarMode: TActionInfo; //1
    ActHit: TActionInfo; //6
    ActHeavyHit: TActionInfo; //6
    ActBigHit: TActionInfo; //6
    ActFireHitReady: TActionInfo; //6
    ActSpell: TActionInfo; //6
    ActSitdown: TActionInfo; //1
    ActStruck: TActionInfo; //3
    ActDie: TActionInfo; //4
  end;

{------------------------------------------------------------------------------}
// TActor class
{------------------------------------------------------------------------------}
  TActor = class(TObject)
  protected
    FrameCount: word; // 当前动作的总帧数
    FrameStart: word; // 当前动作的开始帧索引
    FrameEnd: word; // 当前动作的结束帧索引
    FrameTime: word; // 当前动作每帧等待的时间

    FrameIndex: word; // 当前帧索引
    FrameTick: Cardinal; // 当前帧显示时的 GetTickCount

  public
    CurrentMap: TMirMap; // 当前人物所在地图

    CurrentAction: byte; // 当前动作
    Direction: byte; // 当前方向
    Appearance: word; // 外观显示(对 HumanActor 则相当于级别)
                                  // 对其它, 可用 GetOffset 获得

    IsInAction: Boolean; // 是否正处在一个 Action 事件中(ActStand 除外)

    MapX: word; // 处于地图上的位置(以 MapPoint 为单位)
    MapY: word;
    ShiftX: Integer; // 当前位移(像素单位, 用于 Walk, Run)
    ShiftY: Integer;
    MovX: Integer; // 上次 Walk, Run Action 的偏移值
    MovY: Integer;

    constructor Create(Map: TMirMap); virtual; abstract;

    // 重新计算动画帧
    procedure ReCalcFrames; virtual; abstract;
    // 根据经过的时间处理下一帧
    procedure ProcessFrame; virtual; abstract;
  end;


{------------------------------------------------------------------------------}
// THumanActor class
{------------------------------------------------------------------------------}
  THumanActor = class(TActor)
  private
  protected
    BodyOffset: word; // 身体图片索引的主偏移
    HairOffset: word; // 头发图片索引的主偏移
    WeaponOffset: word; // 武器图片索引的主偏移

    WeaponOrder: byte; // 武器绘制顺序(是否先于身体绘制)

    IsWeaponBreaking: Boolean; // 是否显示武器破碎效果
    WeaponBreakingFrame: word; // 武器破碎效果当前帧

  public
    Sex: byte; // 性别
    Job: byte; // 职业
    Hair: byte; // 发型
    Weapon: byte; // 武器

    constructor Create(Map: TMirMap); override;

    procedure ReCalcFrames; override;
    procedure ProcessFrame; override;
    procedure Draw(BackDxFastBlt: TDxFastBlt; X, Y, Width, Height: Integer);

    function CalcNextDirection: Boolean;
    // 移动至 MapPoint, 虽然 MapPoint 坐标定义为 Word, 这里必须用 Integer 代替
    // 因为玩家可以点击至 Map 坐标负方向进行转向
    procedure Walk(X, Y: Integer);
    procedure Run(X, Y: Integer);
    procedure Hit(X, Y: Integer);
  end;


const

{------------------------------------------------------------------------------}
// 人物动作图片索引
{------------------------------------------------------------------------------}
  // 以下二项数据组成 9 * 2 * 600 = 10800 幅图片
  // Appearance = [0..8] [没穿衣服/初级/中级/高级(武/法/道)/最高级(武/法/道)]
  // Sex        = [0..1] [男/女]

  // 每个 Appearance 包含 14 种 Action
  // 不同 Direction 的 Action = Action 的起始帧 * 8 * Direction
  // Action     = [0 - 13] (Action 数量与总帧数无关, 并非每个 Action 都 8 帧)
  // Direction  = [0 - 7]

  HUMANACTION_STAND = 0;
  HUMANACTION_WALK = 1;
  HUMANACTION_RUN = 2;
  HUMANACTION_RUSHLEFT = 3;
  HUMANACTION_RUSHRIGHT = 4;
  HUMANACTION_WARMODE = 5;
  HUMANACTION_HIT = 6;
  HUMANACTION_HEAVYHIT = 7;
  HUMANACTION_BIGHIT = 8;
  HUMANACTION_FIREHITREADY = 9;
  HUMANACTION_SPELL = 10;
  HUMANACTION_SITDOWN = 11;
  HUMANACTION_STRUCK = 12;
  HUMANACTION_DIE = 13;

  HUMANACTIONS: THumanAction =
  (
    //                开始帧      有效帧    跳过帧   每帧延迟    (意义未知)
    ActStand: (start: 0; frame: 4; skip: 4; ftime: 200; usetick: 0);
    ActWalk: (start: 64; frame: 6; skip: 2; ftime: 80; usetick: 2);
    ActRun: (start: 128; frame: 6; skip: 2; ftime: 90; usetick: 3);
    ActRushLeft: (start: 128; frame: 3; skip: 5; ftime: 120; usetick: 3);
    ActRushRight: (start: 131; frame: 3; skip: 5; ftime: 120; 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: 85; usetick: 0);
    ActHeavyHit: (start: 264; frame: 6; skip: 2; ftime: 90; usetick: 0);
    ActBigHit: (start: 328; frame: 8; skip: 0; ftime: 70; usetick: 0);
    ActFireHitReady: (start: 192; frame: 6; skip: 4; ftime: 70; usetick: 0);
    ActSpell: (start: 392; frame: 6; skip: 2; ftime: 60; usetick: 0);
    ActSitdown: (start: 456; frame: 2; skip: 0; ftime: 300; usetick: 0);
    ActStruck: (start: 472; frame: 3; skip: 5; ftime: 70; usetick: 0);
    ActDie: (start: 536; frame: 4; skip: 4; ftime: 120; usetick: 0);
    );

{  HUMANACTIONS: THumanAction =
  (
    //                开始帧      有效帧    跳过帧   每帧延迟    (意义未知)
    ActStand:        (start: 0;   frame: 4; skip: 4; ftime: 200; usetick: 0);
    ActWalk:         (start: 64;  frame: 6; skip: 2; ftime: 90;  usetick: 2);
    ActRun:          (start: 128; frame: 6; skip: 2; ftime: 120; usetick: 3);
    ActRushLeft:     (start: 128; frame: 3; skip: 5; ftime: 120; usetick: 3);
    ActRushRight:    (start: 131; frame: 3; skip: 5; ftime: 120; 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: 85;  usetick: 0);
    ActHeavyHit:     (start: 264; frame: 6; skip: 2; ftime: 90;  usetick: 0);
    ActBigHit:       (start: 328; frame: 8; skip: 0; ftime: 70;  usetick: 0);
    ActFireHitReady: (start: 192; frame: 6; skip: 4; ftime: 70;  usetick: 0);
    ActSpell:        (start: 392; frame: 6; skip: 2; ftime: 60;  usetick: 0);
    ActSitdown:      (start: 456; frame: 2; skip: 0; ftime: 300; usetick: 0);
    ActStruck:       (start: 472; frame: 3; skip: 5; ftime: 70;  usetick: 0);
    ActDie:          (start: 536; frame: 4; skip: 4; ftime: 120; usetick: 0);
  );
}

{------------------------------------------------------------------------------}
// 武器绘制顺序 (是否先于身体绘制: 0是/1否)
// WEAPONORDERS: array [Sex, FrameIndex] of Byte
{------------------------------------------------------------------------------}
  WEAPONORDERS: array[0..1, 0..MAX_HUMANFRAME - 1] of byte =
  (
    (
      //
    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,
      //
    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,
      //
    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,
      //
    0, 1, 1, 1, 0, 0, 0, 0,
      //
    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,
      //
    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,
      //
    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,
      //
    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,
      //
    0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 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, 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, 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, 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,
      //
    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,
      //
    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,
      //
    1, 1, 1, 1, 0, 0, 0, 0,
      //
    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,
      //
    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,
      //
    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,
      //
    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,
      //
    0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 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, 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, 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,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -