xDroid's Blog

双曲平面贪吃蛇赛高!

通往新世界的传送门

从c++移植到js上真是太蛋疼了。

最近闲得蛋疼并没有,为了练练手就打算把原来用OpenGL实现的贪吃蛇移植到js+canvas上面去。另一个方面的原因是许多同学抱怨原来的代码需要在linux环境下编译,实在太麻烦了。

既然c++和js在语法上非常相似,移植起来应该不是很困难flag。大致思路是按照原来项目中每一个文件“翻译”成对应的js文件,再把所有的OpenGL接口换成canvas调用。

complex.cpp下手,就遇到了第一个问题:
js里面没有类。

没有类也就罢了,好歹还有替代的解决方案(Javascript定义类(class)的三种方法 - 阮一峰的网络日志),接着来了第二个问题:
不能重载运算符。
窝勒个去把运算翻译成成员函数真是够呛的。比如这个运算式:

return transform(th+((e+t.c.conj()*c)/(1+t.c*c.conj()*e)).arg(),(e*t.c+c)/(e+t.c.conj()*c));

变成了这样:

return transform(this.th+((e.addition(a.com.conj().production(this.com))).division((complex(1.0).addition(a.com.production(this.com.conj().production(e)))))).arg(),((e.production(a.com)).addition(this.com)).division((e.addition(a.com.conj().production(this.com)))));

括号有没有匹配也只有编辑器知道了。
这还没完,遇到浮点数加上一个复数,本来在c++里面已经重载过了,翻译的时候很容易忽略掉,结果各种undefined。正确做法是先用构造器将浮点数转为复数,再调用addition成员方法。

第三个麻烦是,js里面没有“重载”的概念,结果c++里面一堆特性都用不上了,只好默默地if (arguments.length === 0)……

剩下什么全局变量满天飞也是意料之中的事情。

Canvas的2d上下文对象虽然可以满足贪吃蛇这种游戏的要求,但是相对OpenGL来说还是欠缺了很多。不知道webGL上下文能不能提供更多的功能。