zoukankan      html  css  js  c++  java
  • `cocos2dx非完整` 游戏架构缩影 添加启动流程

    这期的话题可能不是很好, 我没有想到很好的词句去更好的表达. 我一直都是很固执的认为, 同一类型的游戏,在开发做的前期工作上面其实都是可以复用的,也就是大同小异的。从游戏启动,启动日志,启动检查,检查更新,到进入游戏.这些都是那一套东西,我想把这些东西抽象一下,概括出一个叫做"流程"的概念.

    我的想法就是流程是顺序执行的, 就像我喜欢画图,先做什么,然后做什么,做完什么做什么.其实从一款app启动到进入游戏,这之间的过程都是流程化进行的.还有一个很经典的例子,新手引导,其实新手引导就是一堆流程集.无论是等级引导还是顺序引导还是任务引导其实都是有顺序的.或者换一个出发点,策划在做游戏的时候,他对游戏玩家在某个时间段出于一个什么样的状态会想的很清楚,因为他就是游戏的制作者.新手引导确实很难处理,谁做过谁知道.

    好吧.既然说到流程这个概念,那么为了实现这个东西,也就需要响应的引入事件调度的概念,这个用lua很容易实现.我就不费力气了,从quick直接把事件机制拿过来,稍微改了一下(请原谅我是个偏执抑郁症患者).预示就诞生了下面这个东西:

     1 --小岩<757011285@qq.com>
     2 --2015-5-27 17:05
     3 local mm = require "fw.oop.measure_mgr"
     4 local m = class("measure")
     5 
     6 function m:ctor(dispatcher, next_m)
     7     self.dispatcher_ = dispatcher
     8     self.next_m_ = next_m
     9 end
    10 
    11 function m:get_name()
    12     return self.__cname
    13 end
    14 
    15 function m:get_next_name()
    16     return self.next_m_
    17 end
    18 
    19 function m:launch()
    20     self.dispatcher_:dispatch({
    21             name   = mm.LAUNCH_M,
    22             launch = self:get_name(),
    23         })
    24 end
    25 
    26 function m:finish()
    27     self.dispatcher_:dispatch({
    28             name   = mm.FINISH_M,
    29             finish = self:get_name(),
    30             forward= self:get_next_name(),
    31         })
    32 end
    33 
    34 function m:remove()
    35     self.dispatcher_:dispatch({
    36             name  = mm.REMOVE_M,
    37             remove = self:get_name(),        
    38         })
    39 end
    40 
    41 function m:onlaunch()
    42 end
    43 
    44 function m:onfinish()
    45 end
    46 
    47 function m:onremove()
    48 end
    49 
    50 return m
     1 --小岩<757011285@qq.com>
     2 --2015-5-27 17:05
     3 local proxy = require "fw.framework.proxy"
     4 local mm = class("measure_mgr")
     5 
     6 mm.LAUNCH_M = "LAUNCH_MEASURE"
     7 mm.FINISH_M = "FINISH_MEASURE"
     8 mm.REMOVE_M = "REMOVE_MEASURE"
     9 mm.TAG      = "MEASUREMGR_TAG"
    10 
    11 function mm:ctor(dispatcher)
    12     self.proxy_ = proxy.new(dispatcher)
    13     self.measures_ = {}
    14     self.proxy_:add_listener(mm.LAUNCH_M, 
    15                     function(e)
    16                         self:onlaunch_m(e) 
    17                     end, mm.TAG)
    18                :add_listener(mm.FINISH_M, 
    19                        function(e)
    20                            self:onfinish_m(e)
    21                        end, mm.TAG)
    22                :add_listener(mm.REMOVE_M, 
    23                        function(e)
    24                            self:onremove_m(e)
    25                        end, mm.TAG)
    26 end
    27 
    28 function mm:register_measure(m)
    29     local m_name = string.upper(m:get_name())
    30     if not self.measures_[m_name] then
    31         self.measures_[m_name] = m
    32     end
    33 end
    34 
    35 function mm:remove_measure_by_name(name)
    36     name = string.upper(tostring(name))
    37     if self.measures_[name] then
    38         self.measures_[name]:onremove()
    39         self.measures_[name] = nil
    40     end
    41 end
    42 
    43 function mm:launch_measure_by_name(name)
    44     name = string.upper(tostring(name))
    45     if self.measures_[name] then
    46         self.measures_[name]:onlaunch()
    47     end
    48 end
    49 
    50 function mm:finish_measure_by_name(name)
    51     name = string.upper(tostring(name))
    52     if self.measures_[name] then
    53         self.measures_[name]:onfinish()
    54     end
    55 end
    56 
    57 function mm:onlaunch_m(e)
    58     self:launch_measure_by_name(e.launch)
    59 end
    60 
    61 function mm:onfinish_m(e)
    62     self:finish_measure_by_name(e.finish)
    63     local next_m = e.forward
    64     if next_m then
    65         self:launch_measure_by_name(next_m)
    66     end
    67 end
    68 
    69 function mm:onremove_m(e)
    70     self:remove_measure_by_name(e.remove)
    71 end
    72 
    73 function mm:destroy()
    74     self.proxy_:remove_all_listeners()
    75     self.measures_ = {}
    76 end
    77 
    78 return mm

    上面也是看到了我给流程封装了finish(), remove(), launch()方法. 为了更彻底的贯彻流程的概念, 我索性也将启动部分的代码做了一点简单的封装.

     1 --小岩<757011285@qq.com>
     2 --2015-5-27 17:27
     3 local ij = require "fw.framework.inject"
     4 local mm = require "fw.oop.measure_mgr"
     5 local app = class("app")
     6 
     7 function app:ctor()
     8     self.dispatcher_ = ij.inject({}):add_component("fw.framework.dispatch")
     9     self.m_mgr_ = mm.new(self.dispatcher_)
    10     self.entrance_m_ = nil
    11 end
    12 
    13 function app:get_dispatcher()
    14     return self.dispatcher_
    15 end
    16 
    17 function app:start()
    18     if not self.entrance_m_ then
    19         error("pls set entrance measure before start()!")
    20     end
    21 
    22     self.entrance_m_:launch()
    23 end
    24 
    25 function app:register_game_measure(m)
    26     if not self.entrance_m_ then
    27         self.entrance_m_ = m
    28     end
    29     self.m_mgr_:register_measure(m)
    30 end
    31 
    32 function app:destroy()
    33     self.m_mgr_:destroy()
    34 end
    35 
    36 function app:exit()
    37     cc.Director:getInstance():endToLua()
    38 end
    39 
    40 return app

    默认会从第一个开始启动进入, 然后依次执行注册的流程.具体的例子我可以给一个.

     1 --小岩<757011285@qq.com>
     2 --2015-5-27 17:39
     3 local clm = require "game.measure.check_log"
     4 local cem = require "game.measure.check_env"
     5 local cum = require "game.measure.check_update"
     6 
     7 local application = class("application", fw.app)
     8 
     9 function application:ctor()
    10     application.super.ctor(self)
    11 end
    12 
    13 function application:run()
    14     self:register_game_measure(clm.new(self:get_dispatcher(), cem.__cname))
    15     self:register_game_measure(cem.new(self:get_dispatcher(), cum.__cname))
    16     self:register_game_measure(cum.new(self:get_dispatcher()))
    17     self:start()
    18 end
    19 
    20 return application

    目前的代码, 我只是写到了增量更新,所以我注册了三条流程.

     -- check_log_measure 启动app运行日志.

     -- check_env_measure 启动检查环境设置 

    --  check_update_measure 启动增量更新.

    下面如果再添加流程应该就是进入游戏的流程了.

    这样做再某些方面显得很呆板, 将一些简单的事情做的有点复杂了. 但是是有一个好处的, 那就是我们的架构设计开始出现模式化的代码了. 模式化很重要, 模式化是统一的前提. 在没有做到模式化之前, 一味的强调各种统一风格的事情就是扯淡,很难做得到.就像以前我遇到过一位主程, 每天就只会强调代码格式, 注释格式的问题, 基础的功能代码并不能提供. 我不知道这么做的意义何在. 这里只是突然想到了, 顺手吐槽一下.

    这里说一句抱歉, 原本计划这一篇写增量更新的. 现在看来要延后了, 这里绝对不是因为技术问题. 我昨天就写好了, 今早起床也是将android包打出来测试通过了.是因为直接跳到更新那边忽略了中间太多的东西了,我想穿插一些文章来说明一下这些问题. 懂的人不需要多说,对于那些渴望学习的人, 我啰嗦一点就罗嗦一点了, 但是能解答他们的问题或者是有一点启示, 就是最好的事情了.

  • 相关阅读:
    ScrollView卷轴视图
    SharedPreferences数据存储
    progressBar进度条
    SeekBar拖动条
    TabWidget选择标签
    RadioGroupRadioButton
    SQLite数据操作
    Spinner
    .NET学习资源
    如何在局域网内其他机器访问我的asp.net网站?
  • 原文地址:https://www.cnblogs.com/respawn/p/4538245.html
Copyright © 2011-2022 走看看