本文對(duì)應(yīng)的代碼庫(kù)見lzl124631x/t-rex, 如果喜歡歡迎給顆星星.
Google瀏覽器有個(gè)廣為人知的小彩蛋, 就是當(dāng)你處于離線狀態(tài)的時(shí)候, 會(huì)有一個(gè)小恐龍. 其實(shí)這是一個(gè)小游戲, 按一下空格這個(gè)恐龍就會(huì)開始跑動(dòng), 要躲避仙人掌和翼龍.
這只龍是霸王龍, 英文名為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ò)閱讀代碼獲得的收獲.