アルカノイドDXボールのリバースエンジニアリング、または古いゲームの新しい生活

コンピュータグラフィックスの非公式の日のすべての居住者を祝福します! この日は、古いゲームのオンライン版をどのように作成したかについてお話したいと思います。

おそらく、多くの人がゲームDX-Ballに精通しており、私は就学前の年齢でそれをプレイし、学校ではコンピューターサイエンスのレッスンを受けていました。 したがって、HTML5でそれを行うことに興味がありました。



仕事について少し

健全なコードを提供することはせず、それがどのように機能するかを説明しません。このゲームをどのように分析したかについてお話しますが、ゲーム自体についてのみ説明します。 オリジナルにできるだけ似たものにしたかったので、できるだけ多くのファイルを変更せず、変更したのはレコードのリストだけでした。それは「無限」になりました。
当初は、変化する要素のみを再描画すると考えられていましたが、これに関連して発生した多数のバグのために、フレームの完全な再描画のオプションを決定しました。 また、ゲームをフルスクリーンに拡大できるという事実にもかかわらず、その解像度は元のように常に640x480pxのままです。

ゲームの構成を分析しましょう:

* .pcxファイルは、ボーナスの説明を含む最初のスプラッシュスクリーンや、最終的な「ハイスコア」など、ゲームのラスター背景です。 私はそれらを分解し始めませんでしたが、ハブのすぐ上の興味深いシリーズの記事でPCXデバイスについて読むことができます
* .mds -MIDI音楽ファイル、 savexは* .mp3への変換を助けてくれました。
Default.bdsファイルには、50レベルすべてのブリックの場所に関する情報が保存されます
1つのレベルでは、20 2個のブリックがこのファイルにバイトで書き込まれます。
これから、20 2 ×50 = 20 KBが得られます
* .sbk-ラスターフォント、およびその他のグラフィックス(ブリック、ラケットなど)のファイル
このファイルがどのように配置されているかに関する情報を見つけることができなかったので、自分でそれを把握しなければなりませんでした。
このタイプのファイルには、次のようなものが含まれます。

Sysfont.sbkのグラフィック表示
画像はクリック可能です。
このファイルの構造はDefault.bdsよりもやや複雑で、文字を順番に記述し、
ファイルの最初の4バイトはファイルヘッダーであり、ファイルに含まれる文字(イメージ)の数に関する情報が含まれています。

スクリーンショットに示すように、ヘッダーが文字(イメージ)の連続した説明になった後、Sysfont.sbkファイルには94文字が含まれます。 最初の文字の幅と高さは、4番目と8番目のバイトで指定されます。 12番目のバイトは、 ASCIIテーブルの文字番号0x41 = Aです。0x00の場合、これは文字ではなく、何らかの画像です。 次に、17番目のバイトから数バイト、この場合は130 (13×10)が続きます-これはシンボルラスタです(図では緑で示されています)。 次に、これをすべて93回繰り返します(文字の幅を示すバイトから始まります)。

画像(文字)は下から上へ、左から右へ1バイト= 1ピクセルで描画されます。バイト値は色番号です。
私が理解しているように、ゲームは2つのカラーモードを使用します。1つ目はゲーム自体で使用され、2つ目はスプラッシュスクリーンでのみ使用されます。
ここに2つのスキームがあり、各色には2つの数字があり、上部は12月の色番号、下部は16進数です:


以下は、最初のスキームを使用したSysfont.sbkファイルの最初の3文字の例です。


ああ、両方のテーブルのゼロは透明色であり、224から231までの最初のスキームの色は動的です。つまり、各フレームはそのようなアニメーションを形成するために1色ずつシフトされます。 画像

ただし、ここで問題が発生します。qypgjなどの一部の文字は他の文字よりも低く、アポストロフィとその他の文字は高くする必要がありますが、すべての文字のサイズが異なるため、下に揃えられます。



この問題を解決するために、シンボルの後に続く特別なバイトがあります(最初のスクリーンショットでは青で下線が引かれています)。
gj文字の場合、このバイトは0xFD = 253です。 ^ 'の場合、このバイトは0x08 = 8です。これは、残りに対する正確な文字オフセットですが、なぜ負のオフセットではなく大きな数字があるのですか? 実際には、これは1バイトで128個の負の数と128個の正の数の負の数を書き込む形式です。 バイトが128未満の場合、そのバイトに触れず、それ以上の場合は、単純に256を減算します。
そして、素晴らしい結果が得られます。


ゲームを開始する前に、すべての画像(シンボル)はゲームと同じキャンバスに描かれ、写真として保存します。
つまり、 char[...].img.src = canvas.toDataURL("image/png");
putImageData()は drawImage()よりもはるかに遅いため、これが唯一のマイナスではありません。
putImageDataは、画像を上にオーバーレイしませんが、完全に置き換えます。
画像
ゲームを分析する過程で、元のゲームでは使用されない2つの秘密のボーナスを発見しました:-)

未使用のボーナス

ゲーム内のすべてのアニメーションはrequestAnimationFrameを使用して最適化されますが、デバイスが異なるとFPS値も異なります。 ボールがfpsに関係なく同じ速度で飛ぶように、ボールの速度に係数deltaを乗算しました。これは次の式で計算されましたdelta = 1000/fps/60; 、私のラップトップは毎秒約55フレームを描画することができましたが、定期的にハングし、一度に30フレーム以上を飲み込みました。秒なので、めったに更新されません。

前のゲームであるDoodle Jumpでは、ユーザーに任意のWebサイトにiframeを埋め込む機会を与えました。その結果、毎日7000人を超えるユーザーが、個人ブログからレコードスタジオまで、まったく異なるテーマのサードパーティサイトでこのゲームをプレイしました。
したがって、DXボールではこの機会を奪いません。さらに、ゲームはサイトに挿入されるように柔軟に構成されています。

すべてのように、あなたの意見で私が前に何も言わなかった場合、質問をして、私は間違いなく答えます。

ゲームへのリンク: DX-Ball.ru

PSゲームはまだ湿気があり、バグやハングが発生する可能性がありますので、コメントの欠点について書いていただければ幸いです。

Source: https://habr.com/ru/post/J147339/


All Articles