木匣子

Web/Game/Programming/Life etc.

在 OSX 中粘帖并替换文件

在现阶段游戏开发中有一个简单但烦琐的问题:每当美术资源需要替换时,需要一序列的搬运工作:

  1. 从版本控制工具更新美术资源(文件名[0.jpg, 1.jpg, 2.jpg…],美术组自已的命名方案)
  2. 在 working space 中找到相应的资源(文件名[a.jpg, b.jpg, c.jpg…],程序组的命名方案)
  3. 逐个替换:复制美术组的文件到 working space(command+c/command+v),复制程序组文件名(enter, command+c),删除程序组文件(command+backspace),修改新的资源文件为原有文件名(enter, command+v)…

如果数量不多的话,这样简单的操作还是可以容忍的。但是有时候懒惰的天性就会让大多数程序员对这种烦琐的操作忍无可忍。当然,解决方案也有很多:

  1. 提出一个合理的方案,使得美术组与程序组使用相同的命名规则。
  2. 使用更佳完善的商业游戏引擎提供的资源管理解决方案。
  3. 找一个方便替换文件的工具。

对于第一种方案,对开发组的阻碍是,美术组对英文命名不敏感;此外程序组并不知道美术组如何分割资源,随时会增删改资源,会增加沟通成本;

对于第二种方案,对于使用开源游戏引擎的小组,一时半会是没办法做出这样的改动的。

所以如果能使用第三种方案,那也是一个不错的 fallback 。

简单灵活的战利品掉落配置

在游戏中常常需要配置各种产出表,例如怪物的掉落、开启宝箱获得道具等等。简单的做法就是将这些功能分开开发,怪物用简单的概率来判断是否掉落物品,宝箱则根据预先设置好的权重来决定最终获得的道具。

但是需求总是处于变化的,如果策划想要让怪物能像宝箱那样根据权重来决定掉落,或者让宝箱像怪物那样由概率来获得道具(也可能什么也得不到)。

既然如此何不设计一种简单而灵活的,可以兼容这两种方案的配置呢?

只有 8 个指令的编程语言

如果一个编程语言只有8个指令,你一定会想:天啊,它能干嘛!

实际上,它是图灵完备所需的最少指令数。

在可计算性理论里,如果一系列操作数据的规则(如指令集、编程语言、细胞自动机)可以用来模拟单带图灵机,那么它是图灵完备的。

没错,这就是 Brainfuck 语言,它的八个指令是:> < + - . , [ ]

> 	右移指针
< 	左移指针
+ 	当前位置+1
- 	当前位置-1
. 	输出当前位置的ACSII码
, 	输入一个字符到当前位置
[ 	如果当前位置为0则跳转到匹配的]处
] 	跳转到匹配的[处

其应对的 C 语言指令是:

>  	++p;
<  	--p;
+  	++*p;
-  	--*p;
.  	putchar(*p);
,  	*p = getchar();
[  	while (*p) {
]  	}

用 Brainfuck 写出来的程序如同它的名字一样难懂,例如这个 hello world:

++++++++++[>+++++++>++++++++++>+++>+<<<<-]
>++.>+.+++++++..+++.>++.<<+++++++++++++++.
>.+++.------.--------.>+.>.

这段程序将会输出 Hello World!

我写了一段能输出233的程序:>+++++++[<+++++++>-]<+.+..

如果你有兴趣玩转 Brainfuck 的话,可以试试 Github 这一个基于 javascript 的 brainfuck-debug,可以在这里或者这里运行你的程序。

另外,在 http://codegolf.stackexchange.com 上面有很多大神用 brainfuck 实现各种不可思议的程序。

Cocos2d-js 实现弹窗背景虚化效果

美术组希望游戏中对话框的背景不是单调地叠一层半透明黑色,而是能有模糊的虚化效果。像是这个网页中第一个按钮按下去的样子。

显然,如果在要手游中实现这个效果,需要借助 OpenGL ES 2.0 Shader 来完成。

一个理想的方案是对当前场景设置一个 Shader 并在 Shader 中实现模糊效果,使得整个场景虚化。但是对话框也需要置于场景中,这会导致连对话框也虚化掉。

在 Cocos2d-js 中使用 Node.js 模块

Node.js

自 node.js 问世以来,javascript 在服务端的地位得到了许多人的认可。javascript 也不再是以往被认为的“前端的玩具语言”。在开发流程与规范上,node.js 提供了一套完整的方案,其中最基本的就是 CommonJS 规范。它将 javascript 划分为模块,模块之间通过 require 进行调用——这很像其它语言的 includeimport

此外,node.js 还提供了 npm 包管理工具(node package manager)。这使得全球的 node 开发者能够非常方便的共享和使用优秀的模块。可以说 node.js 的成长离不开这些优秀的开源社区。

模块化开发的好处非常多,最重要的就是使得测试驱动变得更加友好,不用再去处理复杂的依赖关系。mocha 是 node.js 环境下的一款非常好用的测试/行为驱动框架,能够结合各种第三方测试框架(只要它能抛出异常),我个人比较喜欢 should.js

于是我尝试使用 mocha + should.js 进行了一段时间的 BDD 开发,感觉非常好。很快就能把模块写好,并且得到一份不错的测试文档。

CCAnimate Loops

Cocos2d-x 提供了一组制作帧动画的工具:CCAnimationFrame + CCAnimation + CCAnimate.

CCAnimationFrame 是 CCSpriteFrame 的容器,但是增加了额外的帧信息,比如该帧的停留时间;

CCAnimation 是 CCAnimationFrame 的容器,包含的整个动画所需的帧序列。此外还有动画的循环次数,并且可以设置每帧之间的停留时间;

CCAnimate 是一个动作,它根据 CCAnimation 容器中的 CCAnimationFrame 以一定时间间隔切换 CCSprite 的外观(CCSpriteFrame)。并且从继承树看可以看到 CCAnimate -> CCActionInterval -> FiniteTimeAction -> CCAction 它是一个有限时长的动作。

可以把 CCAnimationFrame 想像成书中的页面,CCAnimation 想像成一本书,而 CCAnimate 就是翻书的动作。

露骨的骨骼动画透明效果

技术背景:cocos2d-x 游戏开发,骨骼动画

骨骼动画是现代游戏中十分常用的技术。相比关键帧动画,可以节约大量的数据资源,调整起来也比较容易。而且它可以借由CPU计算力实现补间与混合,从一个动作平滑的切换到另一个动作。

然而,由于骨骼动画是由多个不同的关节分层构建而成,这导致了一个问题。当一个人物由不透明渐变到透明的过程中,每个骨骼独立变化至半透明,这时每个骨骼将一览无余。虽不至于毛骨悚然,但着实不太美观。为了更清楚说明这个效果,可以参看这个演示左边的例子。

也不是所有游戏都会涉及到整个骨骼的透明度变化,但在清理地面上的死亡角色时的,这通常是较简单做法。所以为了让骨骼比较“好”地从屏幕上消失,我试图寻找一种可用的方法。

用 DragonBones for Cocos2d-x 实现帧动画

本文所使用的 Cocos2d-x 和 Cocos2d-html5 版本均为 2.2.2

美术组对骨骼动画提出了一个需求,希望能用 DragonBones 实现定格效果,而不是每帧都自动产生补间。

经过一翻搜索,我在这里找到了一个方法,只需要在骨骼的关键帧上使用 ^ 标签就可以取消骨骼动画的补间。实际上 DragonBones 的 wiki 上就有这么一行说明,被我略过了。