产品资讯

联系方式

产品资讯当前位置: 主页 > 产品资讯 >

类魔兽国际moba技术体系的数值结构设计

发布者: 发布时间:2017-11-03

1.数值都用key value来保存,key是数值的类型,由NumericType来界说,value都是整数,float型也能够转成整数,例如乘以1000;key value保存特点会变得十分灵敏,例如法师没有能量特点,那么初始化法师目标不加能量的key value就好了。响马没有法力值,没有神通损伤等等,初始化就不必加这些。

2.魔兽国际中,一个数值由5个值来影响,能够一致运用一条公式:

final = (((base   add) * (100   pct) / 100)   finalAdd) * (100   finalPct) / 100;

比方说速度值speed,有个初始值speedbase,有个buff1添加10点绝对速度,那么buff1创立的时分会给speedadd加10,buff1删去的时分给speedadd减10,buff2添加20%的速度,那么buff2创立的时分给speedpct加20,buff2删去的时分给speedpct减20.乃至可能有buff3,会在终究值上再加100%,那么buff3将影响speedfinalpct。这5个值发作改动,一致运用Update函数就能够从头核算对应的特点了。buff装备中对应数值字段适当简略,buff装备中填上相应的NumericType,程序很轻松就能操作对应的数值相似魔兽国际,moba这种技术极端杂乱,灵敏性要求极高的技术体系,有必要需求一套及其灵敏的数值结构来调配。数值结构规划好了,完成技术体系就会十分简略,不然就是一场灾祸。

比方魔兽国际,一个人物的数值特点十分之多,移动速度,力气,肝火,能量,集中值,魔法值,血量,最大血量,物理进犯,物理防护,神通进犯,神通防护,等等多达几十种之多。特点跟特点之间又相互影响,buff又会给特点添加绝对值,添加百分比,或许某种buff又会在算完一切的添加值之后再来给你翻个倍。

一般的做法:

一般就是写个数值类:

class Numeric

{

    public int Hp;

    public int MaxHp;

    public int Speed;

    // 能量

    public int Energy;

    public int MaxEnergy;

    // 魔法

    public int Mp;

    public int MaxMp;

    .....

}

细心一想,我一个响马运用的是能量,为什么要有一个Mp的值?我一个法师运用的是魔法为什么要有能量的字段?纠结这个搞毛,当作没看见不就行了吗?真实不可,我来个承继?

// 法师数值

calss MageNumeric: Numeric

{

    // 魔法

    public int Mp;

    public int MaxMp;

}

 

// 响马数值

calss RougeNumeric: Numeric

{

    // 能量

    public int Energy;

    public int MaxEnergy;

}

10个种族,每个种族7,8种英豪,光这些数值类承继联系,你就得懵逼了吧。面向目标是难以习惯这种灵敏的杂乱的需求的。

再来看看Numeric类,每种数值可不能只规划一个字段,比方说,我有个buff会添加10点Speed,还有种buff添加50%的speed,那我至少还得加三个二级特点字段

class Numeric

{

    // 速度终究值

    public int Speed;

    // 速度初始值

    public int SpeedInit;

    // 速度添加值

    public int SpeedAdd;

    // 速度添加百分比值

    public int SpeedPct;

}

SpeedAdd跟SpeedPct改动后,进行一次核算,就能够算出终究的速度值。buff只需求去修正SpeedAdd跟SpeedPct就行了。

Speed=(SpeedInit   SpeedAdd)*(1   SpeedPct)/100

每种特点都可能有好几种直接影响值,能够想想这个类是多么巨大,初略估量得有100多个字段。费事的是核算公式根本一样,可是就是无法一致成一个函数,例如MaxHp,也有buff影响

class Numeric

{

    public int Speed;

    public int SpeedInit;

    public int SpeedAdd;

    public int SpeedPct;

 

    public int MaxHp;

    public int MaxHpInit;

    public int MaxHpAdd;

  &注册送彩金公司nbsp; public int MaxHpPct;

}

也得写个Hp的核算公式

MaxHp=(MaxHpInit   MaxHpAdd) * (1   MaxHpPct) / 100

