ゲームプログラミングっぽく絵を動かしてみる【絵が動くゲームを作ってみよう】
2020/04/12
新型コロナウイルス感染症、COVID-19拡大の影響で、 2020年4月8日からという形で、日本で東京都など7都府県に緊急事態宣言が出され外出自粛の要請などが行われましたね。
医療従事者の方やその関係者の方、社会生活に必要な業務をされている方、対応に当たられている方には本当に感謝しております。 一方で感染してしまった方も辛い思いをされているかと思いますが一日も早い回復をお祈りします。 私などはただ制限されただけでも気が滅入ってしまいますからね。 今は辛くてもいつかは解決するのは間違いないでしょうから、 今はインドアでできることをポジティブにやっていければと思います!
プログラミングブログ記事一覧
[PR]
ボールの位置を変更するプログラミングをしてみる
今回は以下の絵を用意しました。この中央のボールの位置を操作してみます。
waiting...
setBallX(0);
まずは、この実行ボタンを押してみてください。 緑色のボールが枠内の左端に移動すれば成功です!
色々な位置にボールを置いてみる
うまくいったら、今度は以下を試してみてください。
setBallX(96);
うまくいったら、さらに以下を試してください。
setBallX(192);
setBallX(288);
どうでしょう?ちょっとずつ右に動いているように見えませんか?
本記事の setBallX は、スクリーン上のボールのX座標を設定する関数です。 関数というのは、このように呼び出すことで、処理を実行してくれる、プログラムの専門用語です。
「マンガで感じる!本当の基礎から学ぶゲームプログラミング」のエピソード「関数」もご参照ください。
座標という用語は、中学の数学で習うと思います。 位置のことです。横がX、縦がY。 X座標は横の位置です。
ここでスクリーンは、左端が0、右端が320になっています。 また、設定する座標は、ボールの左端です。 ボールの幅が32ピクセルあるため、X座標に 288 を設定することで右端にくっつきます。
理解を深めるためにも、数値を変えて色々と「実行」してみてください。 なんとなく、右とか左に動いているように見えると思います。
ゲーム内で絵が動く仕組みはパラパラまんが
実はゲームの画面で絵が動いているのもこの仕組です。 一枚一枚の止まっている絵、すなわち静止画を、パラパラまんがのようにパラパラと切り替えて表示しているだけなのです。 それが高速に切り替わるので、滑らかに動いているように見えるのです。
プログラムは時系列に沿って順番に処理するのが特徴
プログラムは時系列にそって順番に処理を行うのが特徴的です。 プログラムを複数行書けば処理は上から下に順番に行われます。
つまり、上から順番に座標を変更しつつ処理を書いていけば、動いているように見えそうですよね! やってみましょう! こういうのは思いついたらやってみるのが大事です。
以下は左端0から96ずつずらしていって、最後は右端の288にするプログラムです。 「実行」してみてください。
waiting...
setBallX(0); setBallX(96); setBallX(192); setBallX(288);
…どうでしょう?うまく行きましたか? 左端から徐々に右端に…。 行かないですよね。 単に右端に行きましたよね。 なぜでしょう。
速すぎて見えない?
皆さんはディスプレイのリフレッシュレートというのをご存知でしょうか?
リフレッシュレート
リフレッシュレートとは、画面の更新頻度のことです。
昔のテレビは60Hz、最近は240Hzとかもありますね。 スマートフォンは60Hzが多くて、そろそろ90Hzが出てきているところでしょうか。
これは、例えば60Hzなら、1秒間に60回、画面を更新することを意味します。 言い換えれば60分の1秒に1回、だいたい17ミリ秒に1回更新するということになります。
17ミリ秒という更新頻度
17ミリ秒で更新されるならかなり速いように感じますし、 人間の目が認識できるのが50ミリ秒間隔らしいので実際に速いですが、 コンピューターの速度に比べるととても遅いです。
コンピューターの性能を表す数値のひとつにクロック数がありますが、最近は数GHzです。 例えば2GHzなら1秒間に20億回というのが基本的な処理速度の単位になります。 なんというか、要はめっちゃ速いのです。
一瞬で右端に行く理由
前記のため、ボールのX座標は0,96,192,288と順々に設定されていくものの、 画面が更新される前にそれが行われてしまいます。
画面が更新されなければ、表面上見えているのは元の画面のまま、つまり「実行」ボタンを押す前の画面のままですね。 そしてようやく画面が更新された頃には、X座標はとっくに288になっている、つまり一瞬で288になったように見える、ということです。
「左に動く」プログラミングをしてみる
さて、ここまでは数値を直接、X座標として指定してきましたが、もう少し高度なプログラミングに挑戦しましょう。 現在のボールのX座標を使って、ボールが左に動くようにプログラミングしてみます。 以下を実行してみてください。動きましたか?
waiting...
let iX = getBallX();
iX = iX - 32;
setBallX( iX );
値を返すと関数がその値になる
getBallX() は、今のボールのX座標を返す関数です。
返すいうのは、関数がその値を返すことで、呼び出した側から見ると、関数がその値になるように見えます。
例えば、ボールのX座標が 288 ならば、この行は「iX=288;」と同じです。
letは変数宣言
最初に登場する「let」(レット)は、変数と呼ばれるものを宣言するものです。 変数とは、値を入れておく場所です。 名前が付けられます。 今回の例では「iX」という名前の変数だよと、宣言しています。
「マンガで感じる!本当の基礎から学ぶゲームプログラミング」のエピソード「変数」もご参照ください。
「=」(イコール)は代入
「=」(イコール)は、右の値を左の変数と呼ばれる入れ物に代入する処理です。 算数や数学とは意味が異なりますので注意が必要です。
つまり最初の行「let iX = getBallX();」は、今のボールのX座標を、入れ物である 変数iX に入れる処理です。 例えばボールのX座標が 288 なら、iX は 288 になります。
変数の値は変更できる
次の行は「iX = iX - 32;」です。
右辺は、iX から 32 を引いています。 例えば iX が 288 なら、右辺は 256 です。
これを「=」(イコール)で、左辺の変数に代入します。 つまり iX に 256 を設定します。
このように、左辺と右辺に同じ変数を指定することで、変数を書き換えることができます。 「iX = iX - 32;」は、 iX を 32 減らす処理、ということです。
setBalXでX座標設定
最終行は「setBallX(iX);」です。
これをすることで、ボールのX座標が iX になります。 直前でボールが右端にいっていて、元のX座標が 288 だったとしたら、iX が 256になっているので、この行は「setBallX(256);」と同じ意味になります。 これで左に32ピクセル動きました。
以上が「実行」1回分の処理です。 そして再度「実行」ボタンを押すと、さらに左に動き、座標は例えば、256 から 224 になります。 さらに押していけばどんどん左に動きます。
今度は「右に動く」プログラミング
ボールが右に動くプログラムはもうわかりますでしょうか。 答えを書いてしまいますが、ぜひ考えてみてください。
let iX = getBallX();
iX = iX + 32;
setBallX( iX );
左右に動くプログラミング
waiting...
このプログラムをそれぞれボタンに割りあえて、スクリーンの近くに配置しました。 右に左に自由に…ではありませんが、 このように、ボタンを押すたびに右に左に動くようにできます!
[PR]
ゲームは自動的に一定間隔で繰り返し処理し滑らかに動かします
実際の挙動について(ちょっと難しいお話)
「速すぎて見えない?」セクションの説明の補足です。
このセクションの説明を受けると、本当にピッタリのタイミングで実行できれば、 途中経過を一瞬見られることがある…と思えるのですが、 本記事に関しては、残念ながら、その可能性はほぼありません。
setBallX は、本記事のプログラムで保持しているボールのX座標を設定し、Webブラウザーが描画するための html を変更します。
Webブラウザーは、html に基づいて、レンダリングエンジンと呼ばれるもので、画面を描画します。 ただしレンダリングエンジンが実行されるのは、プログラムとプログラムの隙間に限ります。
本プログラムは、4つの setBallX の間にその隙間が無いため、レンダリングエンジンが動かず、htmlが変更されているにも関わらず、途中の状態は画面は反映されません。 本記事のプログラムが終了すると、隙間ができるので、レンダリングエンジンが動き、最後に書き換えられた html の情報に従い、ボールは右端で描画されます。
[PR]
まとめ
本記事では、ボールの位置を操作することで、ゲームプログラミングっぽく絵を動かす体験をしていただきました。
少しでも、プログラミングの楽しさを感じていただけたら幸いです。
補足
・今回使用しているプログラミング言語はWeb業界で一般的に使われる「JavaScript」です。・setBallX(…)とgetBallX()は私が自作したものです。JavaScriptに元から入っている機能ではありません。
・setBallXの処理がクロック数で示された回数分できるというわけではありません。もっと遅いです。それでもリフレッシュレートよりは遥かに高速です。
・(本記事公開後)SVG画像を使用した形に変更しました。
・(本記事公開後)letとその説明を追加しました。
・(本記事公開後)「実際の挙動について」「まとめ」を追記しました。
・(本記事公開後)初期に提示していたプログラム記述ギミックを2025年5月にセキュリティー上の都合で閉じました。
カテゴリー:絵が動くゲームを作ってみよう,絵を動かす
[PR]