プログラミング
Atari 2600の名作ゲームへのトリビュート
A tribute to one of the best games on the Atari 2600 (plicerin.github.io)
要約
この記事は、Atari 2600の名作シューティングゲーム「River Raid」のJavaScriptによる移植版について解説しています。オリジナルのROMコードを1命令ずつJavaScriptに書き起こし、オリジナルの動作と完全に一致することを確認した移植の技術的な詳細や、ゲームの仕組み、リバー生成のアルゴリズムなどが説明されています。
全文翻訳
River Raidをプレイ
プレイを押してから、上またはファイアを押して離陸
フルスクリーンを終了
▲ ◀ ▶ ▼ ファイア
←→ ステアリング
↑↓ スピード
スペース ファイア
Enter ゲームリセット
ゲームリセット
一時停止
ミュート
フルスクリーン
遊び方
川を上り、邪魔なものを撃ち落とせ。
燃料は常に減っていく。ゲージがEに達する前に、デポの上を飛んでタンクを満タンにせよ。
岸、橋、または水上のものに触れるとジェットは墜落する。
操作方法
ステアリング
←→ または AD
スピードアップ
↑ または W
スローダウン
↓ または S
ファイア
スペース / Z
ゲームリセット
Enter
一時停止
M
ミュート
P
ゲームパッドで
ジョイスティックまたはDパッド
ファイア
A ・ B ・ X ・ Y
ゲームリセット
スタート
一時停止
バック
Atariのジョイスティックにはボタンが1つと8方向があり、すべてのフェイスボタンが発射に使用される。
サウンドは、最初のクリックまたはキー入力後に開始される。これはブラウザのルールであり、カートリッジのルールではない。
燃料
川の下にあるゲージはEからFまである。飛んでいる間、見た目よりも速くフレームごとに減少し、4分の1を下回ると警告音が鳴り始める。
デポの上を飛ぶと、そこにいる間タンクが補充される。
デポを撃つと80点になるが、燃料はなくなる。
ライフ
3機のジェットで開始し、9機まで10,000点ごとに1機増える。
墜落後、カートリッジはそのセクションの開始地点に巻き戻され、正確に再生される。なぜなら、カートリッジはその乱数をそこに保存していたからだ。
川は決して保存されない。
ゲーム全体は4,096バイトのカートリッジに収まるため、川の32行ごとのブロックは、同じシード値$A814から始まる16ビット乱数ジェネレーターから、ゲームごとに同じように構築され、表示される直前に生成される。
だから川は終わることがなく、プレイするたびに同じ川になるのだ。
川
32ブロックで1セクションとなり、各セクションは道路と橋で終わる。
奇数セクションはまっすぐ走り、偶数セクションは曲がりくねり、島を囲むように分岐する。
川の上流には敵が多く、デポは少なくなる。
タンカー
30
ランダムに動き出し、岸に触れると反転してパトロールする。
船が通れないほど川が狭い場所では、代わりにヘリコプターが配置される。
ヘリコプター
60
ローターは、フレームごとに2つの形状が入れ替わる。
タンカーと同様にパトロールする。
ジェット
100
セクション3から出現する。
画面全体を停止せずに横切り、端でラップアラウンドする。
燃料デポ
80
上に乗っている間、燃料を補給するか、撃つとスコアになる。
橋
500
撃つと次のセクションが開く。
橋に突っ込むとライフを失う。
家
0
岸や島にある風景で、川にあっても価値のない唯一のもの。
ROMから構築
これはエミュレーターではない。
カートリッジの各ルーチンは、同じ128バイトのRAMを同じアドレスで操作しながら、6502命令を1つずつJavaScriptで書き直された。
それを証明するために、小さな6502コアが移植版の隣で実際のROMを実行し、各フレームをバイトごとに比較している。
プレイされた45,000フレームでカートリッジとの差は0
チェックされた300,000の川生成状態、セクション1から48
オープニングフレームの31,840ピクセルは、Stellaのキャプチャと同一
カートリッジ全体で4,096バイト、コードとグラフィック
ROMから読み込まれた。
コードには、マニュアルには決して記載されていないことがいくつか含まれている。
メモリにスコアはない。
6桁は数字のグラフィックへのポインタであり、ポイントはポインタに追加される。
衝突は、TIAのハードウェアラッチからのみ発生し、川のブロックごとに1回読み取られる。
衝突計算は一切行われない。
船、ヘリコプター、ジェットに衝突しても、墜落する際にスコアが加算される。
家に触れると、燃料デポに触れるのと同じコードが実行される。
新しいブロックがスクロールインしたばかりのとき、一番上の部分での衝突は、存在しない7番目のブロックの下に記録され、フラグが最初のオブジェクトの位置バイトに着地する。
移植版は、それらすべてを保持している。なぜなら、それがゲームだからだ。
開発者ページ
Harness: ライブスコア、燃料、ライフ、RAMの読み出しを備えた移植版
Inspector: より古いROM表示モデルとそのメモリビュー
ROMとの照合: 6502オラクルと比較スクリプト