几十种特点,就要写几十遍,而且每个二级特点改动都要正确调用对应的公式核算. 十分费事!
这样规划还有个很大的问题,buff装备表填对应的特点字段不是很好填,例如疾跑buff(添加速度50%),在buff表中怎样装备才能让程序简略的找到并操作SpeedPct字段呢?欠好搞。

ET结构采用了Key Value方式保存数值特点

using System.Collections.Generic;

 

namespace Model

{

    public enum NumericType

    {

        Max = 10000,

 

        Speed = 1000,

        SpeedBase = Speed * 10   1,

        SpeedAdd = Speed * 10   2,

        SpeedPct = Speed * 10   3,

        SpeedFinalAdd = Speed * 10   4,

        SpeedFinalPct = Speed * 10   5,

 

        Hp = 1001,

        HpBase = Hp * 10   1,

 

        MaxHp = 1002,

        MaxHpBase = MaxHp * 10   1,

        MaxHpAdd = MaxHp * 10   2,

        MaxHpPct = MaxHp * 10   3,

        MaxHpFinalAdd = MaxHp * 10   4,

        MaxHpFinalPct = MaxHp * 10   5,

    }

 

    public class NumericComponent: Component

    {

        public readonly Dictionary<int, int> NumericDic = new Dictionary<int, int>();

 

        public void Awake()

        {

            // 这儿初始化base

        }

 

        public float GetAsFloat(NumericType numericType)

        {

            return (float)GetByKey((int)numericType) / 10000;

        }

 

        public int GetAsInt(NumericType numericType)

        {

            return GetByKey((int)numericType);

        }

 

        public void Set(NumericType nt, float value)

        {

            this[nt] = (int) (value * 10000);

        }

 

        public void Set(NumericType nt, int value)

        {

            this[nt] = value;

        }

 

        public int this[NumericType numericType]

        {

            get

            {

                return this.GetByKey((int) numericType);

            }

            set

            {

                int v = this.GetByKey((int) numericType);

                if (v == value)

                {

                    return;

            注册送彩金    }

 

                NumericDic[(int)numericType] = value;

 

                Update(numericType);

            }

        }

 

        private int GetByKey(int key)

        {

            int value = 0;

            this.NumericDic.TryGetValue(key, out value);

            return value;

        }

 

        public void Update(NumericType numericType)

        {

            if (numericType > NumericType.Max)

            {

                return;

            }

            int final = (int) numericType / 10;

            int bas = final * 10   1;

            int add = final * 10   2;

            int pct = final * 10   3;

            int finalAdd = final * 10   4;

            int finalPct = final * 10   5;

 

            // 一个数值可能会多种状况影响,比方速度,加个buff可能添加速度绝对值100,也有些buff添加10%速度,所以一个值能够由5个值进行操控其终究成果

            // final = (((base   add) * (100   pct) / 100)   finalAdd) * (100   finalPct) / 100;

            this.NumericDic[final] = ((this.GetByKey(bas)   this.GetByKey(add)) * (100   this.GetByKey(pct)) / 100   this.GetByKey(finalAdd)) * (100   this.GetByKey(finalPct)) / 100;

            Game.Scene.GetComponent<Eventcomponent>().Run(EventIdType.NumbericChange, this.Entity.Id, numericType, final);

        }

    }

}

3.特点的改动能够一致抛出事情给其它模块订阅,写一个特点改变监督器变得十分简略。例如成果模块需求开发一个成果生命值超越1000,会取得长命大师的成果。那么开发成果模块的人将订阅HP的改变:

    /// 监督hp数值改变

    [NumericWatcher(NumericType.Hp)]

    public class NumericWatcher_Hp : INumericWatcher

    {

  &n注册送彩金官方网站bsp;     public void Run(long id, int value)

        {

            if (value > 1000)

            {

                //取得成果长命大师成果

            }

        }

    }

同理,记载一次金币改变大于10000的反常日志等等都能够这样做。

有了这个数值组件,一个moba技术体系能够说现已完成了一半。

代码地址:https://github.com/egametang/Egametang

 



注册送彩金| 关于我们| 产品资讯| 优惠活动| 业界动态| 技术荣誉| 最新新闻| 行业导向| 给我留言| 联系我们|

Copyright © 2005-2016 http://www.song55.com 注册送彩金版权所有 注册送彩金