TypeScript復(fù)制Google的T-Rex游戲

本文對(duì)應(yīng)的代碼庫(kù)見lzl124631x/t-rex, 如果喜歡歡迎給顆星星.


Google瀏覽器有個(gè)廣為人知的小彩蛋, 就是當(dāng)你處于離線狀態(tài)的時(shí)候, 會(huì)有一個(gè)小恐龍. 其實(shí)這是一個(gè)小游戲, 按一下空格這個(gè)恐龍就會(huì)開始跑動(dòng), 要躲避仙人掌和翼龍.

T-Rex

這只龍是霸王龍, 英文名為Tyrannosaurus (暴龍) rex(王), 簡(jiǎn)稱T-Rex.

想要玩這個(gè)游戲, 不必?cái)嗟糇约旱木W(wǎng)絡(luò), 隨時(shí)訪問(wèn)chrome://dino/都可以玩!

一直對(duì)動(dòng)手寫一些小游戲比較感興趣. 于是就開始扒T-Rex的代碼.

扒代碼

原代碼見chromium, 或chromium git (這個(gè)地址方便打包下載).

另外, 網(wǎng)上已經(jīng)有一些t-rex扒下來(lái)的版本, 還有人做了排行榜什么的. 如https://chromedino.com/, http://apps.thecodepost.org/trex/trex.html. 這些網(wǎng)站大大加速了扒代碼的速度.

最終成果是extraction.html, 一個(gè)獨(dú)立的HTML文件, mp3/png/js/css都被一股腦塞在這個(gè)HTML中了, 只有105KB! 獨(dú)立的HTML意味著你不需要服務(wù)器的支持, 只要打開這個(gè)文件, 就可以玩兒了.

轉(zhuǎn)換成TypeScript

原本想自己按照游戲的思路, 自己用TypeScript實(shí)現(xiàn)一下.

但是試了一下發(fā)現(xiàn)那樣太浪費(fèi)時(shí)間, 因?yàn)楹芏鄸|西, 包括Sprite的尺寸, 其實(shí)別人都已經(jīng)算好了, 不如直接挪過(guò)來(lái)用.

慢慢地, 覺(jué)得還是把原來(lái)的實(shí)現(xiàn)重寫成TypeScript然后再學(xué)習(xí)比較快. 于是就開始了轉(zhuǎn)換過(guò)程.

這個(gè)轉(zhuǎn)換過(guò)程比較枯燥, 但是也能學(xué)到一點(diǎn)點(diǎn)東西. 甚至還借助TypeScript發(fā)現(xiàn)了源代碼的一些小瑕疵.

TypeScript的Singleton

參考: How to define Singleton in TypeScript

參考了其中@Alex的回答, 因?yàn)檫@個(gè)比較類似原來(lái)的實(shí)現(xiàn).

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

想要定義一個(gè)HashMap接口來(lái)對(duì)應(yīng)原JS文件中大量存在的字典結(jié)構(gòu). 可以采用如下實(shí)現(xiàn):

export interface IHashMap<T> {
    [key: string]: T;
}

TypeScript no index signature

參考: Index Signatures

源代碼中, 有些字典結(jié)構(gòu)的值可能是number也可能是string, 針對(duì)這種情況不好用IHashMap. 即使用IHashMap<number | string>也不方便, 因?yàn)檫@樣索引出來(lái)的東西的類型是number | string, 傳參的時(shí)候還是需要具體指定為number或者string.

所以定義了一個(gè)接口, 如下:

interface RunnerConfig {
  ACCELERATION: number,
  // Many other fields
  RESOURCE_TEMPLATE_ID: string
}

然而并沒(méi)有那么順利, TypeScript報(bào)錯(cuò)說(shuō)no index signature. 因?yàn)榇a中嘗試用config[key]的形式去訪問(wèn)屬性. 根據(jù)參考, 只需要加一行[index: string]: string | number;, 其實(shí)跟上面的IHashMap定義可檢索屬性是一個(gè)知識(shí)點(diǎn).

interface RunnerConfig {
  ACCELERATION: number,
  // Many other fields
  RESOURCE_TEMPLATE_ID: string
  [index: string]: string | number;
}

結(jié)語(yǔ)

TypeScript的代碼轉(zhuǎn)換就到這里. 之后我會(huì)更新我通過(guò)閱讀代碼獲得的收獲.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 背景 一年多以前我在知乎上答了有關(guān)LeetCode的問(wèn)題, 分享了一些自己做題目的經(jīng)驗(yàn)。 張土汪:刷leetcod...
    土汪閱讀 12,769評(píng)論 0 33
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,923評(píng)論 18 139
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程,因...
    小菜c閱讀 6,523評(píng)論 0 17
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 31,765評(píng)論 18 399
  • 網(wǎng)絡(luò)模型OSI(Open System Interconnection 開放系統(tǒng)互連)參考模型物理層主要定義物理設(shè)...
    灰氣球閱讀 948評(píng)論 0 0