H5学习笔记让前端飞我爱编程

TypeScript复制Google的T-Rex游戏

2017-12-28  本文已影响27人  柳正来

本文对应的代码库见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的代码转换就到这里. 之后我会更新我通过阅读代码获得的收获.

上一篇下一篇

猜你喜欢

热点阅读