zoukankan      html  css  js  c++  java
  • 《楚河汉界分析》

    楚河汉界

    ——战斗系统分析

    1.  战斗资源

    人物和技能:

    楚河汉界中人物和技能是绑定的,放在同一个资源中。人物动画使用位图序列制作,技能效果使用矢量动画使效果更炫,更平滑。

    打斗效果:

    楚河汉界中战斗时,技能施加到人物身上之后,的效果是与技能独立的。所有的这些效果放在一个资源中,这些效果也是使用矢量动画制作。

     

    战斗中就是轮流播放人物的技能和添加技能伤害效果到目标上面。

    人物状态:

    不同状态分别在不同的层,通过控制层来显示状态。

    clip_image002

    2.  战斗控制

     

    游戏的主体操作UI都是通过页面构建出来的,只有一些打斗、地图、场景等等效果是使用Flash。游戏的控制逻辑都写在JavaScript脚本里面,Flash在主文件中注册了一系列回调函数供JavaScript调用。JavaScript负责与后台(PHP)交互,当需要Flash显示效果,如战斗,JavaScript根据PHP的返回结果调用Flash回调函数。

            private function addCallBack() : void

            {

                ExternalInterface.addCallback("is_loaded", Face.is_loaded);

                ExternalInterface.addCallback("set_var", Face.set_var);

                ExternalInterface.addCallback("get_var", Face.get_var);

                ExternalInterface.addCallback("set_cookie", Face.setCookie);

                ExternalInterface.addCallback("get_cookie", Face.getCookie);

                ExternalInterface.addCallback("set_pos", Scene.set_pos);

                ExternalInterface.addCallback("show_scene", Scene.show_scene);

                ExternalInterface.addCallback("move_scene", Scene.move_scene);

                ExternalInterface.addCallback("add_monster", Scene.add_monster);

                ExternalInterface.addCallback("del_monster", Scene.del_monster);

                ExternalInterface.addCallback("add_npc", Scene.add_npc);

                ExternalInterface.addCallback("del_npc", Scene.del_npc);

                ExternalInterface.addCallback("update_npc", Scene.update_npc);

                ExternalInterface.addCallback("update_player", Scene.update_player);

                ExternalInterface.addCallback("update_over", Scene.last_over);

                ExternalInterface.addCallback("story_role", Scene.story_role);

                ExternalInterface.addCallback("story_state", Scene.story_state);

                ExternalInterface.addCallback("stage_xy", Scene.stage_xy);

                ExternalInterface.addCallback("show_play", Combats.show_play);

                ExternalInterface.addCallback("quit_play", Combats.quit_play);

                ExternalInterface.addCallback("is_play", Combats.is_play);

                return;

            }// end function

    黑色粗体几个回调即战斗相关回调。

    战斗设计到九宫格排兵布阵、技能/装备、打斗顺序、胜负结果等等。

    排兵布阵

    楚河汉界使用九宫格方式排兵布阵,给9个位置分别编号(代码中用012345678)如下图所示:

    clip_image004

    排兵布阵会直接影响到战斗胜负,因为:

    l  排兵位置直接影响到怪物攻打我们队友的顺序;

    l  施展辅组技能(如加攻击、防御)队员位置,影响到哪些队友会受益,因此攻击力、防御值会收到影响

    进入战斗模式时,后台会下发两边初始的排兵布阵,如玩家打野猪的时候(http://s326.sh.ch.qq.com/do.php?c=duty&a=lineup&r=0.7727291548204278),返回以下布阵数据:

    {

        "tpl_data": {

            "members": {

                "4": {

                    "type": 1,

                    "skill": "61:2,",

                    "avatar": "2",

                    "swf": "1003",

                    "position": 4,

                    "level": 26,

                    "role_name": "吴秦",

                    "role_id": 0

                }

            },

            "monster": {

                "group_id": 90054,

                "type": 17,

                "monster_num": 1,

                "level": 20,

                "exp": 0,

                "money": 0,

                "borad_reward": 0,

                "contribute_reward": 0,

                "fight_limit": 2,

                "dialog": "我是可爱小野猪,皮肤比较黑,毛发比较粗,牙齿比较长,鼻子粉嘟嘟……",

                "img_id": 100529,

                "monster_units": {

                    "4": {

                        "monster_id": "90113",

                        "img_id": "100003",

                        "swf": "2001",

                        "level": "20",

                        "description": "猪未必是这个世界上最蠢的生物",

                        "monster_name": "野猪"

                    }

                }

            }

        },

        "tpl": [

            "duty_lineup"

        ],

        "tpl_ver": "032314",

        "tpl_arg": [

            4,

            "_duty_lineup_",

            true

        ]

    }

    以上数据表示左边编号为4的格子有一个玩家:"4":{"type":1,"skill":"61:2,","avatar":"2","swf":"1003","position":4,"level":26,"role_name":"吴秦","role_id":0};右边编号为4的格子有一个怪物:"4":{"monster_id":"90113","img_id":"100003","swf":"2001","level":"20","description":"猪未必是这个世界上最蠢的生物","monster_name":"野猪"}

    然而玩家可以改变布阵数据,如将玩家从编号为4的位置拖到编号为8的位置:

    http://s326.sh.ch.qq.com/do.php?c=duty&a=lineup_change&f=4&t=7&r=0.03912129900640776

    返回结果:<script type="text/javascript">_CALLBACK([["mt_cl",["0:7",":4",0]]]);</script>

    多人布阵也是类似。

     

    打斗顺序

    clip_image006

    当点击“攻击”按钮之后,Javascript告诉后台开始战斗(http://s326.sh.ch.qq.com/do.php?c=duty&a=attack&r=0.02707068482358438),后台计算战斗顺序、胜负等详细信息,然后返回给JavascriptJavascript调用Flash回调播放战斗效果。后台计算返回结果如下:

     

    [["cbt_py",["17282197",{"role_info":[[[{"cell_pos":7,"role_id":212640,"level":26,"life_max":1031,"life_now":1031,"vigour_max":100,"clique_id":2,"vigour_skill":"53:2:25:0","anger_skill":"","vigour_sec":1,"avatar":2,"swf":1003,"role_name":"吴秦"}]],

    [[{"cell_pos":4,"role_id":90113,"level":20,"life_max":330,"life_now":330,"vigour_max":100,"clique_id":0,"vigour_skill":"2001:1:30:0","anger_skill":"","vigour_sec":1,"avatar":100003,"swf":2001,"role_name":"野猪"}]]],

    "start_time":1333244413,"round_num":1,"result":-1,"combat_type":25,"total_time":30,"max_time":500,"monster_id":90054,"frame":140,"left":[7555,0],"bg":5,"item_drop":[],"item_get":[],"item_team":[],"good_item":[],"task_item":[],"role_exp":[],"role_money":[],

    "data":{"0":[[0,0,0]],"14":[[1,0,1,1,0,53,1],[13,0,75],[12,0,5],[12,1,5],[2,1,1,192,0],0],"18":[[1,1,1,1,0,2001,1],[3,1,5,-13],[13,1,70],[12,1,10],[12,0,10],[2,0,1,252,1],0],"28":[[1,0,1,1,0,53,1],[13,0,64],[12,0,15],[12,1,15],[2,1,1,186,0],[5,1],0],"29":[0]}}]],["r_u",[{"9":2,"36":0,"10":"17282197","21":369}]]]

    这些数据包含了所有的打斗信息,包括胜负"result":-1-1胜,0负),"data":{"0":[[0,0,0]].}打斗顺序、技能、伤害值,等等。

    JavaScript拿到这些数据之后,调用Flash的回调(重播也是调用的该回调,实际上是一个东西):

        public static function show_play(param1:Object) : void

        {

            var data:* = param1;

            try

            {

                if (m_combats[data.combat_id] == null)

                {//第一次

                    m_combats[data.combat_id] = new Combat(data);

                }

                else if (m_combats[data.combat_id].is_finished)

                {//重播效果

                    m_combats[data.combat_id].replay();

                }

                else

                {//播放效果

                    show_combat(data.combat_id);

                }

            }

            catch (e:Error)

            {

                Face.debug("Combats.show_play(" + data + ")");

                Face.debug(e);

            }

            return;

        }// end function

    宝宝可以使用该方式,开始打斗时通知后台,后台将计算结果返回给前台,前台根据后台返回的数据播放战斗效果。

     

    楚河汉界,在副本打怪的时候,可以直接在浏览器中输入http://s326.sh.ch.qq.com/do.php?c=duty&a=attack&r=0.02707068482358438,完成击杀怪物的动作,绕过去组队、布阵等操作,还可以连续击杀几个怪物。很容易做外挂

    clip_image008

     

     

    3.  战斗资源(对比精灵猎手)

    精灵猎手中人物、技能是分开的,所有的技能单独一个资源文件,宠物共享所有这些技能。当使用技能的时候,简单的两边的宠物替换为相应的即可。

    clip_image010

    技能打斗控制做在一个时间轴上(这点跟楚河汉界不一样,楚河是坐在不同的图层),同跳转帧标签来控制状态。

    宠物资源使用矢量图制作:

    clip_image011

    技能效果也使用矢量图制作:

    clip_image013

    技能打斗中两个怪物使用两个位图表示,然后根据实际替换为相应宠物。

     

    性能对比:

    精灵猎手,所有资源都采用矢量动画制作,相比楚河汉界部分使用位图序列,CPU相对不稳定有时会达到30+

    clip_image014(精灵猎手CPU占用,峰值在30左右)

    楚河汉界的CPU占用稳定在20以内:

    clip_image015(楚河汉界CPU占用峰值在20左右)

    当然这个技能的效果也有一定关系,两个游戏的技能效果不同,对CPU也有响应,不能完全反应问题。

     

     

    总结

     

    综合上面两款游戏,网页游戏打斗系统可以采用以下方式:

    clip_image001  技能效果使用矢量动画制作,使效果更好

    clip_image001[1]  人物动作动画,使用位图序列,减少CPU占用

    clip_image001[2]  人物打斗过程中的不同状态,可以使用楚河汉界的方式,把状态坐在不同的图层,通过控制图层来显示不同的动作

    clip_image001[3]  战斗数据通过后台计算下发,前台解析数据播放战斗效果即可

    clip_image001[4]  ……


    作者:吴秦
    出处:http://www.cnblogs.com/skynet/
    本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名吴秦(包含链接).

  • 相关阅读:
    Delphi cxGrid –--> RecordIndex out of Range
    局域网共享需要密码
    提高AdoQuery的速度
    string literals may have at most 255 elements
    delphi控件属性大全-详解-简介
    Cxgrid获取选中行列,排序规则,当前正在编辑的单元格内的值
    FastReport 使用说明
    delphi的取整函数round、trunc、ceil和floor
    cxGrid 速度
    SQL Server 无法在服务器上访问指定的路径或文件解决方法
  • 原文地址:https://www.cnblogs.com/skynet/p/2429004.html
Copyright © 2011-2022 走看看