モチベーション
TypeScriptに触れてみようと思い、何かしらいい題材が無いかと探していました。色々と検討した結果、Akashic Engine というゲームライブラリを利用するとすぐさまTypeScriptでコーディングが始められそうだったので、そちらを利用させていただきました。
AkashicにはJavaScriptで書かれたサンプルがいくつかあるのですが、その中からサンプルデモの1つをTypeScriptで写経してみました。
今回行った成果物のリポジトリはこちらです。
やってみた感想
TypeScriptの書き心地は非常によかったです。普段、仕事でCをゴリゴリ書いている身としては、ある程度の規模のプログラムになると、やはり型がある方がありがたいです。C#に似通ったところもあり、特段取っ掛かりにくいところは無かった気がします。
TypeScriptのドキュメントを読みながら探り探りやったので、「ふつうはこう書きます」ということができていないところもあると思います。お気づきの点があればコメントしていただけると幸いです。
はまったところ
Assetへのアクセス
Akashicではassetsには以下のようにアクセスします。例えばgirlという名前の画像ファイルの幅を取得したいなら
scene.assets["girl"].width
という感じです。しかし、TypeScriptの場合はキャストが必要でした。まあ、自分がチュートリアルの効果音とBGMの章にちゃんと説明があったのに、それを見落としただけなんですが…。
(scene.assets["girl"] as g.ImageAsset).width
課題
htmlへエクスポートしたファイルが壊れる
akashicではnpm run export-htmlでhtmlへのエクスポートができるのですが、どうもakashic-tileのバンドルがうまくいかず、exportされたhtmlを開くとモジュールが読み込めずにエラーとなってしまっています。
akashic install @akashic-extension/akashic-tile
この点は自分自身の最新のECMAScriptの仕様、TypeScriptの仕様の理解が浅すぎるのが原因の可能性もあるので、調査中。
追記 2018/02/16
単独動作の意味を勘違いしていたようです。サーバーに置くことが前提で、単独動作可能という事のようでした。
グローバル変数の扱いに悩む
今回はこんな感じに全てexportしたが、declareでアンビエント宣言するほうが良いのだろうか…。
export const game: g.Game = g.game;
// タイルの幅
export const TILE_WIDTH: number = 32;
// タイルの高さ
export const TILE_HEIGHT: number = 32;
// 重力加速度
export const GRAVITY_ACC: number = 500;
// ホップ初速度
export const HOPPING_SPD: number = -Math.sqrt((TILE_HEIGHT * 2) * 2 * GRAVITY_ACC);
// スクロール速度
export const SCROLL_SPD = (TILE_WIDTH * 2) / (Math.abs(HOPPING_SPD) / GRAVITY_ACC * 2);