ゲームプログラミングっぽく絵を動かしてみる
2020/04/12
新型コロナウイルス感染症、COVID-19拡大の影響で、 2020年4月8日からという形で、日本で東京都など7都府県に緊急事態宣言が出され外出自粛の要請などが行われましたね。
医療従事者の方やその関係者の方、社会生活に必要な業務をされている方、対応に当たられている方には本当に感謝しております。 一方で感染してしまった方も辛い思いをされているかと思いますが一日も早い回復をお祈りします。 私などはただ制限されただけでも気が滅入ってしまいますからね。 今は辛くてもいつかは解決するのは間違いないでしょうから、 今はインドアでできることをポジティブにやっていければと思います!
ボールの位置を変更するプログラミングをしてみる
今回は以下の絵を用意しました。この中のボールの位置を操作してみます。
waiting...
上の白い枠内はプログラムを書く場所になっています。ここに、
g.setBallX(0);
色々な位置にボールを置いてみる
うまくいったら、今度は以下を貼り付けて実行してみてください。 先程書いたプログラムの0を100に変えるだけでも大丈夫です。
g.setBallX(100);
うまくいったら、さらに以下を試してください。
g.setBallX(200);
どうでしょう?ちょっとずつ右に動いているように見えませんか? ここで指定する数字がボールの横の位置を示しています。 位置というのは座標ってやつですね。 横の位置はX座標。 たぶん座標を習うのは中学校の数学だと思います。
ここでは、左端が0、右端が480になっていますので、 理解を深めるためにも、数値を変えて実行、数値を変えて実行、としてみてください。 なんとなく、右とか左に動いているように見えると思います。
ゲーム内で絵が動く仕組みはパラパラまんが
実はゲームの画面で絵が動いているのもこの仕組なのです。 一枚一枚の止まっている絵、すなわち静止画を、パラパラまんがのようにパラパラと切り替えて表示しているだけなのです。 それが高速に切り替わるので、滑らかに動いているように見えるんですね。
プログラムは時系列に沿って順番に処理するのが特徴
プログラムは時系列にそって順番に処理を行うのが特徴的です。 プログラムを複数行書けば処理は上から下に順番に行われます。
つまり、上から順番に座標を変更しつつ処理を書いていけば、動いているように見えそうですよね! やってみましょう! こういうのは思いついたらやってみるのが大事です。
以下は左端0から160ずつずらしていって、最後は右端の480にするプログラムです。 この4行すべてをプログラムが書ける枠内に書いて「実行」です! コピーして貼り付けでもOKです。
g.setBallX(0); g.setBallX(160); g.setBallX(320); g.setBallX(480);
…どうでしょう?うまく行きましたか?左端から徐々に右端に…。 おそらくですが、そうならず、単に右端に行っただけではないでしょうか。 なぜでしょうね。
速すぎて見えない
皆さんはディスプレイのリフレッシュレートというのをご存知でしょうか? 昔のテレビは60Hz、最近は240Hzとかもありますね。 スマートフォンは60Hzが多くて、そろそろ90Hzが出てきているところでしょうか。 これは、例えば60Hzなら、1秒間に60回、画面を更新することを意味します。 言い換えれば60分の1秒に1回、だいたい17ミリ秒に1回更新するということになります。
17ミリ秒で更新されるならかなり速いように感じますし、 人間の目が認識できるのが50ミリ秒間隔らしいので実際に速いですが、 コンピューターの速度に比べるととても遅いです。 コンピューターの性能を表す数値のひとつにクロック数がありますが、最近は数GHzです。 例えば2GHzなら1秒間に20億回というのが基本的な処理速度の単位になります。 なんというか、要はめっちゃ速いのです。
なのでボールのX座標は0,160,320,480と順々に設定されていくものの、 画面が更新される前にそれが行われてしまいます。 画面が更新されなければ、表面上見えているのは元の画面のまま、つまり「実行」ボタンを押す前の画面のままですね。 そしてようやく画面が更新された頃には、X座標はとっくに480になっている、つまり一瞬で480になったように見える、ということです。
本当にドンピシャなタイミングで実行できれば、 途中経過を一瞬見られることはあるかも知れません。
「左に動く」プログラミングをしてみる
さて、ここまでは数値を直接、X座標として指定してきましたが、もう少し高度なプログラミングに挑戦しましょう。 現在のボールのX座標を使って、ボールが左に動くようにプログラミングしてみます。 以下を貼り付けて実行してみてください。
let x = g.getBallX(); x = x - 32; g.setBallX(x);
g.getBallX()は今のボールのX座標を返します。 この形式のものを関数と呼びますが、返すいうのは、関数がその値になることです。 ボールのX座標が480ならば、この行は「x=480;」と同じことになります。
「=」(イコール)は、右の値を左の変数と呼ばれる入れ物に入れる処理です。 算数や数学とは意味が異なりますので注意が必要です。 つまり最初の行は、今のボールのX座標を、入れ物である変数xに入れる処理です。 つまりボールのX座標が480なら、xは480になります。
次の行は、xから32を引いてxに入れます。 これでxには、今のボールの座標より32だけ小さい値が入ります。 元々が480だったとしたら、この行の処理でxの値は448になります。
次のg.setBallX(x)をすることで、ボールのX座標がxになります。 もともと480だったとしたらxが448になっているので、この行は「g.setBallX(448);」と同じ意味です。 これで左に32ピクセル分動きました。
以上が「実行」1回分の処理ですね。 そして再度「実行」ボタンを押すと、さらに左に動き、座標は448から416になります。 さらに押していけばどんどん左に動きますね。
今度は「右に動く」プログラミング
x=g.getBallX(); x=x+32; g.setBallX(x);
うまくいけば、右に左に自由に…ではありませんが、実行ボタンを押すたびに右に左に動くようにできましたね。
ゲームは自動的に一定間隔で繰り返し処理し滑らかに動かします
ゲームは一定間隔でこういった処理を繰り返して、滑らかに動くようにできています。 次回以降でその片鱗だけでも紹介できたら良いなと思っています。
補足
・今回使用しているプログラミング言語はWeb業界で一般的に使われる「JavaScript」です。・g.setBallX(…)とg.getBallX()は私が自作したものです。JavaScriptに元から入っている機能ではありません。
・g.setBallXの処理がクロック数で示された回数分できるというわけではありません。もっと遅いです。それでもリフレッシュレートよりは遥かに高速です。
・g.setBallX(…)の処理として変な数値を指定しても右端や左端より外側へは行かないようになっています。
・(2020/04/18追記)SVG画像を使用した形に変更しました。
カテゴリー:メガホンDEポン,プログラミング,JavaScript
Copyright (C) Logic Lovers Inc.