zoukankan      html  css  js  c++  java
  • 【独立游戏制作人】领先业界3年的游戏开发技术——业务逻辑持久化

    概述:

    本文介绍一种“逻辑持久化技术”。目的是进一步提升代码复用程度。主要应用场景在游戏中,例如人物角色升级、事物队列冷却等。

     

     

    前言:

    开发游戏中,经常看到一些业务逻辑相似,但是又无法复用的代码。例如升级。

     

    英雄:每100点经验升级1级。

    骑宠:每100点经验升级1星,每12星升级一级。

     

    如果用传统的设计思路,会得到以下代码片段:

     

    USR_HERO
    {
      public int exp;
      public int level;
    }
    UsrHeroDao
    {
      public boolean upgrade( USR_HERO hero, int exp)
      {
        hero.exp += exp;
        if (hero.exp >= MAX_EXP)
        {
          hero.exp = MAX_EXP - hero.exp;
          hero.level += 1;
        }
      }
    }

     

    如果是宠物,就写一套宠物的升级代码。这种代码开发多了,就开始觉得烦,但是不认真看又会出Bug。我们程序员尼玛怎么能每天都重复的干着这些无聊的事情??

     

    于是我开始冥思苦想,如果这些能力是模块,一个对象安装了这个模块,就具备了升级的能力,那我就不用开发了啊。多爽??不断的冥思苦想,曾经还半夜在家里的大厅摸黑转来转去,大脑不断构造着各种架构,又不断的被推翻。

     

    终于,有一天, 我走在回家的路上的时候,给我想到了!!!

    PS: 各位看解决方案的时候,也可以稍微1分钟思考下上面的问题)

     

    核心思路:

    首先要分析为什么代码不能复用。因为升级的经验值是值类型对象!这个就是一切的根源本质。可以想象下,如果把对象的经验、等级放入方法内运算,实际上对象的值是没有受到影响的,因为按值传递被拷贝了一份。

     

    所以???把值类型转成对象类型,突然间一切都柳暗花明了。例如:

     

    OrmInt
    {
      public int value;
    }
    USR_HERO
    {
      public OrmInt exp;
      public OrmInt level;
    }

     

    看到这里,大家是否突然间明白了?突然间觉得高端大气上档次了?尼玛这可是我奋战几天的结果。我相信我不说,业界起码3年内不会有人往这个方向思考(臭美一下,各位大侠手下留情,千万别喷我。。。。。)

     

    现在我把升级的方法修改一下:

     

    UsrHeroDao
    {
      public boolean upgrade(OrmInt exp, OrmInt level, int exp)
      {
        exp.value += exp;
        If(exp.value >= MAX_EXP)
        {
          exp.value = MAX_EXP - exp;
          level.value += 1; 
        }
      }
    }

     

    怎样?是不是觉得爽了很多。

    案例:

    为了进一步说明这个“逻辑持久化”如何的高端,我举个我实际使用的例子, 使用了简化代码:

     

    // 为OrmInt增加一个可升级的方法,返回升级对象。
    OrmInt
    {
      public OrmUpgradable ugprade(OrmInt upgradeValue, OrmUpgradeLimit upgradeLimited)
      {
        OrmUpgradable value = new OrmUpgradable(this, value, ugpradeLimited);
      }
    }
    
    // 升级对象,支持链式编程,实现升级触发下一升级的效果
    OrmUpgradable
    {
      private OrmInt value; // 被升级的对象
      private OrmInt upgradeValue; // 当前升级的值
      private OrmUpgradeLimit upgradeLImited; // 升级的上限对象
      private OrmUpgradable head; // 链式升级的头
      private OrmUpgrade child; // 链式升级的尾
      
      // 触发下一个升级
      public OrmUpgradable upgrade(OrmInt value, OrmInt upgradeValue, OrmUpgradeLimit upgradeLimited)
      {
        OrmUpgradable orm = new OrmUpgradable(value, upgradeValue, upgradeLimited);
        orm.head = this.head;
        this.child = orm;
        return orm;
      }
      
      // 开始升级
      public boolean doWhile()
      {
        // 不断循环升级
        if(this.value.greatThan(0))
        {
          // 当前的升级上限
          int upgradeLimited = this.upgradeLimited.getUpgradeLimit();
          // 计算可升级的值的部分 并升级
          int incValue = min(upgradeLimited.substract(this.value), upgradeValue);
          this.value.increase(incValue);
      
          //判断是否升级
          if(this.value.greatEqualThan(upgradeLimit))
          {
            // 链式触发后续的升级
            if(!this.child.doWhile())
              return true;
          }
      
          // 更新剩余可升级部分
          upgradeValue.update(upgradeValue.substract(incValue));
          this.value.update(0);
        }
      
      return true;
      
      }
    }

     

     

    使用方法:

    p.value.upgrade(11, 10)

    .upgrade(p.value2, 1, 10)

    .upgrade(p.value3, 1, 10)

    .doWhile()

     

    这段代码用起来简单,但是原理有点复杂。

    • 首先这是个链式升级。当exp值增加到达了最大值,则触发下个对象level进行增加,一直触发到最后。然后一个循环。
    • 其次,exp不断升级,直到可升级的值用完了。感觉就像一个储水池。
    • 最后,升级上限我用了一个对象OrmUpgradeLimit,原因是实际项目中,当用户的等级不同的时候,当前等级经验值上限是不一样的。所以OrmUpgradeLimit实际上内部包含了level这个对象。而由于level类型对象,因此在升级过程中,升级上限是动态变化的。

     

    小结:

    本文抛砖引玉,介绍了一种非常强大的“业务逻辑持久化”技术。本质就是值类型转对象类型;对象类型除了包含数据外,并带上处理方法。

    这样,这个对象复制给了OrmOrm就具备了对应的能力。所以我命名为“业务逻辑持久化”,因为我把逻辑放在了持久层。

     

    扩展阅读: 

    实际上现在的业务逻辑操作,都是围绕着数据。

    逻辑更确切的说,就是围绕相互有关联的数据字段进行逻辑操作。 思维发散下,就明白。这个已经不是对某个对象进行操作了。

    英雄有经验等级、坐骑也有经验等级,但是升级这个操作实际上是针对经验和等级这2个数据建立关系,而不是英雄和坐骑。

    这个技术国外叫做:functional reactive programming
    Hudak, Paul (September 1989). "Conception, evolution, and application of functional programming languages" (PDF). ACM Computing Surveys 21 (3): 359–411. doi:10.1145/72551.72554.

     

    下期预告:

    领先业界3年的游戏开发技术——顶级数据库持久层的设计。

    目前最流行的数据库持久层是什么?Hibernate?ADO.NET?不,Hibernate从出生开始,我就觉得他实在太落后了。欢迎关注6月份的主题——顶级数据库持久层设计。

    关于我们:

    我们来自Pixysoft独立游戏制作人。我们的目标是培养早就游戏行业的独立制作人,提供一切相关的技术文档资料,从前端到后端、策划、数值、美术全方位进行培养。

    欢迎加入我们的群:95755843

    本群每月1~10日为开放日,不限条件加入。11~30日为闭关日,除了成员邀请外,不对外开放,进行封闭培训。

    本群关注的是思想的交流,其次借助开源平台共享资源。

    欢迎游戏爱好者加入。

  • 相关阅读:
    android 模拟器手机如何添加文件到sd卡?
    Asp.Net 前台和后台交互的一些问题
    Cannot get WiFi AP state 错误
    MediaPlayer.getCurrentPosition IllegalStateException错误
    SQL Compare 错误 给定关键字不在字典中
    java.net.SocketException: Connection timed out的一种情况
    System services not available to Activities before onCreate()
    java.net.SocketException: Connection reset by peer
    卸载Microsoft Virtual WiFi Miniport Adapter 方法
    java 跳出 if
  • 原文地址:https://www.cnblogs.com/zc22/p/3707009.html
Copyright © 2011-2022 走看看