👾

オンラインゲーム開発:五日間でオリジナルゲームをつくってみる - その3(まとめ)

2020/12/31に公開

この記事は「オンラインゲーム開発:五日間でオリジナルゲームをつくってみる - その2」の続編です。その1、その2は下記から閲覧できます。

https://zenn.dev/kenzan100/articles/ba3c7dbf4e642e
https://zenn.dev/kenzan100/articles/d64adeef878f2a

その2、までで基本的なオンラインブラウザゲームの動きを整えるところまで来ました。

その3(最終回)では、これをゲームとして「遊べるもの」に仕立て上げていきます。

Day4~5: 「遊べるもの」に向けての調整

ゲームアイデアメモをもう一度確認しましょう。

ゲームアイデアメモ

<登場人物>
キャラクター:2D空間で移動。
じゃんけんコイン:2D空間上に配置。

<ロジック>
キャラクターがコインを集めると集めたコインの総数に応じて状態変化(グー、チョキ、パーのいずれか)。
キャラクター同士がぶつかると、じゃんけん開始。キャラクターの状態に応じて、勝者が決まる。
勝者はそのまま2D空間に居残る。敗者は退出。

「遊べるもの」にするために重要なのは、ゲームの中でどうプレイが展開していくか、というイメージです。上記メモでロジック、という書いてある部分をきちんと精査し、それをゲームの中でのストーリーとして組み立てましょう。

1. ゲーム開始時、キャラクターは「グー」でスタート。そのときに接触しても「あいこ」なので何も起こらない。
2. キャラクターを動かしながら、じゃんけんコインを配置する。
3. 相手のキャラクターの状態を確認し、それに勝てるじゃんけんコインを取得することで、接触すれば勝てる状態をつくりだす。
4. 相手にぶつかって、勝敗を決する。
5. 勝ったら、他のプレイヤーに大して同じことを繰り返す(バトルロイヤル)。
6. 負けた方は、再接続することで再挑戦できる。

まずはこの遊びのストーリー(仮説)を検証することを目指します。


キャラクターの状態変化を可能にする

「キャラクターがじゃんけんを取得すると状態が変わる」という、アイデアの肝の部分をつくります。おそらく一番コードが多く登場する部分なので、細かく切り出してステップを解説します。

  1. サーバー側のデータに「状態」の値を持たせる(Rock:0, Paper:0, Scissor:0)。
  2. 配置したコインとキャラクターの位置情報から、衝突判定[1]を行う。
  3. 取得したコイン総数に応じて、キャラクターの状態を変化させる。
  4. 変化させた状態をユーザー側にも反映させる(現状では色の変化で表現)。

この部分のコミットはこちら


カーソルキーで動かしながら、コインを配置してキャラクターの色を変える

このままだと、配置したコインが自分のキャラクターに大して即座に衝突判定をしてしまっています。また、コイン総数を何かしらの方法で表現しないとルールが伝わりません。このあたりは本記事後半で調整します。

キャラクター同士の接触で勝敗を判定する

キャラクターとコインの接触判定を流用して、キャラクター同士の接触で「じゃんけん」が行われる土台をつくります。勝敗も、必要なデータモデルの一つとして考えます。

match = { loser: webSocketId, winner: webSocketId } 

こうすることで、勝敗が判定されたキャラクターのみに特別な表示をすることができます。

  1. 勝敗が決まった状態を表現する "match" データモデルを考える(上記)。
  2. プレイヤー同士の接触判定をサーバーサイドに記述する。
  3. 接触判定の際に、「じゃんけん」のルールに則り勝敗を決める。
  4. じゃんけんの結果生じた "match" データモデルをユーザー側に送信する。
  5. ユーザー側で受け取った勝敗の結果を出力する(現時点ではconsoleに表示)。


二つ画面を開いて、勝敗が決するとコンソールに文字が現れる

コミットはこちらから。

キャラクターとコインの画像を差し替える

