做个大宝剑游戏(这些神剑都大有来历?权力的游戏中那些瓦雷利亚钢锻造的宝剑)
做个大宝剑游戏文章列表:
- 1、这些神剑都大有来历?权力的游戏中那些瓦雷利亚钢锻造的宝剑
- 2、外国作坊打造黑暗之魂3大狼剑
- 3、乐高无限自我开发游戏
- 4、FC銆婇湼鐜嬬殑澶ч檰銆嬫灏嗘洿鎹㈠叺鍣ㄧ被鍒€煎緱锛熷墤銆佸垁銆佺煕鐩稿厠
- 5、大天使之剑H5主程分享:大型游戏如何登陆微信小游戏
这些神剑都大有来历?权力的游戏中那些瓦雷利亚钢锻造的宝剑
上一篇小编和大家讨论了冰与火世界里的第一美女,快速通道如下:https://www.toutiao.com/i6600223873923285518/
今天的主题是瓦雷利亚钢锻造的神剑,如喜欢小编的文章,可右上角点击关注,有任何问题,欢迎留言讨论,再次感谢!
瓦雷利亚钢(Valyrian steel),是一种注入了魔法的钢铁,瓦雷利亚的工匠以反复锻打来平衡及去除钢铁中的杂质,再施加咒语(或其他无人知晓的技艺)使钢铁附上非凡的特质。瓦雷利亚钢质轻坚硬,比任何其他钢材都要锋利。
但这制剑工艺现已失传,因此现存的瓦雷利亚钢剑变得极为珍贵和罕见。流传至今的瓦雷利亚钢剑只有几千把,其中约有两百在维斯特洛大陆。按瑟古德博士的计算,确切数目是227把。
一、已知现存的:
1、 寡妇之嚎(Widow's Wail)
是一柄融化史塔克家族的寒冰而成的双剑之一。剑刃上有红黑两色波纹,剑鞘由镀金樱桃木制成,由上过油的红皮革包裹,装饰着纯金狮子头,狮子有红宝石的眼睛。
这是一份泰温公爵送给国王乔佛里一世的结婚礼物。乔佛里死后,它传给了其弟弟托曼一世。这把剑见证了乔佛里的死亡,也见证了瑟曦的哭嚎。
2、 守誓剑(Oathkeeper)
同样是融化史塔克家族的寒冰而成的双剑之一。它比寡妇之嚎大一点,剑身上有黑红两种波纹,由泰温公爵赠予其子詹姆。
詹姆后将它送给了塔斯的布蕾妮,并让她去寻找珊莎·史塔克。他将剑取名为“守誓剑”,希望她能牢记自己的誓言和使命。
3、碎心(Heartsbane)
碎心是双手巨剑,属塔利家族,已经流传了500年。蓝道·塔利伯爵曾携此剑加入蓝礼·拜拉席恩大军。
4、长爪(Longclaw)
长爪是莫尔蒙家族的祖传之宝,流传约有五百年。
它是一柄长柄剑,长爪比长剑长,比双手巨剑短,为一手半剑,通常背在身后。
当乔拉逃往自由贸易城邦的时候,他留下了长爪,剑的所有权重新归杰奥·莫尔蒙。为从 尸鬼在黑城堡的攻击中解救杰奥,琼恩·雪诺放了一把火,这把火烧掉了长爪的剑柄。杰奥重新打造了一个带狼头的剑柄,并将剑送给了琼恩。琼恩提到杂种挥舞一把大剑很合适(大剑又称杂种剑)。
5、空寂女士(Lady Forlorn)
它归科布瑞家族族长所有,在剑柄末端嵌有一颗红宝石,按照传统总是借给家族中最强的骑士使用,待骑士死后,再归还给族长。
6、红雨(Red Rain)
它是卓鼓家族的祖传之宝。
希尔玛·卓鼓凭借智慧和一柄木棍从全副武装的骑士手中赢得这把瓦雷利亚钢剑,并从此成为卓鼓家族的传家宝。为此,他被成为“狡猾的”希尔玛。
7、夜临(Nightfall)
夜临属于哈尔洛家族,它的剑柄圆头是月光石做的,现由赫拉斯·哈尔洛持有。
在此之前,这柄长剑曾被铁群岛头领道尔顿·葛雷乔伊大王持有,他在一次掠夺中从某位死去的海盗手上抢得这把武器,并为之命名“夜临”。
8、缝衣针(Needle)
是一柄剑身细长的精钢单手短剑,也是艾莉亚·史塔克的第一柄佩剑。这柄剑与艾莉亚瘦削的身形很匹配,同时也是以轻盈敏捷著称的布拉佛斯“水舞者”剑客所善用的剑型。
二、已毁坏:
寒冰(Ice)
寒冰是史塔克家族祖传的巨剑,身宽过掌,立起来比罗柏·史塔克还高。其瓦雷利亚钢锻造而成的剑刃暗如黑烟。
奈德·史塔克曾用它来战斗以及亲自处决有罪的犯人。在他被俘虏之后,伊林·派恩得到这柄剑并用来处决奈德本人。后泰温·兰尼斯特将剑取走,“寒冰”也因此被重铸为两柄长剑,即寡妇之嚎和守誓剑。
三、不知去向
1、黑火(Blackfyre)
黑火在坦格利安家族代代相传,伊耿曾在征服战争中挥舞它。
它的最后一任主人是戴蒙·黑火,其姓氏和家族也是以这把剑命名。在其发起的黑火叛乱被平息后,黑火并被带往厄斯索斯,如今下落不明。也许它已经遗失,也许它仍然归属“寒铁”创立的著名佣兵团黄金团。
2、光啸(Brightroar)
光啸隶属于兰尼斯特家族,凯岩王于瓦雷利亚的末日浩劫之前一个世纪花了许多金子换到光啸,据说这些金子重量足够组织一支军队。
后托曼二世率领一支黄金舰队探索被末日浩劫摧毁的瓦雷利亚,却一去不返,光啸也就此遗失。
3、 黑暗姐妹(Dark Sister)
隶属于坦格利安家族,它细长的剑身是专门设计给女性使用。血鸦是暗黑姐妹最后一个已知的持有者,现在下落不明。
4、 警觉(Vigilance)
警觉是海塔尔家族的族剑,已知最后持有者为蒙德·海塔尔。
5、 孤儿制造者(Orphan-Maker)
河湾地洛克斯顿家族的族剑,已知最后持有者为Jon Roxton。
6、 真理(Truth)
可能是里斯贵族罗佳尔家族的族剑,已知最后持有者是摩雷多·罗佳尔。
7、哀悼(Lamentation),符石城罗伊斯家族的族剑,最后的持有者为威廉·罗伊斯爵士。暴民冲击龙穴时将威廉爵士杀死,此剑一并遗失。
今天的内容到此结束,敬请期待下期。有任何想法或建议可留言讨论,文章看完,确定不点个赞就走了吗?
外国作坊打造黑暗之魂3大狼剑
国外作坊Man at Arms打造了《黑暗之魂3》中的大狼剑。
近期国外作坊Man at Arms打造了《黑暗之魂3》中的大狼剑(Greatsword of Artorias)。《黑暗之魂3》是人气动作游戏《黑暗之魂》系列的新作,游戏日版已于2016年3月24日发售,中文版将在2016年4月12日发售。
以下是铸剑全过程:
从视频中可以看到,虽然不知道这把大剑是不是能在现实中削铁如泥,但是看看僵尸模型,爆爆白色液体什么的还是轻而易举的。
Man at Arms致力于打造游戏、动漫等作品中的武器,之前还铸造过《刀剑神域》中亚丝娜和桐人的武器,以及Saber的EX咖喱棒等。
乐高无限自我开发游戏
《乐高无限》是在乐高积木背景下诞生的游戏。这款游戏作品将乐高积木还原到游戏中,在赋予一些现实世界的特色后,玩家可以在屏幕上体验乐高积木的乐趣。
当然,这个工作不是搭积木那么简单。
我知道当你看到这个作品时,你会第一时间想到《我的世界》。的确,MC作为沙盒游戏的经典值得每一个热爱游戏的玩家铭记,但并不意味着所有沙盒游戏的核心玩法都要向MC靠拢。《乐高无限》是一部和MC完全不同的游戏作品。
《乐高无限》把自己定义为沙盒游戏,但实际上你可以在游戏里找到很多非沙盒游戏。这些游戏是沙盒本身创造出来的,但不是积木那么简单。可以是FPS。你可以和你的朋友在同一张地图上享受射击战斗,并从其他游戏中创建一些经典地图,如“运输船”。
也可以是赛车。你甚至可以在赛道上漂移,用氮气加速,用道具干扰对手,从而第一个冲过终点。
甚至是一个动作游戏,扮演一个忍者,用惊人的弹跳力和出色的手里剑技巧从黑暗中杀死敌人。
所有的游戏都可以由玩家自己创造,如解谜、塔防、角色扮演、构建地图、制定规则和测试游戏。基本的功能游戏都完成了。只要你有足够的想象力和耐心,这个游戏的深度几乎是无限的。
每个人都是开发者。
开发者模式是提供给玩家的专属游戏开发功能。以上游戏均为开发者模式创作。点击主界面开始游戏,创建地图成为开发者。但是,虽然实际上是在创作,但玩法不亚于单纯的体验别人创作的游戏。
进入开发者编辑模式后,你会发现所有物品都会处于无限使用状态,甚至连工具和生物都可以被创造出来。界面右上角有一个触发器,是普通游戏中很少见到的名词。玩家的出生点、复活点、怪物刷点等游戏机制。取决于它,而一个非常好的游戏性机制可以通过利用好触发器来创建。
FC銆婇湼鐜嬬殑澶ч檰銆嬫灏嗘洿鎹㈠叺鍣ㄧ被鍒€煎緱锛熷墤銆佸垁銆佺煕鐩稿厠
FC銆婇湼鐜嬬殑澶ч檰銆嬫父鎴忥紝姣忎綅姝﹀皢閮借澶囨湁鍒濆鍏靛櫒锛屾垨鍓戯紝鎴栧垁锛屾垨鐭涖€傛瘮濡傦紝涓诲叕鏇规搷閰嶆湁鐮存柀鍓戯紙鍓戯級锛屾枃姝﹀弻鍏ㄧ殑鍏崇窘閰嶆湁鍋冩湀鍒€锛堝垁锛夛紝涓夊浗绗竴鐚涘皢鍚曞竷閰嶆湁鏂瑰ぉ鐢绘垷锛堢煕锛夈€傛灏嗙殑鍏靛櫒鍚勪笉鐩稿悓锛屽奖鍝嶅疄闄呮垬鍔涜緭鍑恒€俓u003c/p>
FC闇哥帇鐨勫ぇ闄哱u003c/p>
鐜╁浠兂蹇呬篃閮界煡閬擄紝娓告垙涓殑鍓戙€佸垁銆佹灙锛屼笁绫诲叺鍣ㄦ槸鐩稿厠鐨勶紝涓昏琛ㄧ幇鍦ㄧ浉浜掍箣闂寸殑涓嶅悓鍛戒腑鐜囥€俓u003c/strong>鏍规嵁涓嶅悓鐨勬鍣ㄦ敾鍑诲懡涓巼锛屾垜浠熀鏈彲浠ュ緱鍑虹粨璁猴細鍓戝厠鍒€锛屽垁鍏嬫灙锛屾灙鍏嬪墤銆俓u003c/p>
涓嶈繃鍦ㄥ疄鎴樹腑锛岀帺瀹朵滑浼间箮鎰熻涓嶅埌杩欑鍏靛櫒鐩稿厠鐨勫瓨鍦紝鍥犱负澶у鐨勫懡涓巼閮戒笉楂樸€傚湪绗旇€呯湅鏉ワ紝鏃犺璋佸厠璋侊紝50%-80%鐨勫懡涓巼锛屽叺鍣ㄨ緝楂樼殑鏀诲嚮澶辫触鐜囨憜鍦ㄩ潰鍓嶏紝杩愭皵澶噸瑕佷簡銆傜壒鍒槸涓ゅ憳瀹炲姏鐩歌繎鐨勫ぇ鐚涘皢鍗曟寫锛岀悊璁轰笂鍙屾柟閮芥墰涓嶈繃瀵规柟涓夋姝i潰鏀诲嚮锛涗絾鐢变簬褰兼鐨勬敾鍑诲け璐ョ巼閮藉緢楂橈紝瀹為檯璋佽儨璋佽礋杩樼湡闅捐锛屽叏闈犺繍姘斻€俓u003c/p>
鍓戝垁鐭涗箣闂寸殑鍛戒腑鐜嘰u003c/p>
杩欓噷鏈変竴绉嶅彲闈犵殑鏀诲嚮鍙壍鍒讹紝鍛戒腑鐜?00%锛岀粷瀵逛笉浼氬嚭鐜板け鎵嬶紱浣嗙敱浜庢潃浼ゅ姏澶綆锛堟瘡娆″熀鏈湪10鐐瑰乏鍙筹級锛屽張鎬庤兘涓庢甯告敾鍑荤浉姣旓紵瑕佺煡閬擄紝姝e父鏀诲嚮鐨勬潃浼ゆ晥鏋滃彲杈?0鐐?40鐐癸紝鐢氳嚦鏇村銆傚姝わ紝鐜╁浠墠涓嶄細鎷胯嚜宸辩殑鐖卞皢鐢熷懡寮€鐜╃瑧锛屾姄浣忔満浼氾紝鍏ㄥ姏鏀诲嚮鎵嶆槸涓婄瓥銆俓u003c/p>
鍥犱负鍏靛櫒鐨勫懡涓巼鏅亶涓嶉珮锛屼娇鍏靛櫒鐩稿厠鏁堟灉涓嶆槑鏄撅紝鎵€浠ュ湪瀹炴垬涓紝鐜╁浠苟涓嶅叧蹇冨弻鏂规灏嗙殑鍏靛櫒鐩稿厠闂銆俓u003c/strong>姣斿锛屽叧缇絍S鍚曞竷锛屽悤甯冧负浜嗕繚璇佸叺鍣ㄧ浉鍏嬬殑浼樺娍锛屼富鍔ㄦ斁寮冩墜涓殑鏂瑰ぉ鐢绘垷鑰屾彁鍓嶆崲瑁呭ぇ鍓戯紝閭f槸涓嶆槑鏅虹殑閫夋嫨銆俓u003c/p>
姝﹀皢鍗曟寫锛氬叧缇藉叺鍣ㄦ湁浼樺娍
鐜╁浠粰鐖卞皢鎹㈣鍏朵粬绫诲埆鍏靛櫒锛岃櫧璇磋兘鍦ㄦ煇娆″崟鎸戜腑鎻愬崌涓€瀹氬懡涓巼锛屼絾鏁堟灉瀹炲湪澶湁闄愶紝杩樻湁鎹熻繖浣嶇埍灏嗗湪鐜╁蹇冪洰涓殑鍘熸湰褰㈣薄銆傛瘮濡傦紝璇歌憶浜甛u003c/span>鎵涙柟澶╃敾鎴燂紝寮犻鎻″嚖鍢村垁锛屽緪鏅冩寔澶у墤锛屼笉鏄笉鍙互锛岃€屾槸寰堝埆鎵€俓u003c/p>
鎬讳箣锛屽墤銆佸垁銆佺煕涔嬮棿鐨勫叺鍣ㄧ浉鍏嬬‘瀹炲瓨鍦紝浣嗘晥鏋滀笉鏄庢樉锛屼负浜嗘灏嗕滑鐨勫厜杈夊舰璞★紝杩樻槸淇濇寔姝﹀皢鐨勫垵濮嬪叺鍣ㄥぇ绫讳负濡ャ€傦紙鐩愰倯澶у厰璇存父鎴忥級#FC闇哥帇鐨勫ぇ闄?
大天使之剑H5主程分享:大型游戏如何登陆微信小游戏
想要了解更多的游戏资讯 一定要关注游戏陀螺!
导语:
有料,实例分析压缩优化代码方案。
随着渠道平台的发展不断发展及演化,我们的产品往往要登陆各种平台,而微信小游戏就是这些平台的其中之一。
微信小游戏是微信小程序的一个类目,它即点即玩,无需下载安装,体验轻便,可以和微信内的好友一起玩,比如PK,围观等。
但想让自己的游戏登陆微信小游戏,往往会有一些方面的限制。以下是由三七互娱旗下研发公司极光网络客户端主程陈策在上周举办的首期“极光会客厅”活动上的技术干货分享,以《大天使之剑H5》这一项目登陆微信小游戏受到的主要限制和解决办法进行实例分析。
《大天使之剑H5》受到微信小游戏的主要限制
1.所有分包大小不得超过8M:分包指的是在微信开发工具里上传的所有资源,包括JS代码和资源,一共不得大于8M;
2.单个包的大小不得大于4M:上传的文件里,不能有大于4M的文件;
3.JS必须放在分包里才可以运行,加载进来的JS文件只会被当成文本:加载进的JS文本,无法转成可执行脚本
《大天使之剑H5》在登陆微信小游戏前,整个项目大小约有400多M,光JS代码部分就有大约10M。除逻辑代码的其它资源(图片、音效、配置等),可以在游戏运行时进行加载,不用在开发工具里上传,但约10M的JS代码部分必须全部上传。因此,《大天使之剑H5》想登陆微信小游戏,必须缩小JS代码的大小。
现有压缩工具UglifyJS部分功能简介
LayaBox引擎里将项目的AS3部分生成JS时会进行一定的优化,这个功能应该是基于UglifyJS来实现的。其优化内容主要有:
1.去掉代码中无效的空白字符
2.去掉代码中的注释
如图所示:
3.把方法中局部变量名缩短
如图所示:
4.代码格式优化 (把代码改为更省字符的写法)
如图所示:
5.压缩属性名 (默认不开启)
我们先来看看这个例子,这个是一个类,在工具默认不开启压缩属性名称时,工具就只会压例子里橙色的两处X和Y,因为这个是参数,也就是刚才说的方法里定义的变量,this.x,this.y这都是不压的,因为这个是属性名。如果类名Point,方法名setTo,属性名X,Y压了,那其他使用的地方就要根着一起改,如果代码里有用到反射来调用的,那就调用不到了。所以压缩这些名称是有风险的,这也就是工具默认不压的原因。那这个功能不就废了?不会,工具还提供了很多参数让你可以设置不压缩的名称的列表,还允许你定义压缩的名称的正则表达式等等,其实还是可以使用的,只是还是要先整出一份针对自己项目的名称数据出来,整理出来的不压缩名称集要和代码同步进行维护,这样难度会比较大,所以《大天使之剑H5》项目并没有使用这个功能。
小结:
《大天使之剑H5》项目现有的AS3代码代码在Layabox生成JS代码时,已经默认进行了上述前四点优化:
去掉代码中的无效的空白字符
去掉代码中的注释
方法中的局部变量名缩短
代码格式优化
但生成的JS代码有10M左右,还没有达到微信小游戏的要求,因此,为了缩小代码量,我们需要对我们的AS3代码再做一些优化,从而减少代码量。
减少程序代码
缩小代码量,最直接的方式就是减少代码里的字符,这部分所作的优化,是在我们项目的AS3代码部分所做的优化,这些优化包括以下几点:
1、将界面布局的数据改为从外部加载
Layabox的UI编辑器编辑后,会生成对应的UI类文件,其内容如图:
这里面主要内容是UI的布局数据,不用涉及到逻辑,可提取出来。做为文本文件保存,在其对应的界面初始化时再加载,在Layabox中,我们可以通过修改UI模式来做调整:
我们可以随意创建一个UI来做测试,如图所示:
我们可以看到,新建一个TestPageUI界面,使用内嵌模式生成的TestPageUI.as文件共有3283字节,而使用分离模式,生成的文件只有579字节。图中右边绿色部分表示的是减掉的部分代码,为我们缩小约80%左右的UI布局相关代码。
而在《大天使之剑H5》中,UI布局文件目前有931个,使用这种方式帮我们减少了1.8M的代码。
2、将类里不使用的导入删除
我们在开发时,手误import进入的一些项目并未使用到的类,需要将这些import删除。
如:import Sprite3D 类,2D游戏用不上3D相关的东西,无需导入
3、将方法里的this用局部变量代替
当我们的AS3代码转成JS后,类中的属性名在方法中的访问形式,是会在其前面加上this. 这里的this我们是否能减少呢?如下图所示:
上面的方法里有若干个this。如果把this用一个局部分变量来代替,那就是下面的方法这样。这里的局部变量用的是一个字符的变量,因为最后我们项目会用UglifyJS来压,所有方法内定义的变量,只要不超过54个,都会是单字符的变量。我们看优化前,一共是有四个this,他们占用16个字符。优化后,四个this变成了四个n,是4个字符,还多出一个赋值语句,这个语句包括中间的空格,包手后边的分号,一共是11个字符,加上四个n就是15个字符,比优化前少了一个字符。如果这个方法里我再加一个this,那优化前的代码,就要增加4个字符,而优化后的代码只需要增加1个字符,所以方法里的this越多,能减少的大小也越多。因此:
总结来说就是只要方法里的this关键字多于3个,就能省字符数量。而且this越多,省得也就越多。我在编译好的JS代码里搜索,一共是有近18号个this,这个就可以省很多了。但这个优化要注意,每个function都是一个作用域,每个作用域里的this指代都是不一样的,所以每个不同的作用域里的this要分别进行计算,也就是说,方法里如果有一个函数,那在计算方法里的this数量时,不应该计算函数里出现的this。第二个,是有一些方法,已经写了内部的变量赋值是this的,那就可以利用这个已经存在的变量,可以进一步减少字符。这个优化最终省了0.3M。这个优化优化的不仅仅是代码的大小,因为在JS里,局部变量的调用效率是比this要高的,所以这还可以加快游戏的运行效率。
4、压缩包名、类名、方法名、属性名
这一步做的事,是把UglifyJS默认不压的名称,我们用我们的方式把他给压了
① 相同的名称压为相同的短名称,把代码里出现的相同的名称,压为相同的短名称
② obj.abc 与 obj["abc"] 区别处理:
默认压缩规则:obj.abc 写法的属性名会被压缩,obj[“abc”] 写法的字符串部分不会被压缩。
想到这种方式,主要是因为UglifyJS也考虑到有些属性名压缩后,可能会引起某些属性访问不到,UglifyJS的做法是提供个不压的属性名的配置列表,但是这仅仅是个配置列表,我们通过这个列表无法定位到代码里有用到这些属性名的地方,有一定的局限性,因此,通过obj.abc 与 obj["abc"] 区别处理,我们可以在写代码的时候就用不同的写法告诉编译器,这里的属性名是否要压。
有人会有疑问,用obj[“abc”]的写法,会比obj.abc的写法多了三个字符。不用担心,因为在最后用UglifyJS压缩的时候,会将[]语法转成.语法的。
③ 自定义标签 /*[ZIP-JSON]*/
为了不破坏程序员的编程习惯,我们在不得不用字符串的形式去
访问属性时,想到了下面的解决方案:在字符串前加上一个/*[ZIP-JSON]*/
如:
我们常用的缓动类的用法中,上图的”x”和”y”是属性名,我们默认情况下字符串是不会被压缩的。此时我们可以在代码中加上/*[ZIP-JSON]*/标签,如:
这样,”x””y”就会被压缩成对应的名字了。
通过这些处理,我们的代码的写法就会有以下几种形式:
形式1:label 这个属性名,并不会被压缩,访问时也用它原名访问
形式2:label这个属性名在定义时就被压缩了,可以通过也会被压缩的.语法去访问
形式3:label这个属性名在定义和访问时都有被压缩
当然,/*[ZIP-JSON]*/做为注释块,在最后AS3被转成JS时,UglifyJS会帮我们把注释块给清除掉的,不用担心加了注释块反而代码会大的问题。
④ 特别处理
诸如 hasOwnProperty、propertyIsEnumerable 等方法,以及Layabox 里的 __JS__ 方法
方法里传入的字符串,其实是属性名称。因为默认属性名称是会被压缩的,而字符串是不会被压缩的,所以对这些方法中名字,我们默认进行压缩。但要压缩成什么样的名字呢?
上面我们讲的,是哪些名称要压,压的时候要注意的一些点,那最终这些名称,要压成怎么样呢?当然是压到越小越好,那最小是多少呢?一个字符是最好的。我们先看看要做名称,受哪些限制。名称是可以由字母组成的,字母是区分大小写的,还可以使用数字,还有下划线,还有一个比较不常用的$符号,要注意的是,名称的首字符不能是数字。
如果我们把名称全用单个字符,可以有多少个名称呢?26个小写字母,26个大写字母,10个数字不有用,加两个符号,就是54个。那双字符的名称呢,就有3456个,三个字符就是22万个。当然这里能用的还会少几个,为什么呢?因为比如像as,is,if,for这样的名称,也是两个字符三个字符,但他们是关键字,名称不能和关键字重名,不过这样的关键字也不多,不多于10个。三个字符可以有22万个名称,那是否够我们使用了呢?
上图是《大天使之剑H5》中所用到名称字数的分布图,一共有4万个名称,那两个字符的3千多个肯定是不够的,三个字符的22万个就完全可以满足了。而且我们看看这些名称的长度分别是多少,可以从表里看到,95%以上的名称是大于三个字符的,那可以优化的空间就比较大了。最终我们项目把名称都压缩完后,一共减少了1.9M。在压缩名称这里,大部分工作都是用编辑工具去完成的,有一部分是要修改源代码的,也写了一个工具去处理,尽量做到用工具去完成,不然要手动去修改,工作量会变得超大。
上述的五点对《大天使之剑H5》优化过后,结果如图所示:
《大天使之剑H5》的代码由约10M减小到约5.1M的大小
⑤ 一些还未在《大天使之剑H5》中做的可取优化
静态常量编译为JS后是把值写在使用的地方,这不一定是最优的
方法里使用的属性赋值给局部变量再使用
使用(param)=>{}代替function(param){}
某类只有一个子类时可减少继承链
包结构可以减化
四.使用分包
在上述的优化后,《大天使之剑H5》的主代码还有5.1M,任然需要对这5.1M进行拆分,这5.1M中,有游戏引擎的部分占了0.7M,其他小文件占了0.2M,剩余的主程序还有4.2M,剩余的4.2M可以通过分包处理。怎样分包我们可以在腾讯和layabox的官网上找到详细的教程 。
关于在layabox下是如何分包的,在这里简单说一下:
在项目的根目录下,创建一个module.def文件,这是一个文本文件,里边的内容如下,就可以在编译后,生成主文件的JS和模块.js两个文件。如果要分为多个模块的,就把这个结构写多个,都定义好模块名称和模块对应的代码所在的文件夹就可以了。
看起来是不是很简单?但我们随意的指定一个文件夹下的代码被编译为一个模块独立出去后,在运行时,就会出错上图红色部分的一个报错。
出现这个报错的原因是主文件会先运行,主文件里引用了模块里的XXX,而运行到这里的时候,模块还没有被加载,所以xxx没有被定义,所以报错了。
所以,要做好分模块前,就需要对项目进行解偶。要解偶的话,那就得知道,我们分到模块里的是什么功能,这个功能里如果需要和主程序进行交互,就需要设计相应的中转机制来进行解偶。
如果项目是新项目,我们可以在一开始设计游戏的时候就做好这部分内容,在功能进行开发中,会知道这个功能是要分出去的模块,要以怎么样的开发规则进行开发,就可以做到解偶进而做到分模块。
但我们的游戏已经上线快一年了,如果现在才加入这样的机制相当于我们要对需要放到模块里的功能进行重构,这样做工作量大,而且功能还要重新测试,开发周期开,还容易出BUG。后来我想了一个不需要解偶也可能分模块的办法。
我在说我们办法前,我要说明一点,我这个办法只是为了解决在小游戏里做到分包小于4M而做的,与分模块的设计思路是不太一样的。分模块的目的是什么呢?是把还没有使用到的功能放到模块中去,需要使用到的时候,再去加载对应的模块。而我的做法,是需要在进游戏前,需要把所有模块都加载进来,无论模块的功能是否需要,也不管模块里到底是什么功能。
为了说清楚这点,我们先来看看JS的类。JS的类定义在书写的时候,是否有先后顺序?看看这段代码,这里定义了一个父类,然后再定义了一个子类。这里我们是否能先写定义一个子类,再写定义一个父类吗?大家注意下子类的定义里,是需要将父类的定义传入的,如果先写子类的定义,那传入的父类定义就是一个undefined,里边在调到到父类定义里的属性时,就会报错。所以父类必须要写在子类前边。换成分模块的情况下是怎么样呢?
假设我们现在有两个文件,先被加载的叫模块A,后被加载的叫模块B。模块A里有一个子类的定义,在模块B里有其他类的定义,也包括这个模块A里的子类的父类的定义。在模块A被加载完成后,运行到子类的定义时,就调用到了他的父类,因为模块B还未加载,所以必然报错了。这里我们要怎么避免报错呢?很简单,把父类的定义,也放到模块A里,那就不会报错了。如果父类还有父类,而且也在模块B里的,那记得也要把他的父类也拿到模块A里。
具体我们是怎么操作把父类也放到模块A里的呢?我们只需要在调用Laya的编译器前,把父类的as文件考到模块A的文件夹里就可以了。父类里的包名什么的,都不需要做修改。要知道包名在AS里虽然是和文件存放的路径相匹配的,但在用laya编译时,是不检测包名是否和路径匹配的,最终生成到JS里的,是文件里写的包名,路径只做为是放到哪个模块的依据。
刚才我们讲的是父类是在另一个模块的情况下引起的报错。除了这个,还有没有其他情况呢?有的,比如说我们在刚才的模块A里的类,在未解偶的逻辑里,是肯定有调用到模块B的类。不过在初始化时,应该不会运行到业务逻辑里,那为什么会报错呢?
我们来看看模块A里的代码。模块A里的头几行一般是长这个样子的,第二行,是将Laya引擎里的一些公共方法定义了短名称的变量,方便在逻辑里调用。第三行开始,就是把这个模块里引用到的类,都用类的名称做变量名赋值,这样就方便在使用的时候,不需要写包括包名的类名称。也就是我们直接写在AS里的代码,不用做太多修改就可以在变成可运行的JS。
要注意到,这几行代码,是在这个JS文件初始化的时候就会被运行的。注意看第四行,我们有一个类,假设这个类叫ClassName,这个类是定义在模块B里的,那这句赋值语句就会因为模块B还未加载而找不到ClassName的定义,然后报错。而且这个类之所以出现在这里,就是因为在该模块的某个类里使用了它。
这里我们就明白了,写在类的方法里的代码,在初始化的时候是不会被运行的,所以写了模块B里定义的类也不会在初始化时报错,被导入的类会被写到模块的最开头,会在初始化时运行到就会报错。那我们这么处理,所有模块A里的类,如果import的类是模块B的类,那就把这个import删除掉。并且把所有使用这个类的地方,都写成用这个函数调用的字符串的包括包名的类名。
好像这样改,需要改的地方会比较多,而且生成的代码里,也会有多处长名称,我改成了这样,在类里加一个静态的变量,让他等于这个函数,那代码里就不用修改,使用到这个类名的地方,其实调用的是这个定义的静态变量。而且编译为JS后,静态变量的定义会变成get函数来得到这个值也就是在使用的地方才会调用,而不是初始化的时候。这样就解决了模块A的代码里调用到模块B的类的引起在初始化的时候报错的问题。
做好刚才的两个地方就完成了吗?我们再回想一下两个情况,都是模块A里的类,如果引用了模块B里的类,那就想办法把他的引用去掉,让他在首次运行时才调用。也就是说,在编译为JS的时间,模块A里的类是被当成没有引用模块B里的那个类了,那如果模块B里的那个类,假设叫SimgleClass,只有唯一的一个引用就是模块A里的类引用了,现在把模块A里的引用去掉了,那SimgleClass就没有类引用到它了,也就是编译的时候,会把这个类不编译到JS里去。那运行的时候就会因为找不到定义而报错。所以要在SimageClass里加上强制编译的标签,这个是由LayaBox提供的标签,当有这个标签时,这个类就算没有引用,也会被编译到JS里去。
最终的结果,如图所示:
这4.2M的主程序文件,就被拆分为了一个1.2M和一个3M,小的那个和引擎代码还有其他一堆小文件一起打包成一个包,共2.1M,3M的那个文件就一个包。在程序运行的时候,会在进入游戏的时候,先加载2.1M的包,完成后会立即加载3M的包。两个包都加载完成后,才会进入游戏。
网友评论