共计 27500 个字符,预计需要花费 69 分钟才能阅读完成。
开篇注:这是我首次参与创业失败后的全面总结,三年高强度磨练下来,相比学生时代整体认知提高了很多,算是失败带来的收获吧。
目录
→我的 FLASH WEB GAME 开发历程
→当今 FLASH WEB GAME 概述
→创业型游戏公司面临的问题和困难
→FLASH WEB GAME 的系统架构
→FLASH WEB GAME 的前端架构与人事分工
→前端与美术的配合
→前端与后端的配合
→公司文化与产品定位
→2010 年:我的梦想扬帆起航
我的 FLASH WEB GAME 开发历程
2007 年的夏天,顶着炎炎烈日,我从学校直接跑到上海,开始了我的 FLASH WEB GAME 创业之旅。时至今日,转眼快三年了。作为国内最早的一批 FLASH WEB GAME 开发人员,今天我粗略的总结一下这三年左右的经验和心得。讲的不对的地方,请大家多多指教。
2007 年刚到上海的时候,初创团队只有四个人,一个 CTO, 一个美术,一个后端,一个前端。手里的产品是一个已经在台湾运行三年左右的 FLASH 社区,和国内的“梦境家园”非常像。这个产品还是不错的,早在 FLASH5 就在开发出来了,FLASH6 出来后,又用新版本的 AS1 重写过。这个产品让我又爱又恨,爱的是,在 2007 年的时候,国内除了“梦境家园”和“1D 社区”真的很少有能赶上它的;恨的是,这个产品竟然没有前端源码!要想修改还要破解!玩过 AS1,在时间轴、MC 和 BTN 上写过代码的朋友应该知道这是什么概念——1 个字:囧!
后来老板可能也觉得这样改下去不是办法,终于同意自己重写一个。正好 07 年有条新闻很火爆:国外有个 FLASH 社区第一次利用 FLASH 技术取得了重大成功,以 7 亿美金卖给迪斯尼,它就是“企鹅俱乐部”。老板看到了商机,我们决定做一个中国版的企鹅,于是“海底世界”应运而生了。而“海底世界”的创意,只不过是我们四个初创成员在闲聊时,我开玩笑随便说的。
海底世界正式开发到现在两年多,期间我们碰到无数的问题和困难,不管是公司层面或技术层面,都是如此,但始终是坚持了下来。产品一天天完善,公司规模也一天天扩大。前端从最开始的两个人,到现在 5 个人;后端从最开始的 FMS+PHP 到现在自己写的 Socket 服务器;公司规模也从最开始的 4 个人,到现在的 50 多个人。
当今 FLASH WEB GAME 概述
2007:含苞欲放!
2007 年可以说是 FLASH WEB GAME 发展史上的分水岭。2007 年之前,我们眼里只有“梦境”,最多再加上昙花一现的“抱抱城”,那时候根本没有“FLASH WEB GAME”这个概念,大家谈的都是“FLASH 社区”,“FLASH 社区”这个词在很长一段时间代表着 FLASH 应用领域的至高点。也许 2007 年已经有不少团队开始研发 FLASH 的 MMORPG 了,我曾经有幸知道几个,但很可惜,不少都胎死腹中,2007 年国内在线上运营的 FLASH WEB GAME 基本上还是空白。但不管怎么说,我相信 2007 年是蓄势待发的一年,肯定有很多类似我们公司的团队,在默默的努力着。
2008 年:雨后春笋!
经过 2007 年的积累和准备,FLASH WEB GAME 业界的战斗终于在 2008 年打响,以“摩尔庄园”,“海底世界”为代表的“FLASH 儿童虚拟社区”开始崭露头角;以“纵横天下”为代表的 FLASH 策略类游戏兴起;以“昆仑”为代表的 FLASH MMORPG 让“无端网游”的概念又炒了起来。还有各种基于 FLASH 的卡牌对战类,联机棋牌类,模拟经营类游戏等等,都如雨后春笋般破土而出。
2009 年:百花齐放!
2008 年,国内虽然一下出了很多 FLASH WEB GAME, 但大家只要认真收集,总归还是能数的过来,可到了 2009 年,几乎每隔一个月,都会有几个新的 FLASH WEB GAME 进入大家视野,而且他们越来越完善,功能越来越强大,盈利模式也开始成熟并多样化。2007 年每出一个 FLASH WEB GAME,我都会为之兴奋,并很有兴趣的去研究它。而到了 2009 年末的时候,FLASH WEB GAME 已经多到我连体验的兴趣都没了,我已经彻底搞不清楚国内到底有多少个 FLASH WEB GAME 在运营。而伴随着 SNS 行业的成熟,基于 SNS 的 Social Game 进一步扩大和模糊着 FLASH WEB GAME 的概念。FLASH 在游戏领域里的应用,在经历了“社区”、“策略类”、“MMORPG”后,发展到今天创意无限,精彩纷呈的“Social Game”,已经很难用一个词,根据游戏类型概括所有的 FLASH 应用了。所以我觉得“FLASH WEB GAME”,也就是“FLASH 网页游戏”这个词还是相对最恰当的,这也是我前面一直使用这个词的原因。
2010 年 – 2011 年:胜者为王!
就像春秋战国时期,在经历过“百家争鸣”后,必然是“天下一统”。随着游戏巨头和互联网大亨对网页游戏的逐渐重视,以及政府的介入,还有最早领跑某些领域的创业公司不断壮大,相信在不久的将来,网页游戏领域也会出现几个真正的领袖。别的领域不敢说,在我们儿童市场这块儿,淘米公司已经逐渐呈现一家独大的趋势,不信的话,你可以随便找几个小学生问问,比如你父母辈亲戚朋友的孩子,问他们是否知道摩尔庄园和赛尔号,是否充值了,相信你会得到非常惊讶的答案。所以,2010 年后,任何小作坊型的创业团队再想进入 FLASH WEB GAME 行业,都需要更加谨慎了!
创业型游戏公司面临的问题和困难
在正式进入 FLASH WEB GAME 的技术探讨前,我左思右想,还是觉得必须先说一下创业公司存在的问题和困难,为后面可能不太“正规”的做法找一个合适的“理由”。——人不能太爱找客观理由,但也绝对不能为了避免“找理由”之嫌,而弃客观现实于不顾,“实事求是”才是王道。
任何有过创业经验的技术团队和公司应该都知道,教科书那套从成功公司抽象出来的模式在创业初期几乎只能是神话一般的存在,相信没有几个公司能完全做到。当然那种千万级启动资金,有成功背景的新公司除外。像我们公司,一开始就 4 个人,前端和后端各一个人,如果我们两个都每天用一半时间考虑架构和写文档,我们的产品猴年马月也上不了线,况且我们写了给谁看呢?在这个阶段最最重要的目标就是尽快把产品做出来,上线运营出一定效果,给产品更加明确的方向,给团队信心,然后尽最大努力去融资,以求下一阶段的发展。
我觉得一个创业公司最现实的发展观应该是这样的:
初创阶段(技术导向型阶段):这个阶段要一切以“我们能做什么”为基础,在财力、人力、经验都不足的情况下,找出我们的优势,“把我们所擅长的做到最好”是我们唯一的筹码,毕竟初创人员能走到一起,必然是有一定共识,在某方面有优势的。
而“我们能做什么”,在初创阶段很大程度上就是指技术能做什么。没钱、没人还想把项目做的又快又好,绝对是痴心妄想。
这个阶段就开始叫嚣“市场主导产品”,“不看过程只看结果”等口号,完全是不务实的态度,市场上最热门的产品你未必能开发出来。创业阶段,结果还没出来,前途未卜,你不看过程看什么?
发展阶段(人力导向型阶段):假设我们顺利度过了第一阶段,公司开始有现金流或者找到了天使投资,我们就开始布置进一步的发展了,这个阶段招人将是公司的一个要务,招有创业精神的人,更要招我们需要和缺少的人。
以前我们公司只有 AS,于是游戏 Server 只能用基于 AS 的 FMS,现在应该招一个 C ++ Socket 的人了;以前公司没有网页前端,网站都是原画和 PHP 代劳的,现在该弥补了;以前整个游戏都是架构师们设计并实现的,现在应该招一两个做模块打下手的人了。
这个阶段虽然不适合大规模扩展人手,但在要害人力点上,也绝对不能抠门,我们公司就是吃亏在 Socket 上,公司一直不肯招一个专业写 Server 端的,一直让前端和 PHP 代劳,结果游戏同时在线人数一超过 5000 就会出各种离奇问题,最恐怖是大家都不清楚问题到底在哪里,只能大眼瞪小眼,这时候老板就会臭骂公司这帮技术都是饭桶,这么多人还搞不定服务器问题。
老板不懂技术,说出这样的话无可厚非,但老板不听劝,死活不愿意招 Server Socket 要害人员,这就是他的错了。
总之这个阶段要以人力发展为核心,尽最大的努力把必要的人手配备齐。
必须注意的是,这个阶段不适合空降部门领导,公司发展阶段,只有初创人员陪公司一路走来,最明白公司的问题,以及各种问题的根源。而空降的领导容易只看到问题,不明白为什么会有问题,有时候难免说出“道理上很正确,但实际上不可行”的话,而老板为了配合新领导树立威信,很多时候不得不偏向新领导,这样以来很容易打击到初创人员的积极性。更严重的是可能让初创人员看不到前途,创业的激情沦为打工的无味。
这个阶段挖墙脚空降领导,希望他们能把公司制度正规化,希望他们拯救公司的做法可能适得其反!公司初创人员这时候应该依旧是公司的顶梁柱!
成熟阶段(产品导向型阶段):如果有幸过了前两个阶段,到了这个阶段的时候,公司应该已经实现了正向盈利,作为一个游戏公司,一旦靠自己实现盈利,相信各种投资机构肯定会主动找上门,千万美元的投资绝对不夸张。人力、财力、物力都不再是问题,产品研发和运营的经验也成熟了,这时候唯一要关注的就是市场,什么样的产品更被市场和用户接受,争取开发出更多更好的产品。产品要多样化,公司要规模化,要形成自己的产品链和平台,抓住更多的用户,开拓更多的盈利模式。这时候才是产品主导公司,才是从大公司挖人的时代。如果这些都做到了,当老板再次开会谈“上市”的问题时,每个人脸上将会笑容依旧,只不过初创阶段的笑容是那种开玩笑试的玩世不恭,而现在则是对未来的美好憧憬。
其实任何理论都是有前提的,牛顿定律也只是在低于光速的情况下才适用。
公司发展的历程中,老板和员工肯定都会有其信仰和观念,都会用各种言辞来说服别人。但我相信没有那种理论和言辞是永远正确的,尤其是书上和大公司的那些所谓的成功经验更是要警惕,因为它们身上有太多的光环,一场本来可能很有价值的讨论,说不定就会被一句“盛大就是这么做的”给结束掉!所以在我们谈任何理论的时候,不妨看看公司现在所处的阶段,实事求是的看待自己。
我们公司就曾屡次吃类似的亏,公司在第一阶段刚拿到天使投资,就想做第三阶段的事了,结果做了很多,一件也没做好,白白浪费了很多时间和大好机遇。其实当时老板用来说服人的理论也都是正确的,只不过不适合公司的实际发展情况而已。
还有一点要强调的是,不管公司现在处于第几阶段,坚决不能全盘否定其它阶段的付出和努力以及很多不得不犯的“错误”。之所以强调这一点,也是我们公司曾踩过的雷区,当我们发展到第二阶段的时候,公司就开始忙着空降领导,然后这些领导对我们之前的做法开始逐一否定,把做后端的哥们儿说的一无是处,搞得团队气氛极不融洽,吵架红脸的情况经常发生,激化了团队矛盾,打击了团队士气,加速了公司走向死亡!
FLASH WEB GAME 的系统架构
我在这里把一款 FLASH WEB GAME 的架构分为三部分:
1. 系统架构
2. 前端架构
3. 后端架构
“系统架构”主要是指根据一款游戏的特点以及公司的实际情况选择合适的技术实现方案,主要包括美术方案,前端方案和后端方案;
“前端架构”主要指 FLASH 前端的主程序以及模块划分;
“后端架构”主要指即时通讯部分和数据库。
这章先谈系统架构。
谈到架构,我不得不说,那些所谓的完美架构,能够一次架构好,永远不用改的说法只能是传说,或者技术人员忽悠老板的说法,对于创业公司更是如此。
创业公司初创时期更多的时候需要在游泳中学会游泳,因为大家都没有经验,失败是最好的教科书。就算大家知道应该怎么做,很多时候条件也不允许。比如我们在一开始就知道应该自己写 Socket 服务器,可就是没 Socket 的人才,于是不得不先使用 FMS+PHP。公司一开始的美术更精通 FLASH 一些,而且我们计划的是要做“企鹅”,于是我们选用矢量图。
可后来随着公司产品定位的不断改变,我们的架构和解决方案也会不断调整,当达到一个临界点时,修改的代价已经超过重新开发,我们就不得不对架构进行“重构”了!这时候聪明的老板应该支持程序员的意见,充分调动他们的积极性尽快改完,全公司应全力配合,尽快度过难关。而不明事理的老板肯定会每天抱怨程序员无能,搭出一个垃圾架构不能满足产品的持续快速发展,拖了产品和市场的后腿,给程序员造成很大的压力,积极性没了不说,在长期经验积累之后本来可能是一次非常好的机会能做出一个相对完美的架构,满足日后很长一段时间的需求变更,结果因为老板过分催促和施压,又烙下了许多隐患,而这些欠下的债,总有一天要还的,这一天来临之时,责任虽然可以完全由程序员承担,但整个公司都要为之付出代价!
所以关键时刻程序员该坚持还是要坚持自己的观点,要尽量说服老板,程序员的社交能力在这个时候就凸显作用了,你要明白你不但是在对自己负责,也是对公司负责!另外,真的很希望天下的老板们都能明白一个道理:能够根据公司实际情况不断调整的程序员才是最可爱最辛苦的程序员,而不是那些什么都不管,上去就提一大堆要求,必须都满足他,他才愿意做的程序员。
就算时至今日,FLASH WEB GAME 在国内发展差不多三年了,但我敢说 FLASH WEB GAME 还是没有什么行业标准的技术解决方案,尤其是前端,大家都是自成一派。在这个时候,让我们再次搬出那句老话:不管黑猫白猫,抓住老鼠的就是好猫。不过经过这几年的摸索,还是有一些规律可循的:
1,美术
如果游戏画面简单,色彩构成相对单一,场景内总体元件能控制在 100 个以下,则非常适合直接使用矢量图,画面各组成部分尽量拆分为能重用的独立元件。这样虽然牺牲了客户端的 CPU,但能因为“重用最大化”而大大减少美术的工作量,也方便他们日后应对需求变更,比如某些元件的尺寸变动。在画面简单,元件又少的情况下,利用递归全元件位图缓存,拿少量内存还能换回大量 CPU,找出这个平衡点,完全可以做出很好的用户体验。
可大部分时间,我们的游戏场景可能都非常炫,画面复杂,色彩鲜艳。使用矢量图的话,一方面不容易画出想要的效果和精细度,这时候使用矢量图反而增加了美术的工作量和难度;另一方面,使用矢量图还有可能导致客户端 CPU 严重飙升,超出普通客户端电脑的承受范围。这时候我们应当用位图做游戏背景,重用性不大的元件要尽量合并到背景位图里,减少位图总个数,一些简单的动画如果非要用 FLASH 做成矢量动画的话,也要尽量做成逐帧的,相信 FLASH IDE 玩的转的美术同志们应该知道怎么把一个渐变动画瞬间转换成逐帧动画。逐帧动画虽然会导致 SWF 文件体积增大,但相对于换回来的客户端 CPU 来说还是值得,这其实是牺牲了一些服务器带宽和用户等待时间,换回严重的客户端 CPU 超载。而如果你的动画非常复杂和精细,精细到只有 AE 等粒子特效软件才能表达的话,建议还是直接从 AE 里导出位图序列,在 FLASH 里弄成逐帧动画,太过复杂的动画绝对不能用 FLASH 直接做,不但很难做出想要的效果,而且复杂矢量图的 SWF 文件体积也会大大超过位图,有可能导致用户因为 SWF 文件加载时间过长,失去等待的耐心,这时候我们情愿牺牲美术的工作量和工作流程,换回想要的效果,减小 SWF 文件体积。还有一点要提醒的,时间轴动画不可见时,程序一定要记得将其 Stop 掉,不像程序动画,时间轴动画不可见时,FLASH 虚拟机内部其实依旧在重绘,对 CPU 还是有影响的。
还有一种极端情况是场景元件超标,比如整个游戏内所有元素(包括各种 MC、BTN、位图以及程序创建的 DisplayObject,总量超过 500,这时候你会发现,画面静止还好,但只要游戏上鼠标随便一晃,或者有几个人物随便走一下路,CPU 都会狂飙,就算这 500 个元件都是位图也无济于事。其实这是 FLASH 的一个瓶颈所在,是目前所有 FLASH 大型项目都有可能碰到的问题,也是我觉得阻碍 FLASH 进一步发展的主要障碍之一。在一个元件超多的背景图上进行任何的鼠标动作、动画、文本渲染,都会导致 CPU 严重飙升,甚至画面很卡。
要解决这个问题,本质的也是唯一的方案就是减少元件数量,要想尽一切办法降到 200 以下。而这需要美术、前端和策划通力合作才行,绝对不是前端程序员就能搞定的事。策划要从产品的角度上看能不能简化目前场景同一时间出现的元素,美术要把能合并成一张图的元件在绘图软件中合并成一张位图,前端 AS 程序要把不需要响应鼠标事件的元件的 MouseEnable 和 MouseChildren 都设置成 false,一些能利用 CopyPixels 合并的位图就合并成一张,比如可以平铺创建的房间地板和墙面,要 CopyPixels 成一张图,而不是 new 出好几百个元件。
其实元件超标的情况是大多数没有经验的团队很容易发生的问题,这时候前端程序员要起到领头羊的作用,给大家讲明白道理,用事实让大家信服,组织大家一起把事情做的更好,而不是一味的在那里抱怨 FLASH 虚拟机效率低。因为这时候你是团队唯一可以依靠的人,如果这个问题解决不了,虽然大家都有责任,但前端毫无疑问是罪魁祸首!
极端情况下的极端解决方案:如果游戏策划的非常酷,一个子弹爆炸效果就需要几十个元件支撑,画面上同时又需要几十个坦克混战,这时候常规的解决方案是根本达不到的,但不是说就一定无法做了,可以利用强大的 BitmapData 类把每帧要显示的游戏画面完全计算好并且在内存中绘制,然后以一张图的方式渲染给用户,这时候用户玩你的游戏仿佛就像在看逐帧的动画,此时 FLASH 占用的 CPU 大部分都是计算耗用的,而不是渲染耗用的。其实 AS 的执行效率远远高于屏幕渲染,你把 CPU 的主要负荷转移给 AS,反而能做更多更炫的事情。
据我的初步研究,前段时间名噪一时的 FLASH 版 3D 雷神,还有现在很多国外效率高的“有点假”的 TD 类和飞机类单机游戏都是这么做的。可这种模式适合用来做多人联机并且有大量交互界面的 FLASH WEB GAME 么?我初步思考了一下,感觉是不可能的。
首先,大量的交互界面意味着需要用鼠标点击,试想在一个逐帧动画中,每帧都要响应鼠标是什么概念?所以 UI 部分首先排除了;
然后,大量的即时数据交互,每当一个异步的请求得到响应,画面就需要做出相应的改变,这将对本来还可能比较工整的内部绘制算法制造非常大的麻烦,难度太高!基本上也不可行;
最后,很多 FLASH WEB GAME 的画面重用性并不是很高,比如像我们游戏的每个场景都是美术专门画的,而不是用地图编辑器编辑的,这就意味着你无法完全用程序拼出一个场景来;
综上,我觉得一个款多人联网的大型 FLASH WEB GAME 基本不可能完全使用 CopyPixels 完成,最多是部分实现,比如我上面说的墙面和地板。除非你的游戏策划很 NB,知道什么游戏能最大限度的利用 CopyPixels,而这样的策划估计本身肯定也是个前端程序员。
2,前端
从系统架构的角度上讲,前端其实很简单。现在 WEB GAME 主流的前端技术无非就是 AS 和 JS。JS 的前端地位其实比 AS 要老,很多人的 JS 经过这么长时间的磨练,功力深厚,做一个策略类甚至简单的 MMORPG 都没问题。但现在用 AS 来做的更简单,更容易做出更酷的效果和更好的用户体验。所以最近两三年,随着基于面向对象的 AS3 编程语言逐渐完善和普及,FLASH WEB GAME 逐渐成了唯一的主流。
其实除了 AS 和 JS 外,还有很多前端技术可以供我们选择,比如 ShockWave,Java,还有那传说中的 Flash Killer:SilverLight 和 Html5 等等。每种技术都有其优劣势,比如 ShockWave 在图形渲染方面比 Flash 强了千百倍,因为它可以完全调用显卡,我在网页上玩过一个基于 ShockWave 的 CS,流畅度和操作感完全不亚于桌面版的 CS,还有国外的“哈宝”以及国内的“娜娜米米”都是基于 ShockWave 的。而 Java 和 SilverLight 也都有强大的背景,HTML5 最近也是来势汹汹。但不管怎么样,2010 年,FLASH 仍以其广泛的覆盖率、酷炫的效果和逐渐成熟的开发社区,以最高的综合评分独领 WEB GAME 业界风骚。所以任何公司和团队,如果现在想做 WEB GAME 的话,FLASH 还是最好的技术选型。
3,后端
后端不是我的强项,我就不多说了,我只根据我们公司的经验谈谈心得。
我同意前后端编程有很大区别,但绝不同意前后端谁简单谁复杂之说。根据我这几年的观察,我发现,前端偏重的是效果,是用户体验和细节处理,有时候可能还要涉及一些图形算法;
而后端则偏重数据结构和数据处理,讲究的是性能、安全和扩展性。前端工作量一般比后端大,而后端需要的工作经验比前端多,想依靠一个只掌握了理论知识的大学毕业生就支撑一个公司的后端架构是严重不靠谱的!
前端架构师必须是一个编程高手,十几、几十万行代码要在他的手里安排的井然有序,后端架构师则必须有过大型项目经验,并且项目同时在线人数达到过一定规模。
前端架构出现问题,会严重拖垮开发周期,而后端架构一旦出现问题,对公司将是致命性打击。所以在公司里宣传所谓前端重要还是后端重要的说法,是完全错误的,任何一款好的产品,必将是策划、美术、前端、后端都达标的产品,缺失任何一块儿,都成功不了!
不同部门之间的比较和较真儿没有任何正面影响!
至于后端的技术解决方案,如果是需要大量即时交互,并且对即时性要求很高的游戏,就必须使用 Socket 服务器。而如果对即时性要求不高,完全可以用 PHP,部分的即时交互可以用 Socket 实现或者 HTTP 轮询也可以。如果你的公司也像我们一样刚开始没有合适的 Socket 程序员,只有比较厉害的前端,那选择 FMS 和 SFS 也未尝不可,这样至少可以让前端人员代劳,让项目可以启动。切记这只是为解燃眉之急的下下策,长久不了,公司要想办法尽快找到一个合适的人,在合适的时机重构。
FLASH WEB GAME 的前端架构与人事分工
前端的主程序架构和模块划分与人事分工是紧密联系在一起的,而这些很大程度上又是由项目本身决定的。纵观现在国内绝大多数 FLASH WEB GAME 的规模和难度,我觉得前端 AS 人员大概需要 2 - 7 个之间,主程序有效代码一般 10W 行左右。在这种情况下,人事分工应当以功能和模块进行划分,尽量避免多人维护同一份代码,每个人各司其职,减少维护和协作的成本。这种模式非常适合人手不够,制度不健全,而且追求效率的初创公司。
根据各种游戏类型的不同,分工也应该不同。策略类更注重界面开发,分工上应该向 UI 偏重;MMORPG 类注重主架构一些;而像我们的儿童虚拟社区,是更新驱动类游戏,每周都要发布新内容,还需要大量的小游戏和场景功能支撑,所以需要更多的模块和小游戏程序员。
下面就以我们公司为例详细谈一下。
我们公司最多的时候,一共 5 个 AS 程序员,分工是这样的:1 个主架构,1 个主 UI,1 个小游戏,2 个场景和模块程序员。
主架构同时负责 FMS 的 Sever 端;
主 UI 同时负责前端人员管理和项目管理;
小游戏人员以平均每月两个单机或者联机游戏的速度循环不停开发,是相对最独立的一部分;
而两个模块程序员,负责每周发布的新场景和新模块功能,他们的工作量其实蛮大的。
先谈 前端主架构,前端程序主架构有两个主要任务:
1,要从架构高度合理划分前端各模块,提出可行的实现方案;
2,从 AS 级别搭建程序架构(非文档级别),制定前端编程规则和接口,规范程序各部分的职责划分。
这两个任务其实包括很多具体工作,比如:游戏启动流程制定,确定哪些 SWF 文件需要外部加载,那些功能可以从主程序剥离出去单独实现,前端配置文件怎么处理,公共素材怎么处理,MVC 三层怎么划分,主程序框架的选定,主程序怎么和后台通讯,主程序如何与模块协作,哪些代码应该放在主程序中,哪些代码应该放在模块里,主程序如何既能提供模块所需要的一切接口和数据,同时又相对模块自我保护等等等等。
其实我谈的还只是一些大的方面,具体到实现的级别,还有大量细节工作要做。而这些工作在项目启动之初都是非常重要的,直接影响到项目中后期的开发和维护效率。
上面提到的那些点,我不可能全讲一遍,不然直接就可以写本书了!我只挑两个比较核心的内容跟大家略做探讨,就是前端 AS 框架和模块划分的问题。
先谈前端框架:现在市面上流行很多前端框架,不管是针对“FLASH”的,“FLEX”的还是“通用的”都有。我们是否一定需要框架,或者必须使用某个框架,这完全是见仁见智的事,从最终的结果上讲,争论这个问题意义不大,我相信一个 5W 行左右的项目,任何有 5 年以上编程经验的人,不管用什么作战策略,最终都能攻下山头,把项目做出来。但有一点至关重要:你必须能完全把握你的架构和你使用的框架,并能跟你的前端同事解释清楚。
那好坏架构的区别在哪里呢?
1,好的架构在开发过程中会更轻松,你不用天天担心的你代码,不用每天不停的写文档,以防止自己忘了复杂的逻辑,你可以在任何时间开始写代码,在任何时间去玩会儿游戏然后回来接着写;
2,好的架构更符合业界标准,更容易被传统和正统的程序员接受理解;
3,好的架构你可以用很简单的几句话就把架构思想描述清楚,用几个很简单的文档就能让别人接手你的代码,在人事变动和工作交接的时候让自己更轻松;
4,当你掌握了一种通用框架或者自己总结一套成熟的架构后,你几乎可以套用以后的大部分项目,并不断完善它,开发越来越轻松,速度却越来越快!
我们的项目,主程序使用的是 PureMVC 框架,而主 UI 部分是自己写的。主程序和主 UI 相互独立,可以单独编译测试。主程序是纯代码,用 FLEX SDK 编译,而主 UI 则是界面和 AS 混写并用 FLASH 编译。这样就把 MVC 中的 V 从物理层面上完全独立了。
PureMVC 框架正如其名字,是一款“纯粹”的 MVC 框架,在我看来,他只是帮我们实现了 MVC 的编程思想和套路,其它多余的功能一点没有,这使它具有更高的通用性,也是它最可爱的地方。根据我们的经验,PureMVC 单核心版就已经完全可以应对主程序有效代码在 10W 行以下的项目了。
但在我跟很多没有用过框架的前端朋友聊天中,发现他们对这些框架本身就有抵触心理,或者有些对 MVC 模式都理解的不深刻,用起 MVC 框架又怎能得心应手?还有一些更过分的朋友把自己的问题也归结到框架上,说什么用了 PureMVC 框架后,自己的项目编译一下要十几分钟,我听了之后哭笑不得,项目编译慢一般是因为没有合理划分模块主程序过大才导致的,跟框架有什么关系?如果因为大家的种种误解和这些人的言论而导致一些新人错过学习这么一款优秀的框架,我觉得实为憾事!
PureMVC 既然是一种 MVC 框架,这就意味着你首先要熟悉 MVC。这种熟悉绝对不是对 MVC 的直译:模型、视图、控制器,而是要真正理解为什么要把程序划分成这几部分,在划分主程序模块时,要时刻能站在 MVC 的角度考虑问题,而当面对一段实际的代码时,能快速准确的判断,这段代码应该放在 MVC 中的哪部分。《pureMVC 最佳实践》这份短短几十页的文档中,可以说处处闪烁着 MVC 的思想火花,不但清楚地阐述了怎么使用框架,而且时刻从 MVC 的角度告诉我们应该把哪些逻辑放在哪些部分中,应该注意什么问题。这个文档早已经有中文版,有兴趣的朋友可以自己去看看,文中有的,我这里就不赘述了。我只结合自己的体验谈一些文中可能没有涉及的,也是在真正开发中才会碰到的问题。
1,模型部分在实际开发中除了存储数据,还有其他作用么?
是的,其实它的实际职责非常多。它要给 Command 和 Mediator 提供接口,响应用户操作,进行数据操作或者请求远程数据服务,进行数据的序列化和反序列化,得到异步数据后可能还要检查数据合法化。
但不管怎么样,它始终是在和数据打交道,同时也应该是你的主程序中唯一可以直接和数据打交道的管道,别的部分要想和数据有接触,首先要问问它同意不同意。
模型处理完数据会以 Notification 的消息方式通知 Command 或者 Mediator。但绝对不能在 Proxy 中直接调用 Mediator,这是为了保证数据层的独立性、可移植性和重用性,也简化了你的架构思想。不过可移植性这个优势,估计很多搞 FLASH WEB GAME 的朋友暂时都没啥机会体验,因为我们很难有这个需求。
2,Command,Command,Command!连叫三声“Command”,希望可以引起大家的注意。
因为 Command 的使用,在很大程度上反映着你对 PureMVC 框架的理解,甚至是对 MVC 模式的理解深度。
在 PureMVC 框架中,各部分通讯是用 Notification 消息,Proxy 可以给 Command 和 Mediator 发消息,Command 可以给 Command 和 Mediator 发消息,Mediator 可以给 Command 和 Mediator 发消息,怎么样?你现在是不是点晕了,这是正常的,其实我也有点晕!当你代码写到一定规模后,你会更晕。
其实 PureMVC 框架这么设计本来是为了让 MVC 各部分尽量脱耦,但这带来一个负面情况就是消息发送与接收机制设计的太灵活了,灵活对小项目是好事,但对大项目来说,往往意味着混乱,甚至会导致灾难。那怎么办呢?只能靠我们的自觉性自我约束,简化架构思想了。
根据《PureMVC 最佳实践》中的建议,我的做法是这样的,尽量使用 Command,让 Command 成为 Mediator 与 Proxy 之间通讯的唯一桥梁,Mediator 和 Proxy 中发出的 Notification,接收者一定是某个 Command,然后再由 Command 处理并将结果转发给真正的消息接收者,Command 就算仅仅起一个转发作用,仅仅有不到 10 行代码,也要创建一个 Command 类。这样不仅使你的架构更加清晰,而且也更符合 MVC 思想,Command 类的大量存在还使你架构的业务逻辑具有了更好的封装性和扩展性,可谓是一箭三雕,何乐而不为?唯一的负面影响可能是你需要创建和维护更多的 Command 类文件,但相对于优势而言,这点影响不算啥。
3,IDE
我知道现在可能还有一些朋友在用 FLASH IDE 写代码,这些朋友的执着让人钦佩,但我想任何一个熟练使用过 FlexBuilder、FD 或者 FDT 的朋友,都绝不会再回头使用 FLASH IDE 写代码了。
不对啊?不是谈 PureMVC 的么?怎么扯到 IDE 上去了?这是因为我现在要讨论的问题就和 IDE 有关,假如你现在用的还是 FLASH IDE 的话,除了随时写文档外,我真的很难想出一个很好的方案可以让你在没文档支撑的情况下,轻松掌握和随时维护几万行代码。可如果你使用的是 FDT,就可以在没有文档的情况下,利用“ctrl + r”和“ctrl + 鼠标左键”,以及全文件搜索等工具,瞬间搞清楚代码之间的联系和逻辑,找出要修改的地方。
OK,终于到 PureMVC 了。如果你使用的是 FDT,并且开始尝试使用 PureMVC 框架,可在使用的过程中,你发现你在写主程序时,还是不停的使用“ctrl + 鼠标左键”,而不是“ctrl + r”,这说明你必须重新审视你对 PureMVC 框架的理解了,请审查你的 Mediator 类,看里面是不是充斥着大量的 public 方法,如果你的对象之间依旧是通过 public 方法进行引用,而不是通过 Notification 通讯的,那你也没有必要继续使用 PureMVC 框架了。
4,单例模式影响到底有多大?
PureMVC 是一个完全依赖单例模式的框架。单例模式似乎在 AS 界一直有很大争议,这样的话,PureMVC 肯定也会有相应的争议了。
持反对意见的人,大多集中在“性能”和“团队协作”方面,他们认为一个单例持有过多引用会带来性能问题,而且生怕在团队协作中自己的单例类被人无意修改,引发离奇的 BUG。
性能方面,我之前也没做过主架构有效代码 10W 以上的项目,不敢妄言,但 10W 行以下的项目,绝对没有问题,如果你两三万行的架构就开始碰到主架构性能问题,估计十有八九是自己的代码写的有问题;
团队协作方面,我觉得 PureMVC 的 Façade 模式是非常灵活好用的,大家可以略做讨论,制定一个简单的规则,比如模块只能通过 façade 获取数据和发送 Notification,不能直接调用主程序其它 Class,这样只要架构程序员不犯错,模块程序员甚至连犯错的机会都没有,如果他们有,还是你的架构思路有问题,请继续审视自己的代码。
反正单例模式的问题到底是什么,我到现在也没完全搞懂,主要是我们的项目没碰到过此类问题,希望碰到过的朋友能再仔细跟火山说说,我也好弄清楚问题到底出在哪里了,自己以后可以更好的避免此类问题发生。
框架部分先谈上面 4 点吧,进入下一个话题,模块划分。
模块划分主要包括“核心模块划分”和“子模块划分”。
核心模块的划分思路是这样的:它们是游戏启动所必须的,相互之间是紧密联系的,还要经常被子模块调用;
而相对的,子模块的划分思路是:他们在游戏启动过程中不是必须的,可以在游戏过程中再加载,子模块相互之间基本上完全没有联系,一个子模块的增加和删除不会影响到任何其它子模块,子模块可能需要调用主程序的接口或者获得主程序的数据,但主程序绝对不应该依赖某个子模块。
明确了模块划分思路再具体看看哪些部分应该划分为核心模块,哪些部分应该划分为子模块。
一般情况下,核心模块按照游戏启动顺序包括:一个壳子 SWF → 配置文件包 → 登录注册 SWF → 主程序 SWF → 主 UI 的 SWF → 公共素材包。
而子模块相对来说简单很多,比如具体的某个小游戏,某个场景,以及某个场景里的触发功能等等。
下面我对核心模块逐一略做解释。
“一个壳子 SWF”:这是一个体积很小,但意义很大的 SWF;
它后面总是跟着随机变量,确保每次用户加载的都是最新的;
它里面定义着一些需要经常更新而且每次更新都必须保证用户也在第一时间就得到最新值的变量;
它里面最好有一个简单背景图,保证用户在超低网速的时候输入游戏网址不至于长时间面对一片空白;
它里面有安全策略的设定,是我们游戏和很多第三方平台合作的基石;
它里面还定义着主程序被加载进来之前的游戏启动流程等等。
“配置文件包”:核心模块版本号啊,全局文字说明啊,Service 接口定义啊,各个核心模块需要的配置信息啊什么的,一般是一些 XML 文件。
“登录注册 SWF”:这个简单,在加载重量级的 SWF 前,先加载登录注册 SWF,可以保证用户第一时间就能打开登录注册界面,而且可以有效节省服务器带宽。
“主程序 SWF”:这个就是我前面费了好大劲讲的主程序部分了。
“主 UI”:主程序和主 UI 为什么要分开两个 SWF,我前面已经提过了,后面还有说明,这里暂时不讲。
“公共素材包”:公共素材包是一个游戏不可缺少,但也不能过分依赖的东西。它包括一些全局的道具和效果,比如表情、技能特效、场景传送门等等。公共素材包里面最好就是一些简单的动画,体积小功能简单,严禁在公共素材包里添加上百 K 的东西,或者代码上百行的小模块,公共素材包建议 500K 以下。
看了上面的讲解,你可能觉得核心模块分那么多,太麻烦了。
不错,在我看来,对 SWF 加载流程的分解和控制,对异步程序的掌控正是衡量一个 AS 程序员是否经验丰富,是否足够老道的重要指标。很多从其它语言转到 AS 并有多年编程经验的朋友,架构方面可能和 AS 程序员差不多,甚至比很多自学成才的 AS 程序员做的更好,但这方面往往不如长期与 CPU 和 SWF 体积搏斗的老牌 AS 程序员。
核心模块划分的越合理,用户体验往往越好,后期编写和维护代码的效率会越高。但在前期会比较麻烦,而且对架构师的架构经验和能力必须提出更高的要求。
什么都不分,主程序、素材、核心模块都弄在一个 SWF 里,用户一开始必须先下载完这个 SWF,或者弄了一堆核心模块和超多公共素材,用户一开始必须面对 Loading 条长期等待,必须等所有核心要素全部加载完成才能进行一些基本操作的做法,从架构角度上讲,是最简单的做法,因为不用过多考虑复杂的异步和 SWF 拆分问题,但从用户体验和长远的开发维护上讲是非常不利的。
根据我们的经验,用户登录前加载的所有资源体积应该控制在 200K 左右,而用户进入游戏主场景前,加载的资源总数应该控制在 1M 左右。还有前面提到过的那位用了 PureMVC 后项目编译一下要十几分钟的朋友,估计就是把所有东西都弄到一个 SWF 里的做法。主程序随便改动测试一下,就要十几分钟,牵一发而动全身,开发效率从何谈起?
根据我们的经验,任何主程序、核心模块还有子模块的编译,都必须在 10 秒以内,这才是合理的——我的机器是 07 年花了 3000 多买的戴尔品牌机。
谈完主架构,接着谈:主 UI。
主 UI 一般指主要的人机交互界面,这里的主 UI 区分于主架构中的 Mediator,当你看过 PureMVC 文档后,就知道了,Mediator 只不过起到一个真正的 V 和 PureMVC 框架之间的桥梁作用,PureMVC 里的 Mediator 其实并不实现什么功能,真正的功能都是在主 UI 里实现的。但主 UI 又不得不算是主程序的组成部分,因为它不像其它模块,基本上只需要调用主程序的接口就行了,本身并不需要对主程序提供接口。而主 UI 作为用户操作界面,必须大量的向主程序的 Mediator 提供接口,或者发送 Events。所以主程序和主 UI 之间的配合必须非常密切才行。
不同的游戏类型,可以选择的 UI 解决方案也不同。策略类非常适合用 FLEX;
MMORPG 这类标准网游,非常适合用 ASWING;
而像我们儿童虚拟世界这类游戏界面非常夸张,没什么标准规则,又不是太复杂的界面,还是适合完全自己开发。
相信任何有过游戏项目经验的人都应该能理解,UI 也是 FLASH 开发中的重头戏,很多细节的处理非常麻烦,在项目早期具有很大的工作量。
还是以我们的项目为例,我们的 UI 架构思路是这样的:
1,UI 架构概述
我的 UI 框架,所有的界面组件都是直接拖放在 Stage 上的,其功能代码大部分都是在发布时编译的,基本上不用 new 的方式。这种方式的好处是方便编辑界面,从总体上直观的把握所有的 UI,减轻程序运行时的负担,同时避免 AddToStage 带来的诸多问题。缺点是,当 UI 膨胀到一定规模时,可能会需要你有一台配置比较好的电脑——哎,说到这里我就伤心啊,我那台玩魔兽效果全关还卡的电脑,一直陪伴我的整个 UI 开发历程。
2,UI 框架视觉层的结构
UI 的 Fla 层次结构是这样的:
第一层是文档类或者与 UI 主类关联的某个 MC,我们选用的是 MC 的方式,因为 MC 的方式更灵活;
第二层是这个 MC 里的所有组件,这些组件大部分是根据功能划分在一起的一组元件,比如玩家个人面板,而这个组件本身也是个 MC;
第三层是组件里的所有元件或者共用组件,元件就是背景啊,按钮啊什么的,而共用组件比如滚动条啊翻页组件啊什么的;
主要的就这三层,其实那些共用组件 MC 再往里面双击还可以划分一层。
对应 Fla 的层次结构,AS 的结构如下:
第一层是文档类或者主 MC 关联的类,这个类里持有所有界面元件的引用;
第二层是这些界面元件对应的组件 Class,组件的功能都是在这里实现的,比如个人面板的 MC 将会对应一个 MyPanel 的 Class,这个 Class 里实现 MyPanel 的所有功能。至于 Class 和元件之间是怎么对应的,我用的是一种松耦合的代理模式,也就是将 MyPanel 对应的 MC 作为参数传递给 MyPanel 这个 Class,而这个 Class 会有自己的私有变量记录对应 MC 里需要进行操作的元件,具体到功能实现时,从代码层面上看,就好像 Class 操作的都是自己的私有变量,而不是直接操作界面元件。这样,当界面元件修改名字时,CLASS 的改动很小。而且这种代理模式可以实现一个 Class 代理不同的元件,当界面只是需要修改外观不需要修改功能时,非常方便。那么这些 Class 是在哪里初始化并获得它要代理的 MC 呢?正是在主 MC 对应的 UI 主类中,比如当获得 MyPanel 对应的 MC 后,就会立刻:
public var myPanel:MyPanel = new MyPanel(myPanel_mc);
当所有的组件注册完成后,这个 UI 主类就持有了所有组件的引用,可以方便主程序调用;
第三层其实就是共用组件,比较特殊的是,我的共用组件,比如滚动条,也是用代理模式写的。
3,基于代理模式的代码架构设计
完全代理模式为我们创造了一种可能,就是把 UI 和 UI 对应的代码分开编译。
这跟 FLEX 的皮肤更换机制有异曲同工之妙,只不过它的组件是要 new 出来的,布局是要代码控制的,皮肤都是一个个 Class,整体效果一般都要编译后才能看出来;而我的组件是直接拖到舞台上的,布局大部分是直接在 FLASH IDE 里手动布置好的,皮肤都是一个个命名过的 MC,整体效果编译之前基本上就能看出来。
FLEX 在更换皮肤的时候,Class 名绝对不能变,而我的 UI 在更换皮肤时,MC 的名字和层次结构不能变。
FLEX 关联皮肤是在编译时完成的,而我的 UI 关联皮肤是在运行时,当启动程序加载完 UI 代码的 SWF 和皮肤的 SWF 后,动态指定的。
把皮肤和功能代码分开编译成两个 SWF 有个好处,就是在实际开发过程中,我们会碰到有时候只需要修改代码,而有时候只需要修改界面的情况,当然,就算你把代码和界面一起编译成一个 SWF 文件了,也完全可以对应这种情况,无非是编译一次的时间稍微长了一点点。
可当你面对这样的情况呢:某次游戏版本更新出现状况,需要你目前功能不变,但画面必须马上退回到上一个版本。这时候傻眼了吧?你开始对策划们咆哮:“你们能不能想想好再让我们做啊?”但你还是不得不重新打开已经做好的 UI,把里面最新的界面再修改回老版本,同时还不敢把最新的删了,因为下一个版本估计马上又要替换回最新的画面了。可如果你的皮肤和代码是分开编译成两个 SWF 的,这种情况就简单了,你可以让运维从 SVN 上拉出上一个版本的皮肤 SWF 重新推到服务器上就好了,你所要做的只不过是动一下嘴皮。
4,UI 数据层
最后谈一下 UI 的数据层吧,UI 是否需要数据层呢?答案是肯定的。尽管你可以从主程序那里获得任何你想要的数据,尽管大部分时间你只是需要数据来显示一下而已,但 UI 自己记住某些数据会大大方便自己写代码。UI 的数据层不需要主程序那么复杂,每个组件有自己的数据变量,然后整个 UI 再有一个存放公共数据的地方就足够了。
谈完主程序和主 UI,最后再简单谈一下小游戏、场景和模块。
先说小游戏吧,小游戏是相对最独立的一块,可能只需要主程序提供用户数据,并在游戏结束后将分数发送给主程序就行了。所以这部分从管理的角度上来讲是相对轻松的,但这不意味着小游戏开发就简单了,有时候,麻雀虽小五脏俱全,想开发出一个性能和用户体验俱佳的小游戏绝非朝夕之功,要是碰到一些算法复杂的小游戏,那就有得头痛了。其实对于儿童虚拟世界游戏,小游戏应该走创意和简单路线,搞得太复杂了,既不好开发,小孩子又不一定玩得来。
相对于小游戏,“场景和模块”就和主程序甚至是主 UI 关系密切了,但不管怎么密切,大部分时候它们都是在所要数据、发送事件、或者触发某个界面的显示与隐藏。
如果某个模块的修改需要经常波及到主程序,或者很多模块在做同一件事,重复写着同一段代码,这时候就必须重新审视架构,看是不是某些地方架构的不合理了。不合理的地方,只要时机允许,一定要尽快改掉,绝对不能放任自流,一块儿小毒瘤最终可能引发癌症。
模块和场景程序员在我们公司其实是非常累的,因为每周都需要发布新的版本,每次都很赶。在这种情况下,模块和场景程序员的责任心就非常重要,他们随便哪里随意了一下,会直接导致糟糕的用户体验,因为大部分时间,用户直接接触的东西都是他们的作品。
架构写的再好,最终模块都做的很糟糕,对用户来说没有任何价值!
所以,一个老道的,有责任心的,能够快速开发出优良用户体验的 AS 模块程序员,完全有理由拿高薪,因为他们能做到的,一些所谓的纯架构师未必做得到!
前端与美术的配合
老闪客们应该都知道,FLASH 这款软件在历史很长一段时间内都是用来做动画的,闪客和美术在这段时间内本就是同根生。
后来随着第二版 AS1 和 AS2 逐渐完善,以及 AS3 的强势出炉,闪客们才逐渐分化成纯程序和纯美术两个阵营了。但不管怎么分,FLASH 程序和美术之间的关系依旧非常亲密,一个老牌的 AS 程序员必然要比其它语言的程序员懂得更多美术方面的知识,至少也能熟练操作 FLASH IDE,并进行简单的图形处理。
FLASH 程序员与美术的合作大部分时间是由 AS 程序员主导的,主要表现在以下几个方面:
1,FLA 文件管理:
把有联系的美术素材放进一个 FLA 文件中统一管理,既能有效减少美术素材的数量,也方便程序员写程序。
本来美术素材管理应该是由美术负责的,但由于美术素材大部分时间可能也需要程序员写程序,美术和程序需要共享这些素材,虽然我们可以用 SVN 进行共享和版本控制,但程序员和美术还是要靠约定才能非常默契的知道什么时间该到什么地方找什么文件。而这个约定就是我们程序员应该制定的,因为程序员在条理性和制定规则方面一般比美术更靠谱。
以我们公司为例,文件管理基本上都是由我负责的,我把需要多个美术和程序员共同维护的部分以项目名命名成一个文件夹,项目下如果需要还可以进行子分类,分类规则也是我制定。
而大部分的子模块可能只需要一个美术加一个程序员就搞定了,这时候美术就把素材放到以自己英文名命名的文件夹下,至于他们的文件夹内如何分类,我会给出意见,但并不强制管理。
模块程序员也会都有以自己英文名命名的文件夹,他们会把美术的纯 FLA 素材拷贝到自己的文件夹下,并根据模块进行子分类,然后写代码并发布 SWF,至于 SWF 文件如何管理,我会在下一节中讨论。
其实我的管理目标非常简单,我只需要所有的美术和程序员能在任何时候瞬间找到我们需要的素材和源代码所在地,并且把需要的版本调出来。
只要这个目标还在可控范围内,我就会给所有员工最大的自由性,把自己从管理里解脱出来,把更多的时间投入开发,毕竟对于创业型公司而言,快速开发,让老板和市场看到产品才是首要任务,管理只需要在必要的时候强势出手就可以了。
事实上,我们公司的文件管理,我每隔半年才会强势管理一次,用大概一周的时间重新规范规则,其它时间基本处于放任自流状态,但从没出过什么大问题。最后给大家一个数字,我们公司经过将近三年的积累,已经有几十个 G,上万个美术素材了。
2,SWF 文件管理:
SWF 文件一般是由前端程序员发布并管理的,不过也有一些 SWF 可能不需要写代码,比如家具、个人面板背景等等,这些可以直接由美术管理,管理方案和 FLA 文件管理差不多。
最大的不同就是,SWF 文件最终的发布路径是内网模拟测试环境,而不是本机。像我们这样周更新线上版本驱动的游戏运营方式,不可能为每一个模块都单独搭建拟真测试环境,如果这样的话,可能我们测试环境还没搭好,就该上线并准备下一周的更新了,所以所有的模块最终的整合测试都是直接上内网测试环境进行。
3,FLA 内元件的管理:
这个问题相信很多 AS 程序员都碰到过,也都为此头痛过。
美术给到程序员手里的 FLA 文件可能是混乱不堪,库里没有任何分类,元件名也都是清一色的“元件 1、元件 2,元件 3……”,元件内部遮罩,组合,层次也都没啥规律。
要是美术直接给我一个 AI 或者 PS 的源文件让我们自己导入 FLASH,那我们就更抽搐了,颜色模式的改变,路径工具的失灵,大量的图层导致裁切困难,而且还不能进行打散合并,只能一层一层的切。
这个时候,正如我前面提到的,一个合格的 AS 程序员应该对美术和图形软件有更多的了解,你应当及时纠正美术不恰当的做法,甚至给出合理的解决方案。比如你应该知道 FLASH 只支持 RGB 颜色模式,AI 不但整个文档可以指定颜色模式,每个图层也可以单独指定,当美术给到你的 AI 导入 FLASH 有色彩差异的时候,能帮助美术找到哪里的颜色模式不对,并建议他们以后只使用 RGB 模式。
很多纯 AS 程序员可能有图形恐惧症,他们会想尽一切办法把这部分工作推向美术,但最终他们都会很郁闷,因为他们会发现,除了能指定库文件夹的命名规则外,其它的规则很难跟美术说明白,而且由于模块的千变万化,很难总结出一个完全通用的规则。想从美术手里拿到一个完全不用修改,自己可以直接写代码的 FLA 文件,几乎天方夜谭。
所以,与其让 FLA 文件在美术和程序的你来我往中浪费时间,与其让自己在对美术的鄙视中愤懑抱怨,不如提升一下自己的美术常识和图形处理基本功。毕竟,元件在舞台上怎么命名,关联什么类,层次怎么样,怎么被程序利用,这些只有我们程序员最清楚,这部分工作由我们程序员完成完全是合理的,也是效率最高的,美术只要把我们需要的素材交给我们,并放到方便查找的地方就可以了。
放下程序员的架子,主动走入美术的世界,对我们程序员绝对有好处。
4,FLASH 虚拟机的性能问题对美术的影响:
谈到这个问题,我就想起了一个让我抽搐已久的情况。
我们老板总是喜欢语重心长的对我说:“火山,你给咱们前端人员和美术出一个方案吧,告诉他们怎么做可以让 FLASH 性能最高!”
额,现在请问哪位朋友可以帮火山回答这个问题。火山真的惭愧,搞 FLASH 搞了 7 年了,始终还是没完全弄明白 FLASH 的诸多性能问题。
不管以前的 MM 还是现在 ADOBE,都将其图形处理和屏幕渲染部分视为其镇山之宝,不肯公开其技术内幕,我也就始终无法从理论的高度给出一个本质的回答。
我现在的大多数性能解决方案,都是根据项目的实际情况,根据 7 年来的经验总结出的经验科学。
而且我始终不相信,谁可以给出一个适合所有项目的、通用的性能解决方案,可以同时让内存、CPU、带宽占用都最少,而且画面又很炫,功能很强大,SWF 文件非常小,可玩性非常高,而开发周期和成本却很少。
内存、CPU、SWF 体积、带宽、效果、成本,这几个要素往往是相互矛盾的,你对其中任何一点的过分优化,都有可能导致其它点走向反面。
我深信,在目前这个时期,一个性能方面的高手,绝对不是看他能不能给出一个全面优化的方案,而是看他在面对不同的项目,不同的情况时,如何做出选择和取舍。
是的,“选择和取舍”永远都是人生最艰难的话题:手心手背都是肉,削掉哪边呢?老婆孩子都掉海里了,救谁呢?
在这样的情况下,我觉得一个负责的前端人员,反而不应该仅仅简单的扔给美术一份死的文档,告诉他们应该怎么做,让他们一直这么做就可以了。
前端人员应该在每次面对一个实际情况时,都不厌其烦的跟美术讲清缘由,我们应该尽量授人以“渔”,而不授人以“鱼”,让他们明白选择的道理,而不是简单的告诉他们选择什么。相信只要是虚心学习的美术,经过一年半载的讲解他们就能替你做出判断了,这时候你再让他们去跟后来的美术讲,你就解脱了。
很可惜,大部分不懂技术的老板可能觉得你是在故弄玄虚,非要你给出一份文档。无所谓了,你跟不懂技术的人争论不是自讨没趣么?老板更多时候是从管理的角度出发的,我们应该配合。我们也不是没什么可写,比如尽量减少元件数量啊,减小 SWF 体积啊,减少持续性动画啊,多做触发性动画啊,少用遮罩和滤镜啊,不要嵌入中文字体啊,提高元件重用性啊等等等等!这些建议听上去完全正确,忽悠不懂技术的人正合适。
但其实在高端的开发中,这些理论都是废话,帮不上多大忙,因为地球人都知道了,我们碰到的问题肯定是超越这些技术点的高端问题!
综上可以看出,其实前端和美术的配合过程大部分时间是由前端主导的,这也是我前面一再强调前端要多懂一些美术知识的重要原因。当你可以和美术一起谈论美术理论,在美术的电脑上直接操作给他们看;当你从美术的角度给他们提出解决方案的时候,你往往会更容易被美术所接受。担负起主导前端与美术合作的责任,用你的专业征服他们,用你的诚意打动他们,让美术与前端完美结合,让你的产品第一时间抓住用户!
前端与后端的配合
FLASH 与后端通讯的手段多种多样,网上相关教程太多了,这里不再例举。但很多时候,创业团队由于受制于各种现实条件,可选择的方案并不多。像我们公司,刚开始基本上只能选择 FMS+PHP+MYSQL。其实,对于前端来说,后端选择什么解决方案对我们的影响并不大,我们无非就是用的 API 不一样而已。多看看教程,用很少的时间我们就能掌握其要领。
那么前后端合作的难点是什么呢?我觉得关键是逻辑的划分。
“前后端合理划分逻辑”,这句话咋看上去貌似简单,其实里面蕴含着诸多方面的考虑。比如安全性、后端性能、工作量、人事分工等等。
安全性问题:
记得我们的游戏同时在线超过 3000 人的时候,就已经有人开始攻击我们的后端了,篡改了很多人的个人资料。幸亏攻击的人只是我们一个善意的玩家,如果是恶意的商业攻击,后果不堪设想。
经过这次后,老板开始缠着我们追问“怎么防止别人攻击,提高安全性”。
这个问题又一次把我们难住了,我们都知道,基于 HTTP 的请求不被截取是不可能的,而 SWF 文件又不存在绝对的安全。就算你防得了恶意进攻,你也防不了良性的外挂,想从技术层面让别人完全攻击不了我们也是不可能的。那我们是不是只能坐以待毙了?
不是!如果前后端在合作的时候,数据逻辑与合法性检查都是做在后端的,就可以很好的避免一些良性外挂。首先是游戏数据逻辑要尽量全做在后端,比如用户在玩小游戏的时候,我们不要只是在用户结束小游戏后,简单的把数据传回后端,后端记录进数据库完事,一旦攻击者发现了你这个传数据的后台接口,完全可以避开 SWF,做外挂直接呼叫你这个接口刷分,就算你验证用户也没用,因为他可以先注册一个合法的用户,然后在外挂中登录再刷分。
当然,你还可以对游戏分数先加密再传给后端,提高攻击难度,但这也是不保险的,因为加密算法就在你的 SWF 文件中,别人可以很容易获得。
所以正确的做法应该是:游戏开始的时候只告知后端游戏 ID → 后端标识 ID 对应的游戏已经开始并记录开始时间 → 用户每次获得一个分数时,前端传回来的不是分数,而是一个动作 ID, 后端根据动作 ID 给用户加分 → 游戏结束时,前端告知后端游戏已经结束 → 后端得知游戏结束,记录结束时间,计算时间差,根据时间差和最后得分是否符合标准做出相应处理,如果符合标准就把最后得分入库,并返回前端显示给用户,如果不符合标准,就启动作弊处理系统。而这个标准一般是由数值策划给出的。
经过我这么一分析,你可能头痛了,本来一个很简单的小游戏计分,怎么搞得这么复杂?前后端工作量都增加了不说,对后端性能也提出了更高的要求,服务器可能要增加了,后端人手可能要增加了,开发周期也要延长了,值得么?
这个问题问的很好,这正是我下面要说的,
后端性能、工作量、人事分工问题:
一旦我们每一步进行安全性与合法性验证后,整个项目的工作量都会大大膨胀,开发周期也会大大延长;
一旦我们把数据处理、业务逻辑和安全验证都移到后端时,后端的压力就会增加,服务器要增多,对后端人员的能力要求也会提高。
很多初创团队在项目初期人力财力,软件硬件都不足,可能顾不上那么多,一心想着早点让项目上线。在这种情况下,我觉得安全性可以暂时放一下,众所周知的安全漏洞补上就可以了。
但“数据处理和业务逻辑”这个,宁可开发的慢一点,宁可再招个后端高手,宁可多几台服务器成本,也要把它们尽量都放在后端。因为这个没分清的话,会影响到整个系统的清晰度,严重影响项目中后期的发展,为日后的重构增加难度和超多的工作量,我们还指望着在重构时加强安全性呢,到时候数据处理和业务逻辑还是要放后端!所以综合考虑,该出手时就出手,能省的不浪费,不能省的不要抠!
前面一节谈了前后端合作的难点,这里再简单的谈两个要点:
1,前端人员不要以前端的角度看后端:
前端和后端有个本质的区别,就是前端的负荷是分担在每个客户端的,而服务端的负荷是集中在服务器上的。
对于前端来说,一个功能多占了几 K 内存,SWF 文件大了几 K 根本不是什么问题,可对后端来说就是很严重的问题了,一个人大几 K,上千人就是几 M 了。
服务器在连接数、内存和 CPU 之间会有微妙的平衡点,一旦这个平衡点被打破,随便再多哪怕一点点资源占用,整个服务器的性能都会严重下降,影响用户体验。当然,如果你有几十上百台冗余服务器供你负载平衡,你可以当我没说。
可如果你像我们公司一样,一开始就三五台服务器的话,就请前端人员一定要多多配合后端人员,帮他们省出每一个字节,每一次请求。
比如像道具属性会有很多文字说明,这些说明应该以类似 XML 文件的方式储存为静态文件,后端返回给前端的道具数据包里只需要一串物品 ID,前端就可以根据这些物品 ID 在 XML 文件里查询出这些道具对应的静态物品属性了。别看这些数据可能只有十几 K,对后端来说意义重大。
还是那句话,只要不是架构性问题,前端不要怕麻烦,要尽量配合后端提高性能。
2,前端后端要有很明显的 BUG 分界点:
当一个 BUG 出现时,后端应当很快的用一种统一的方案证明数据没有问题!这个方案必须让前端知道,并让前端也可以操作。
大家熟知的 PHP Remoting 里有一个 ServiceBrowser,这个东西就很好,它能罗列出所有 PHP 的接口,前端自己输入参数,它就返回结果,前端可以根据结果直接查看数据是否正确。——确定数据的正确性,对前端 DEBUG 非常重要,而一个 BUG 的解决,一般都是由前端人员入手并进行定位的。
其实相对于前端和美术的合作,前端与后端的合作还是简单清晰的,前后端在开发的过程中,应该是非常独立的,后端开发完全可以先启动,把数据接口提前写好,等着与前端整合,而当整合过程发生问题时,又可以很快的界定是谁的问题。
公司文化与产品定位
前面谈了那么多,无论是策划、美术、前端还是后端,大家通力合作,共同奋斗的目标无非就是希望开发出来一个好产品,而开发出一个好产品的目标无非就是成就一个好公司,这就涉及到“产品定位”与“公司文化”的问题,公司文化和产品定位没做好,其它人再努力都是枉然。
可正是这两个问题,从我们公司成立到现在一直困扰着我,我抓破脑袋苦思冥想,总结出我们公司的公司文化就是“老板说了算”,而我们的产品文化就是“与时俱进,不断重新定位”。
下面我先谈公司文化再谈产品文化,因为产品文化是包含在公司文化中的。
公司文化:
一个公司的文化在很大程度上是由初创团队建立的,而初创团队一般分两种,一种是权力分散型,初创团队在各个领域都有领头人,虽然也有形式上的 CEO,但产品、研发、市场相互干涉的并不多,领导层内部“三权分立,民主平等”,对外发言人则可以统一由 CEO 代劳。
这种模式的优点是大家优势互补,让懂行的人完全负责相关领域,负责人成就感大,责任心强。缺点是,权利分散就要求领导层必须非常团结,配合默契,如果他们之间出现矛盾,对公司影响会很大。我们的竞争对手淘米网络就是这种模式,到目前为止,他们公司发展的还是最好的。
另外一种模式就是“老板专政”模式,专政到什么程度,跟老板对权力的欲望有关。
我们公司老板就专政到事无巨细的程度了,就连买一个几百块钱的路由器都要再三跟老板请示,美术、策划、开发所有的日程安排、人事任用都要由老板点头。
“专政模式”在创业初期也未必就是坏事,因为创业初期,困难重重,大家又都有自己的想法,每个人的信心都比较脆弱,如果没有一个强势的人主掌大事,所有人容易形成一盘散沙的尴尬局面。
专政模式下,公司文化其实就是老板的个人文化。专政的人一定要有专政的资本,有专政的能力,掌握着公司最大的权力,就必须承担最大的责任。如果公司成功了,就算你再说成功是大家的,最大的成功者还是你,但如果公司失败了,就算你找一千个理由推脱责任,最大的失败者也是你!
在这种情况下,专政者要努力提高自己的全面素质,公司管理、产品、开发、策划、美术、市场都必须有所了解,你的任何一个错误的决定都会把公司推向深渊,并引起相关部门人员的不满。
我们公司就是典型,老板以前是做销售的,对策划、开发和美术,甚至是互联网都没什么概念,做我们项目之前连 QQ 都没用过!虽然他在资历和财力方面当之无愧,但其短板也是无法否认的事实。
初创很长一段时间内,他都敢拍板说一个儿童虚拟世界游戏一个 AS 一个月搞定之类的话,而且还要非常强势的让你接受,并拿出执行方案。至于他为什么敢这么坚决的做出这个错误的决定,我也不明白。可能正是因为他也不知道到底需要多长时间才能开发出来,而我们又没有取得他的信任吧,所以他就只能尽量往少的时间说,等到我们没完成工作,大不了再延长时间而已。
可这对我们这些开发者就造成很大困扰了,这种根本不可能达成的目标如何拿出执行方案呢?开发规划如何做呢?最后开发不出来谁承担责任呢?于是一个怪圈形成了:老板不信任开发 → 制定不合理的开发目标 → 制定不合理的开发规划 → 开发规划没完成或者大打折扣 → 老板认为开发者能力不行更不信任开发 → 老板要求开发者提升自身能力满足他的要求 → 开发者依旧满足不了老板 → 老板在工作能力和员工素质上全面怀疑开发者 → 制定更加不合理的开发目标甚至是惩罚制度 → 项目更加完不成……额,这真是一个装满了苦水,倒又倒不出的杯具!
当然,只要不是傻子,在这个悲剧的循环过程中,不管是老板还是开发者都会变得越来越“聪明”,老板一天天成熟了,程序员一天天世故了。只是曾经浪费的时间,错过的时机不再有,曾经不合理制度下积累的问题,明天需要继续补救!如果上天能给大家一次重来的机会,我相信,老板会说:“下次我一定要在项目刚开始就找一个靠谱的,值得信任的 CTO!”,而程序员会说:“我下次再也不会跟着不懂技术还自以为是,横加干涉的老板了!”
虽然“民主平等”和“高度专政”两种模式都有其优缺点,但最终玩的都是一个“人”字。
相同项目,一个模式,不同的人玩出来的结果肯定不一样。同是专政模式,“奥比岛”就比我们项目成功多了。
所以选择一个模式的关键不是模式本身,而是操盘者是否能够在合适的时机选择合适的模式,是否能驾驭模式本身!
产品文化:
产品文化包含于公司文化,“民主平等”的公司,产品的文化就是“管理层相同价值观”的文化,而“高度专政”的公司,产品文化就是“老板个人”的文化。
不管是什么类型的公司,什么产品文化,这个文化一定要简明而清晰,要深入人心,最好能浓缩成简单的一个词或者句子。
“妈妈放心,孩子喜欢”就代表着淘米网络的产品文化。这个口号从淘米成立不久就已经开始喊了,到现在没有变过。我相信他们的用户,他们用户的家长,他们公司从管理层到员工每一个人,就连他们的竞争对手都对他们公司的价值观,对他们的产品文化有一个清晰的认识。
而我们公司呢?反观我们公司,在这方面做的非常差,公司从成立到现在产品定位一直在变。刚开始要做一个针对初高中生和女孩子的休闲社区,搞了几个月后,又发现企鹅俱乐部,一股脑的投入到儿童游戏这块儿蓝海市场,说要做一个中国版的企鹅俱乐部。再后来可能觉得儿童市场有点小,收费比较困难,又想把产品目标用户群再提高一下,提高到初高中生也能玩,游戏复杂度也要随之提高。这样还没做多长时间,又看到人家淘米推出赛尔号这种 PK 游戏了,又觉得纯绿色游戏的可玩性不高,对用户尤其是男孩子的吸引力不够,又要在我们的游戏里也加入 PK 和打怪了。
直到现在,公司里上上下下,除了老板之外,没几个人能弄清公司的产品定位是什么,我们的产品文化是什么!这种情况导致一个很严重的问题,就是策划在策划游戏的时候,没有核心价值观,也就更没什么游戏世界观了,最终导致游戏形散神也散!
游戏一直在改版,功能一直在开发,BUG 一直都存在,性能一直上不去,目标用户群一直在改变,老用户一直在流失,我只能用一个词形容我的心情:痛心疾首!
2010 年:我的梦想扬帆起航
从毕业就开始在现在这家公司参与创业,一直做 FLASH WEB GAME,当时的想法很简单,就是想体验一下顶尖的 FLASH 应用开发。转眼即将三年了,回眸探望,几多感慨,但终究还是能淡然处之。毕竟大家都不容易,大家都在摸索,也都在摸索中前进和成长,公司现在其实已经比刚开始好多了。
如今再打开 4 年前那篇《我的 FLASH 情结 2006》,激扬的文字震撼我心。而现在的我,在项目的前端开发中已经找不到往日的激情,每日重复的机械劳动。而自己的理想,更是逐渐飘渺远去,一种温水煮青蛙的危机感油然而生。于是 2010 年,我向公司递交辞呈,结束我毕业后的第一份工作;再写下本文暂时结束 FLASH WEB GAME 开发生涯。
那么 2010 年,我要做什么呢?我要开始做自己的项目了。
我们公司的一位在商场上混迹多年的大股东在年会上语重心长的对我说:“火山啊,你现在自己做项目有两个最大的问题,一是你没在大公司呆过,对一些正规的公司流程不了解;二是你原始资本积累还严重不足,很难支撑项目长久下去。”
其实我自己又何尝不明白呢,我知道自己这次单干也是九死一生,但我实在等不了了,7 年的技术积累,3 年的工作积累,为的就是今天。我也是奔三的人了,都讲男人三十而立,马上要面对结婚生孩子,上有老下有小的艰难局面,我再不趁机把握最后这两年相对轻松自由的机会,以后会更难。
我的梦想可能很天真,但我会做的很认真。
其实冷静下来想想,也没什么好怕的,想当年我敢带着一千块钱闯上海,今天我就敢拿着几万块钱自己干,大不了折腾完了再到大公司打工深造呗。
虽然我工作三年才积累了几万块钱这听上去有点寒碜,虽然我每个月最多只能给自己播出 1000 块钱的创业资本这听上去太少了,虽然我自己得把策划、开发、美术和运营全做了这听上去有点假,虽然现在我还天天穿着高中和从亲戚那里捡来的衣服这看上去有点苦,但这都是外人看我的观点,我自己是乐在其中,浑然不觉,哈哈。
不管怎么样,2010 年,我的梦想必须扬帆起航,不以成败论英雄,只为人生少留遗憾!
→2010 年 于 上海
后记一:写这篇文章的时候身在上海,现在已经在杭州了。我自己的 FLASH 项目真我网(现在已经无法访问)已经开发完成,心愿也算了了,没做好充分的准备前,暂时不准备大规模运营。现在又参加了一个新的创业团队,希望 2011 年能做出一个成功的商业产品,新的公司也能成为一个成功的公司!
→2011.4.10 于 杭州
后记二:2010 年距今 5 年了,5 年间其实又经历了很多事情,到杭州跟一个风格迥异的团队创业过一次,自己主导创业过一次,参与过一个还算赚钱的移动游戏项目,现在自己又拉了一票人捣鼓了一摊子事。又经历了这么多之后,再回顾这篇文章,不谦虚的说,其实当时我在 FLASH WEB GAME 方面的认知已经足可以撑起一款商业游戏了,也可以说在技术和研发方面,我已经做好了比较充分的准备,但为什么后面却一直不顺呢?现在想想,主要是主观上我有个致命的点一直不对,至于这个点是什么,我会专门开文章讲。而在这篇文章中,关于创业的认知,虽然我也洋洋洒洒讲了很多,但基本都是站在参与创业,甚至是打工者的角度讲的,老板的角度几乎没有,甚至很多幼稚和偏激的想法,这也是没主导过创业的人无法避免的,好在后来自己终于有机会主导了一次,现在的认知也更全面了。到时候在新文章中一并讲。
→2015.10.12 于 上海
后记三:这篇竟然有将近 3W 字,好长啊!但文章刚出来的时候,在“蓝色理想”和“9RIA”两个当时最火的 FLASH 技术论坛,还是有很多读者仔细阅读了全文并跟我进行了深入讨论。虽然这两个网站现在也都已物是人非,但是这篇文章毕竟曾经影响了那么多人,现在正在写的《十年创业史》也算对当时读者们的一个交代吧。
→2017.2.16 于 上海
后记四:16 年后,不惑之年再看这篇文章,竟然有点被当年的自己镇住了,虽然关于公司和商业的认知还不成熟,但从仅仅毕业三年这个角度看,成长度还是蛮高的,尤其是在技术和项目管理的认知上,真的已经很强了,足以领导任何商业级 FLASH 项目。如果今天的我遇到当时的我,应该也会很愿意招聘这样一个热血还有能力的青年吧,哈哈!只可惜后来 FLASH 没了,我个人也从“技术思维”转型到了“赚钱”思维,一路自学来的强大技术专业没得到传承,人生总是在得失之间就已经轻舟已过万重山,但没有遗憾,都是经历!
→2026.2.5 于 新加坡