paint-brush
懐かしさを蘇らせる: HTML5 の Canvas API と JavaScript を使用してスネーク ゲームを再作成する@ssaurel
523 測定値
523 測定値

懐かしさを蘇らせる: HTML5 の Canvas API と JavaScript を使用してスネーク ゲームを再作成する

Sylvain Saurel8m2024/01/21
Read on Terminal Reader

長すぎる; 読むには

スネーク ゲームは、Nokia モバイルにおける 90 年代の偉大な古典の 1 つです。このチュートリアルでは、HTML5 で再作成する方法を示します。
featured image - 懐かしさを蘇らせる: HTML5 の Canvas API と JavaScript を使用してスネーク ゲームを再作成する
Sylvain Saurel HackerNoon profile picture
0-item
1-item

有名なSnake ゲームをプレイしたことがない場合は、手を挙げてください。


そうは言いますが、今日の新しい世代はこのゲームのことを聞いたことがないかもしれません。今日のコンピューターと Web が提供する可能性を考えると、少し時代遅れに思えるかもしれません。


それでも、スネーク ゲームは携帯電話所有者全員が膨大な時間を費やしてプレイするゲームだった時代がありました。はい、当時はスマートフォンのことではなく、電話だけについて話していました。


ことわざにあるように、当時は良い時代であり、Nokia はベンチマークでもあったモバイル デバイスを通じてゲームを普及させました。現在、ノキアによるモバイル世界とスネーク ゲームの支配の痕跡はほとんど残っていない。


このゲームを懐かしむ人のために、私もその一人であることを認めますが、このチュートリアルでは、このゲームを Web 用に再作成する方法を説明します。これを行うには、HTML5 の Canvas API と JavaScript を使用します。


また、JavaScript でクラスを使用する方法や、Web ゲームの効果的なゲーム ループを作成する方法を学ぶ機会でもあります。

スネーク ゲームの Web ページを作成する

まず、このチュートリアルで開発する Snake ゲームをプレイできるようにする Web ページを作成します。この Web ページには何の問題もないことがすぐにわかります。 2 つの div で、1 つはページ タイトル用、もう 1 つはヘビが移動する領域を表示するためのものです。


これに、これらの div に固定幅を適用して中央に配置するための小さなCSSを追加します。

Snakeクラスのデザイン

このチュートリアルの導入部分で説明したように、専用の Snake クラスを使用してゲームをモデル化します。これにより、JavaScript でクラスを操作する方法を発見することもできます。


私たちのスネークには次の特性があります。

  • bwbh はそれぞれボードの幅と高さを表します。
  • nbxnby は、ボードで使用可能なセルの数を表します。
  • eltwelth は、スネーク要素の幅と高さのサイズを表します。
  • dirxdiryはヘビの変位ベクトルを表します。
  • marginxmarginy は、プレイヤーが各スネーク要素間の境界を確認できるように、スネーク要素の幅と高さに小さなマージンを追加します。
  • keyupkeydownkeyleftkeyright は、特定の瞬間の移動矢印の状態を保存します。
  • startftps は、ゲームの開始時にヘビを動かすのに必要な 1 秒あたりのフレーム数を保存します。


コンストラクターの最後で、ゲームの開始時にスネークを初期化するために init メソッドが呼び出されます。新しいゲームを開始する場合は、この init メソッドを再度呼び出すだけです。


これにより、Snake クラスの次のコードが得られます。

init メソッドでは、ヘビの頭へのポインタや尾へのポインタなど、他のスネーク プロパティを定義できます。要素配列には、特定の時点でのスネークのすべての要素が格納されます。 Points プロパティは現在のゲームのポイントを保存するために使用され、level プロパティはゲームの fps を上げるために蓄積されるポイント数を定義するために使用されます。 fps の数値が高いほど、ヘビの動きが速くなります。


fps プロパティは 1 秒あたりのフレーム数を表すため、1 秒 (または 1,000 ミリ秒) を目的の fps 数で除算した結果を値とする fpsinterval プロパティが必要です。

スネークゲームの原理

スネーク ゲームの原理はシンプルです。ボード上に表示されるリンゴを最大数食べるように、4 つの方向の矢印を使用してヘビを誘導する必要があります。リンゴを食べるたびに、ヘビは要素が 1 ずつ成長します。ヘビが成長するにつれて、自分の尻尾に触れないようにするのが難しくなるでしょう。そうしないと負けとなり、スコアはゼロからやり直しとなります。もちろん、リンゴを食べるたびにポイントが入ります。


私たちが実装しようとしているスネークのバージョンは、ボードの端に触れても負けないバージョンであることを指摘しておく価値があります。そうすると反対側にひっくり返ってしまうだけです。 Snake ゲームの 2 番目のバージョンは、Nokia によってこの方法で実装されました。


ヘビはリンゴを食べなければならないので、ヘビの要素に直接リンゴを生成しないように注意しながら、このリンゴをランダムな方法でボード上に表示する必要があります。


これにより、Snake クラスに次のgeneratefood メソッドが得られます。

ヘビの画面上のレンダリング

Snake クラスは進んでおり、画面上にヘビをレンダリングするメソッドを作成する必要があります。また、特定の時点でのプレイヤーのポイント数を表示し、最後に食べられるリンゴを表示する必要もあります。リンゴの位置は、Snake クラスの food プロパティに保存されます。


画面上にスネークをレンダリングするために、HTML5 の Canvas API を使用しています。


