美文网首页H5学习笔记让前端飞我爱编程
TypeScript复制Google的T-Rex游戏

TypeScript复制Google的T-Rex游戏

作者: 柳正来 | 来源:发表于2017-12-28 14:52 被阅读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的代码转换就到这里. 之后我会更新我通过阅读代码获得的收获.

    相关文章

      网友评论

        本文标题:TypeScript复制Google的T-Rex游戏

        本文链接:https://www.haomeiwen.com/subject/fhxvgxtx.html