TypeScript复制Google的T-Rex游戏
本文对应的代码库见lzl124631x/t-rex, 如果喜欢欢迎给颗星星.
Google浏览器有个广为人知的小彩蛋, 就是当你处于离线状态的时候, 会有一个小恐龙. 其实这是一个小游戏, 按一下空格这个恐龙就会开始跑动, 要躲避仙人掌和翼龙.
T-Rex这只龙是霸王龙, 英文名为Tyrannosaurus (暴龙) rex(王), 简称T-Rex.
想要玩这个游戏, 不必断掉自己的网络, 随时访问chrome://dino/
都可以玩!
一直对动手写一些小游戏比较感兴趣. 于是就开始扒T-Rex的代码.
扒代码
原代码见chromium, 或chromium git (这个地址方便打包下载).
另外, 网上已经有一些t-rex扒下来的版本, 还有人做了排行榜什么的. 如https://chromedino.com/, http://apps.thecodepost.org/trex/trex.html. 这些网站大大加速了扒代码的速度.
最终成果是extraction.html, 一个独立的HTML文件, mp3/png/js/css都被一股脑塞在这个HTML中了, 只有105KB! 独立的HTML意味着你不需要服务器的支持, 只要打开这个文件, 就可以玩儿了.
转换成TypeScript
原本想自己按照游戏的思路, 自己用TypeScript实现一下.
但是试了一下发现那样太浪费时间, 因为很多东西, 包括Sprite的尺寸, 其实别人都已经算好了, 不如直接挪过来用.
慢慢地, 觉得还是把原来的实现重写成TypeScript然后再学习比较快. 于是就开始了转换过程.
这个转换过程比较枯燥, 但是也能学到一点点东西. 甚至还借助TypeScript发现了源代码的一些小瑕疵.
TypeScript的Singleton
参考: How to define Singleton in TypeScript
参考了其中@Alex的回答, 因为这个比较类似原来的实现.
class MyClass
{
private static _instance: MyClass;
private constructor()
{
//...
}
public static get Instance()
{
// Do you need arguments? Make it a regular method instead.
return this._instance || (this._instance = new this());
}
}
const myClassInstance = MyClass.Instance;
TypeScript Const Member
参考: How to implement class constants in typescript?
TypeScript的成员变量不支持const
修饰符, 需要使用static readonly
.
TypeScript HashMap Interface
参考: Typescript hashmap/dictionary interface
想要定义一个HashMap
接口来对应原JS文件中大量存在的字典结构. 可以采用如下实现:
export interface IHashMap<T> {
[key: string]: T;
}
TypeScript no index signature
参考: Index Signatures
源代码中, 有些字典结构的值可能是number
也可能是string
, 针对这种情况不好用IHashMap
. 即使用IHashMap<number | string>
也不方便, 因为这样索引出来的东西的类型是number | string
, 传参的时候还是需要具体指定为number
或者string
.
所以定义了一个接口, 如下:
interface RunnerConfig {
ACCELERATION: number,
// Many other fields
RESOURCE_TEMPLATE_ID: string
}
然而并没有那么顺利, TypeScript报错说no index signature
. 因为代码中尝试用config[key]
的形式去访问属性. 根据参考, 只需要加一行[index: string]: string | number;
, 其实跟上面的IHashMap
定义可检索属性是一个知识点.
interface RunnerConfig {
ACCELERATION: number,
// Many other fields
RESOURCE_TEMPLATE_ID: string
[index: string]: string | number;
}
结语
TypeScript的代码转换就到这里. 之后我会更新我通过阅读代码获得的收获.