この API の描画プリミティブを使用して、ヘビのさまざまな要素と食べるリンゴを表す四角形を描画します。プレイヤーが区別できるように、リンゴとヘビに異なる色を適用します。


これにより、Snake クラスの描画メソッドのコードは次のようになります。

ヘビを動かす

これで、画面に表示できるヘビができました。これは非常に問題ありませんが、ヘビの動きに対するサポートを追加する必要があります。上で説明したように、ヘビは座標ベクトル (dirx、diry) に沿って移動します。したがって、ここで定義する move メソッドを呼び出すたびに、ヘビは同じ量だけ移動します。


この移動方法では、ヘビの頭の座標が食べるリンゴの座標と一致していることを確認します。もしそうなら、ヘビはちょうどリンゴを食べたところです。プレーヤーはポイントを獲得しますが、さらに重要なのは、次の 4 つのアクションを実行する必要があることです。


  1. ヘビの要素に要素を追加します。この要素が新しい尾部になります。
  2. generatefood を呼び出して新しいリンゴを生成します。
  3. プレイヤーにポイントを追加します。
  4. プレイヤーがレベルを通過すると、表示される 1 秒あたりのフレーム数を更新して、スネークの動きを高速化します。


それでも、移動方法では、プレイヤーがヘビの要素に頭に触れてしまうという間違いを犯していないかを確認する必要があります。この場合、ゲームは負けとなり、最初からやり直します。これを行うには、上で示した Snake クラスの init メソッドを呼び出します。


次に、実際にヘビを移動して移動メソッドを完了する必要があります。これを行うには、ヘビの頭の座標に dirx と diry を追加します。これにより、追加する新しいヘッドが得られます。また、ヘビの移動は、毎回尾を削除して新しい頭を追加することでインテリジェントに行われることにも気づくでしょう。これにより、ヘビのすべての要素の位置を更新する必要がなくなります。


新しいヘッドを忘れずに更新して終了します。ちなみに、ヘビの頭がボードの境界を横切るとき、ヘビをボードの反対側に移動させることにも気づいたでしょう。これは幅と長さの両方に当てはまります。


これにより、次の move メソッドのコードが得られます。

スネーク ゲームのゲームループ

私たちのヘビは画面上に表示できます。スネークは、move メソッドを呼び出すことで移動できます。私たちに何が欠けているのでしょうか?


ゲームの GameLoop が実装されていません!


一定の間隔で move メソッドとdraw メソッドを呼び出すこの GameLoop がなければ、Snake は移動できません。以下では、JavaScript で GameLoop を適切な方法で実装する方法を示します。ゲームの Web ページのレンダリング スレッドをブロックしないように、適切と思われるときに呼び出すのはブラウザーに任せます。


これを行うには、標準の JavaScript オブジェクト ウィンドウの requestAnimationFrame メソッドを使用します。その後、ブラウザーは、Web ページが使用されるコンピューターまたはスマートフォンにサポートできる最大 fps を適応させます。


ゲームループ メソッド内で、ヘビを動かしたい fps 数からブラウザーでサポートされている fps 数を非相関化します。前に定義した fps 範囲内にある場合にのみ、move メソッドとdraw メソッドを呼び出します。


上下左右の 4 つの方向キーの状態に応じて、ヘビの移動ベクトルの座標を更新することが重要です。


最後に、GameLoop を呼び出して、最適な瞬間を選択するタスクをブラウザーに委任します。これにより、GameLoop 用の次のコードが得られます。

Snake とのユーザー インタラクションの処理

プレーヤーが押した方向キーに応じてスネークを移動できるようにするには、keydown イベントと keyup イベントを使用します。これらのイベントごとに、Snake クラスのメソッドを呼び出します。論理的には、これは keydown イベントの場合は pressdown、keyup イベントの場合は pressup になります。


プレイヤーがこれらのキーを使って何をしたかに応じて、リンクされた Snake クラスのプロパティの値を更新します。ご覧のとおり、ヘビの位置を直接更新することでゲームをブロックすることはありません。代わりに、定期的に呼び出されるゲームループ メソッドで状態を更新します。

さまざまな Snake コンポーネントの組み立て

このスネーク ゲームを完成させるには、さまざまな要素を組み立てる必要があります。 Canvas オブジェクトをその ID を介して取得します。次に、この Canvas にリンクされている 2D コンテキストを取得します。希望の寸法を適用します。 Snake オブジェクトを作成し、ボード上のセルの数などのさまざまな期待値をパラメーターとして渡します。


keydown イベントと keyup イベントのイベント リスナーを追加します。


最後に、あとは Snake のゲームループを 1 回呼び出してゲームを開始するだけです。これにより、Canvas API と地獄の HTML5/JavaScript Web カップルで作成された有名な Snake ゲームの次の完全なコードが得られます。

ヘビゲームの実際の様子

私たちのスネークは完成しました。Nokia がモバイル世界を圧倒的に支配したときのように、Web ブラウザでテストしてスネークの魔法が再び機能するかどうかを確認します。



この Snake ゲームから、いくつかの機能強化の可能性を想像することができます。たとえば、ヘビがリンゴを食べるたびに音を追加できます。 HTML5 の Web Storage API を使用して、プレーヤーのローカル ハイスコアを保存できます。このようにして、プレイヤーがハイスコアを超えたときに、お祝いのメッセージを表示できます。可能性は無限ですが、プログラミングの世界ではこれまでと同様、唯一の制限は想像力です。


YouTube でこのチュートリアルをご覧ください

このチュートリアルは、YouTube の SSaurel チャンネルでも視聴できます。


ここでも公開されています。