ここまで来たらもう少しです!画像を差し替えて、じゃんけんというコンセプトを明らかにします。

  1. キャラクター画像とじゃんけんコイン画像を用意する。
  2. 今まで丸で表現していたキャラクター、コインを対応する画像に差し替える。
  3. 画像のx, y座標が中央に来るように調整する[2]
おまけ:コインとキャラクターの衝突判定を遅らせる

上で判明した「キャラクターとコインが即座に衝突し、コインのゲーム性が失われている」という部分を解決します。いくつか方法があると思いますが(弾として発射させる、キャラクターの前方に配置する)、ここでは衝突判定の遅延を試してみます。

(4.) コインに配置した時間(placedAt)データを追加し、当り判定が有効になるまでに1秒かかるようにする。

該当コミットはこちらから。

1ゲームのサイクルを完結させる

さて、すべてのゲーム要素は実装された段階です。最後に、ゲームのストーリー(上述)に基づき、ゲームの開始→終了→次のゲームの開始のサイクルを実装しましょう。

  1. じゃんけん時に表示する勝敗ディスプレイをHTMLで用意する。
  2. 今までコンソールに表示させていたYou win/You loseを、HTML contentとして表現する。
  3. 負けた方の後処理(WebSocket、画面描画の停止、サーバ側からのデータの削除)を行う。
  4. ゲームルールの解説を記述する。


勝った方のインタラクション


負けた方のインタラクション

コミットはこちらから。

おまけ:デプロイ先を決める

今回は、HerokuのNode.jsデプロイを使用しました。友達にオンラインゲームを紹介する分には、まったく問題ない選択だと思います。

まとめ

おめでとうございます!これで最初のオンラインゲーム構築が完了しました🙌
レポジトリを眺めて、ここまでの作業順番、作業単位を確認します。

コミットログを見ると、どうやってゲーム要素が追加されていったか、学ぶことができます。

最後に、次のゲームをつくるにあたって大切なポイントを紹介します。

つくったゲームの要素分解、パターン化を進める

このゲームのどこを変えれば他のゲームが比較的簡単につくれるか検討することで、ゲーム作りを習慣化させるハードルを下げることができます。

  • Canvas 2Dでの描画・操作
  • 衝突判定があるゲーム
  • 複数人同時対戦するゲーム

などのキーワードかつ自分が興味がある題材で、次に何がつくれるか考えると、捗ります。

同じようなゲームをつくっている解説記事を探す

MDNのサイトはウェブ技術に対する高水準かつ取り掛かりやすい解説が豊富です。関連技術で分からないことがあったら、"canvas MDN" や "setTransform MDN" などで検索すると、純度の低い記事に惑わされることが減ります。

ゲーム作りに関しては、"create io game from scratch" という検索ワードで出てきた下記記事に大変お世話になりました

https://victorzhou.com/blog/build-an-io-game-part-1/

ゲーム開発において、検索でヒットする記事の水準はまちまちです。運良くドンピシャの記事が見つかることもありますが、「前に進むためには最低限何を知らないといけないのか」キーワードを収集するくらいの感覚で関連記事を探しましょう。

数をこなす

面白いゲームをつくるというのは深遠な問いです。とにかく良質な練習、数をこなすことで、自分が満足いくもの+他の人に楽しんでもらえるものをつくれる技術、感覚を手に入れましょう。

デザイン、ゲームを遊んでもらえる仕掛けなど、関連分野を掘り下げていくとキリがありません。長続きさせるためには、「ゲームができました!」というよりも、「ゲームをつくる過程で学んだことはこれです」という発信方法 の方が良さそうです。

あとがき

気軽に書き始めたものが、そこそこのボリュームになりました。
私自身この経験をいかして、次のゲームをつくることに励みます。もし「こんなものつくりたいんだけど」などのリクエスト、質問があればぜひお寄せください。

Twitterは日本語, 英語の二アカウントです。

それではまた!

脚注
  1. 衝突判定に関してはこの記事が参考になります。 ↩︎

  2. 画像をキャンバスに描画するにあたって、Transformというコンセプトを使います。 ↩︎

Discussion