代码内将每个actor的动作细分为  站立 行走 攻击 死亡 等等。

而每个动作都包含8个方向的定义。指定如何从资源文件中 获取相应的纹理。

以下是方向的常量

  // 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;

以下是动作定义。

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

不管人类还是NPC或者是怪物,其当前动作 都可以使用TActionInfo 来指定 读取规则。

而人类是包含以下动作的

  THumanAction = packed record //人物动作ActStand: TActionInfo; //1  站立ActWalk: TActionInfo; //8   行走ActRun: TActionInfo; //8     跑ActRushLeft: TActionInfo; // 左冲锋?ActRushRight: TActionInfo; //右冲锋ActWarMode: TActionInfo; ActHit: TActionInfo; //攻击ActHeavyHit: TActionInfo; //重击ActBigHit: TActionInfo; //大击ActFireHitReady: TActionInfo; //烈火攻击准备?ActSpell: TActionInfo; //使用法术ActSitdown: TActionInfo; //1   //坐下ActStruck: TActionInfo; //3     //被攻击ActDie: TActionInfo; //4      //死亡ActSerieHit: array[0..18 - 1] of TActionInfo;  //连击动作

同时定义了一个全局人类读取规则

{人类动作定义}
HumAction: THumanAction = (//       开始帧      有效帧    跳过帧   每帧延迟    (意义未知)ActStand: (start: 0; frame: 4; skip: 4; ftime: 200; usetick: 0); //0-63  站立ActWalk: (start: 64; frame: 6; skip: 2; ftime: 90; usetick: 2);  //64-127   行走ActRun: (start: 128; frame: 6; skip: 2; ftime: 120; usetick: 3);  //128- 191    跑步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: 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);ActSerieHit:(  //连击(start: 0; frame: 6; skip: 4; ftime: 60; usetick: 0), //0(start: 80; frame: 8; skip: 2; ftime: 60; usetick: 0), //1(start: 160; frame: 15; skip: 5; ftime: 60; usetick: 0), //2(start: 320; frame: 6; skip: 4; ftime: 60; usetick: 0), //3(start: 400; frame: 13; skip: 7; ftime: 60; usetick: 0), //4(start: 560; frame: 10; skip: 0; ftime: 60; usetick: 0), //5(start: 640; frame: 6; skip: 4; ftime: 60; usetick: 0), //6(start: 720; frame: 6; skip: 4; ftime: 60; usetick: 0), //7(start: 800; frame: 8; skip: 2; ftime: 60; usetick: 0), //8(start: 880; frame: 10; skip: 0; ftime: 60; usetick: 0), //9(start: 960; frame: 10; skip: 0; ftime: 60; usetick: 0), //10(start: 1040; frame: 13; skip: 7; ftime: 60; usetick: 0), //11(start: 1200; frame: 6; skip: 4; ftime: 60; usetick: 0), //12(start: 1280; frame: 6; skip: 4; ftime: 60; usetick: 0), //13(start: 1360; frame: 9; skip: 1; ftime: 60; usetick: 0), //14(start: 1440; frame: 12; skip: 8; ftime: 60; usetick: 0), //15(start: 1600; frame: 12; skip: 8; ftime: 60; usetick: 0), //16(start: 1760; frame: 14; skip: 6; ftime: 60; usetick: 0) //17));

而对于怪物来说。也定义一些基本的动作状态:

    TMonsterAction = packed recordActStand: TActionInfo; //1ActWalk: TActionInfo; //8ActAttack: TActionInfo; //6ActCritical: TActionInfo; //6 0x20 -ActStruck: TActionInfo; //3ActDie: TActionInfo; //4ActDeath: TActionInfo;

而关于怪物的读取规则就定义了许多。以配合读取不同的怪物资源。

如:

MA9: TMonsterAction = (//4C03D4ActStand: (start: 0; frame: 1; skip: 7; ftime: 200; usetick: 0);ActWalk: (start: 64; frame: 6; skip: 2; ftime: 120; usetick: 3);ActAttack: (start: 64; frame: 6; skip: 2; ftime: 150; usetick: 0);ActCritical: (start: 0; frame: 0; skip: 0; ftime: 0; usetick: 0);ActStruck: (start: 64; frame: 6; skip: 2; ftime: 100; usetick: 0);ActDie: (start: 0; frame: 1; skip: 7; ftime: 140; usetick: 0);ActDeath: (start: 0; frame: 1; skip: 7; ftime: 0; usetick: 0););

而对于NPC的读取规则定义 就是使用的怪物的定义。也就是说NPC的基本动作和怪物是一样的 只不过他们都是站立的 并不会行走,当然可以自己实现行走也是没问题的。

而actor的绘制,是通过TActor.DrawChr 这个函数来绘制的,而Actor实现的绘制只是身体的绘制并不包含武器 头发这种。

procedure TActor.DrawChr(dsurface: TTexture; dx, dy: Integer; blend: Boolean; boFlag: Boolean);//绘制玩家角色?
varidx, ax, ay: Integer;d: TTexture;ceff: TColorEffect;wimg: TGameImages;
begind := nil; if not CanDraw then Exit;if not (m_btDir in [0..7]) then Exit; //如果人物方向不在0.。7就退出if GetTickCount - m_dwLoadSurfaceTick > m_dwLoadSurfaceTime then beginm_dwLoadSurfaceTick := GetTickCount;LoadSurface;//此函数的作用就是载入纹理。end;ceff := GetDrawEffectValue; //获取当前绘制状态,是不是中毒 隐身 等等if m_BodySurface <> nil then begin DrawEffSurface(dsurface,m_BodySurface,dx + m_nPx + m_nShiftX,dy + m_nPy + m_nShiftY,blend,ceff); //在Dsurface上绘制出来。而Dsurface是全局纹理。end;if m_boUseMagic and (m_CurMagic.EffectNumber > 0) then begin //如果使用魔法并且魔法效果号>0if m_nCurEffFrame in [0..m_nSpellFrame - 1] then begin  GetEffectBase(m_CurMagic.EffectNumber - 1, 0, wimg, idx);idx := idx + m_nCurEffFrame;if wimg <> nil thend := wimg.GetCachedImage(idx, ax, ay);if d <> nil thenDrawBlend(dsurface,dx + ax + m_nShiftX,dy + ay + m_nShiftY,d); //混合绘制纹理end;end;
end;

以上函数是将纹理绘制出来而已。并没有写出如何按照规则读取出纹理。而读取纹理 其实是在Tactor.loadsurface

procedure TActor.LoadSurface;
varmimg: TGameImages;
beginmimg := g_WMonImages.Images[m_wAppearance]; //获取纹理图库 MonX.wilif mimg <> nil then begin     //如果纹理图库部位空if (not m_boReverseFrame) then begin      //GetOffset的函数是按照怪物的m_wAppearance(数据库内Appr) 返回图片的基地址。m_BodySurface := mimg.GetCachedImage(GetOffset(m_wAppearance) + m_nCurrentFrame, m_nPx, m_nPy);end else begin                            //m_nCurrentFrame就是t将动作计算成偏移图片的序号。m_BodySurface := mimg.GetCachedImage(GetOffset(m_wAppearance) + m_nEndFrame - (m_nCurrentFrame - m_nStartFrame),m_nPx, m_nPy);end;end;
end;

如上注释:m_nCurrentFrame就是将动作转换成偏移图片的序号。而将当前actor的动作转换成偏移序号的函数是TActor.CalcActorFrame

procedure TActor.CalcActorFrame;
varhaircount: Integer;
beginm_boUseMagic := False;m_nCurrentFrame := -1;m_nBodyOffset := GetOffset(m_wAppearance);  //按照怪物的appr(外观编号)获得偏移的序号。m_Action := GetRaceByPM(m_btRace, m_wAppearance);//按照Actor的Race(动作编号)获得怪物的绘制规则。是一个TMonsterAction.if m_Action = nil then Exit;//如果这个动作没有定义则不执行。 一下就是如何将当前动作结合动作规则将其转换成图片序号的详细过程case m_nCurrentAction ofSM_TURN: beginm_nStartFrame := m_Action.ActStand.start + m_btDir * (m_Action.ActStand.frame + m_Action.ActStand.skip);m_nEndFrame := m_nStartFrame + m_Action.ActStand.frame - 1;m_dwFrameTime := m_Action.ActStand.ftime;m_dwStartTime := GetTickCount;m_nDefFrameCount := m_Action.ActStand.frame;Shift(m_btDir, 0, 0, 1);end;SM_WALK, SM_RUSH, SM_RUSHKUNG, SM_BACKSTEP: beginm_nStartFrame := m_Action.ActWalk.start + m_btDir * (m_Action.ActWalk.frame + m_Action.ActWalk.skip);m_nEndFrame := m_nStartFrame + m_Action.ActWalk.frame - 1;m_dwFrameTime := m_Action.ActWalk.ftime;m_dwStartTime := GetTickCount;m_nMaxTick := m_Action.ActWalk.usetick;m_nCurTick := 0;m_nMoveStep := 1;if m_nCurrentAction = SM_BACKSTEP thenShift(GetBack(m_btDir), m_nMoveStep, 0, m_nEndFrame - m_nStartFrame + 1)elseShift(m_btDir, m_nMoveStep, 0, m_nEndFrame - m_nStartFrame + 1);end;SM_HIT: beginm_nStartFrame := m_Action.ActAttack.start + m_btDir * (m_Action.ActAttack.frame + m_Action.ActAttack.skip);m_nEndFrame := m_nStartFrame + m_Action.ActAttack.frame - 1;m_dwFrameTime := m_Action.ActAttack.ftime;m_dwStartTime := GetTickCount;//WarMode := TRUE;m_dwWarModeTime := GetTickCount;Shift(m_btDir, 0, 0, 1);end;SM_STRUCK: beginm_nStartFrame := m_Action.ActStruck.start + m_btDir * (m_Action.ActStruck.frame + m_Action.ActStruck.skip);m_nEndFrame := m_nStartFrame + m_Action.ActStruck.frame - 1;m_dwFrameTime := m_dwStruckFrameTime; //pm.ActStruck.ftime;m_dwStartTime := GetTickCount;Shift(m_btDir, 0, 0, 1);end;SM_DEATH: beginm_nStartFrame := m_Action.ActDie.start + m_btDir * (m_Action.ActDie.frame + m_Action.ActDie.skip);m_nEndFrame := m_nStartFrame + m_Action.ActDie.frame - 1;m_nStartFrame := m_nEndFrame;m_dwFrameTime := m_Action.ActDie.ftime;m_dwStartTime := GetTickCount;end;SM_NOWDEATH: beginm_nStartFrame := m_Action.ActDie.start + m_btDir * (m_Action.ActDie.frame + m_Action.ActDie.skip);m_nEndFrame := m_nStartFrame + m_Action.ActDie.frame - 1;m_dwFrameTime := m_Action.ActDie.ftime;m_dwStartTime := GetTickCount;end;SM_SKELETON: beginm_nStartFrame := m_Action.ActDeath.start + m_btDir;m_nEndFrame := m_nStartFrame + m_Action.ActDeath.frame - 1;m_dwFrameTime := m_Action.ActDeath.ftime;m_dwStartTime := GetTickCount;end;end;
end;

对于 NPC 和Hum 虽然有不同但也是按照此思路进行编码。

思考:对于绘制其实是将动作转换成相应的纹理将其绘制出来。而对于一个Actor只有BodySurface 也就是身体的纹理。而对于Hum 则有 武器 头发 翅膀 等效果。那么应该把将动作转换成纹理这个函数独立出来。 并不局限于某个类,将各种纹理 例如武器头发翅膀 这些按照一定规则独立出来。那么则可以以自由的方式组合某个Actor的纹理,可以拥有身体 武器  或者又拥有 头发 翅膀等等。

这样方便实现变身这种功能。只需要改变动作类型以及选择使用哪些纹理 即可实现。

ActionDrawObject. HumanDrawAction    MonDrawAction,  NpcDrawAction

关于热血传奇actor绘制的分析与思考相关推荐

  1. 注入游戏没有焦点_《热血传奇怀旧版》即将登陆咪咕快游 盛趣游戏端游上云再落一子...

    盛趣游戏云游戏业务开始提速.日前,回归最经典版本的<热血传奇怀旧版>重聚测试开启,并将独家上架咪咕快游云游戏平台.这是盛趣游戏与中移动咪咕互娱共建的擎云工作室正式落地后,双方在云游戏又一实 ...

  2. javascript高仿热血传奇游戏

    前言 游戏的第一个版本开发于14年,浏览器端使用html+css+js,服务端使用asp+php,通讯采用ajax,数据存储使用access+mySql.不过由于一些问题(当时还不会用node,用as ...

  3. 热血传奇 祖玛阁路径搜索

    最近突然间想怀旧一下热血传奇,于是去淘宝里买了个单机版的热血传奇.在祖玛阁中死了好几次,发现乱走是很消耗人品的事,网络上搜索出来的走法也是无效的,于是只能自己动手了. 打开MirServer\Mir2 ...

  4. R语言Kaplan-Meier绘制生存分析、Log-rank假设检验、Cox回归曲线实战案例:恶性黑色素瘤的术后数据生存分析

    R语言Kaplan-Meier绘制生存分析.Log-rank假设检验.Cox回归曲线实战案例:恶性黑色素瘤的术后数据生存分析 目录

  5. wegame饥荒一直连接中_23万人捧场热血传奇怀旧版,WeGame拯救计划,前景如何?...

    日前,<热血传奇怀旧版>正式于WeGame上线,截至开服前,平台共有近23万人预约了这款游戏,一跃成为平台最热游戏. 虽然和当年开服半年,便有30万在线人数的成绩还有所距离,但在目前的端游 ...

  6. unity怪物攻击玩家减血_热血传奇:游戏里要千万小心的小怪,玩家稍有不慎就要吃大亏...

    热血传奇这款网游当中,除了形形色色的武器和装备之外,或许数量较多的就是地图当中的各式各样怪物了,在这其中有怪物也是大的BOSS,有的很容易就可以解决的.像新手任务的钉耙猫.鹿.半兽:还有像例如赤月恶魔 ...

  7. 怪物刷新时间计时_热血传奇;散人对这类怪物可谓是情有独钟

    热血传奇游戏的每一个地图其实都是离不开怪物的,而每一个地图内的怪物也不相同,但是却都有一个相同点,那就是每一个地图内都会有一个极品的大boss,而这一类怪物掉落的东西也是非常让玩家所动容的,好装备基本 ...

  8. 传奇手游服务器搭建_热血传奇3月开服计划

    官方唯一正版授权的传奇手游<热血传奇>与您一起迎接3月份的到来! 新服即将开启,自由PK,体会热血快感!3月的开服计划如下,请玩家们提前做好战斗准备,前往沙巴克集结!最原汁原味的传奇手游, ...

  9. python蟒蛇绘制实例分析_011 实例2-Python蟒蛇绘制

    一."Python蟒蛇绘制"问题分析 1.1 Python蟒蛇绘制 用程序绘制一条蟒蛇 貌似很有趣,可以来试试 先学会蟒蛇绘制,再绘朵玫瑰花送给TA 设计蟒蛇的基本形状: 问题1: ...

最新文章

  1. 写给第十七届,来自十六届的感想与建议
  2. Python基本语法_强制数据类型转换
  3. 用文件fw读写链表_用FORTRAN95写的sgy文件读写程序
  4. 《Pro Ogre 3D Programming》读书笔记 之 第十章 布告板与粒子 第一部分 (转)
  5. myeclipse连接hadoop集群编程及问题解决
  6. 《金蝶ERP—K/3标准财务模拟实训(11.X版)》——第1章 金蝶K/3标准财务介绍 1.1 金蝶K/3标准财务系统介绍...
  7. Vue指令篇_v-model_数据双向绑定
  8. 结构体指针需要申请指针内存,结构体对象不需要申请对象内存
  9. 从单亲家庭内向小男生到哈佛耶鲁全奖,百万年薪的“男神学长”活出了一部励志偶像剧!
  10. 无需第三方,使用Mac预览合并多张图片
  11. 红橙Darren视频笔记 Handler源码简析与handler框架模拟 ThreadLocal
  12. C语言把整数转换为字符串
  13. 当大家都不理解你的时候,就是你成就的捷径
  14. 微信小程序云开发 数据库
  15. 苹果cms模板_万词无限模板站群黑帽SEO利器
  16. DW CS5及CC的部分序列号总结
  17. 一个手握安兔兔,一个执掌鲁大师,周鸿祎雷军这场仗谁能赢?
  18. python requests 爬取代理ip并验证(快代理西祠代理)
  19. 华为Atlas200DK的环境部署与运行demo(人脸识别)
  20. TestLink在线Excel用例转换xml

热门文章

  1. 获取axios返回的值
  2. 用学生用计算机打吃鸡游戏,电脑端游吃鸡怎么玩
  3. python测量不确定度程序设计_测量不确定度计算 - 用于计算测量不确定度的资源...
  4. Arduino—— 4*4按键
  5. 什么是PACS系统?其特点是什么?PACS系统应该具有哪些功能?
  6. 没想到!网络美女直播背后的真相居然是这样
  7. 【嵌入式开发】 嵌入式开发工具简介 (裸板调试示例 | 交叉工具链 | Makefile | 链接器脚本 | eclipse JLink 调试环境)
  8. React18学习(第一版---初级)保姆级教程
  9. STM32-通行闸机2(HAL库)
  10. 直播电商行业迎来新的里程碑!未来仍存在很大的想象空间