AOYAMA KOJI's PROGRAMMING BLOG

ボールを上下左右の壁で跳ね返すプログラミング【絵が動くゲームを作ってみよう】プログラミングを始めようとしている方・初心者向け

2020/05/03
ボールを上下左右の壁で跳ね返すプログラミング【絵が動くゲームを作ってみよう】

 外出自粛の中、自動車税の通知書が届き 「うわ、これはさすがに出かけないとダメか」 と思ったら、今はネットで支払えるのですね。 超便利。 クレジットカードで支払って妻に報告したら「いつもインターネットバイキングで払っているよ」と言われて。 結構前からできていたのですね。恥ずかしながら知りませんでした。 ただしバンキングね(ボソッ)
 外出自粛で家のことを少しは自分もするようになって知識が増えました。 というかゲーム開発以外のことを知らなすぎでしたね。 先日も近くのスーパーで、カレー用の肉がだいたい250g単位で売られている、と気づいて、 それがカレールーのレシピに多い250gおよび500gに合わせているのだと気づいて感動しました。 工夫はいたるところにあるのですね。
 さて本記事では、 ボールを動かすプログラムはすでにある状態で、四方の壁にぶつかったときの跳ね返りの部分のプログラミング体験をしてみましょう。


[PR]

まずはボールの動きの確認から


 まず最初にゲームスタートボタンを押してみてください。 何も手を加えていないときの挙動を確認してみましょう。 ちなみにまだ今回はまだゲームと呼べるものでは無いですけれど雰囲気でボタン名は「ゲームスタート」にしてみました。
 内部のプログラムは、ボールを0.1秒ごと、 すなわち10fpsで動かしています。 初期方向は右下です。
 右下に動いていって、下の端に沿って這うように右に進んで、右下で止まれば成功です。


壁にぶつかったときに呼ばれるプログラム


 それではまず、以下をご覧ください。 ボールが動くたびに、この処理が差し込まれます。
if ( 144 <= g.iBallY ) {
  g.iSpeedY = -g.iSpeedY;
}

 確認したら、「ゲームスタート」を押して、実行してみましょう。 下の壁にぶつかって上にうまく跳ね返れば成功です!
 その後は右の壁にぶつかって上に這うように進んで止まってしまうでしょうが、そこは今は気にしないでください。

ボールを動かすための変数


変数名
初期値
意味
g.iBallX
0から288
144
X座標
g.iBallY
0から144
74
Y座標
g.iSpeedX
-8または8
8
X速度
g.iSpeedY
-8または8
8
Y速度

 本記事では、ボール用にこのような変数を用意しました。 変数というのは、値を入れるための入れ物のことです。

座標


 座標というのは位置のことです。 Xが横、Yが縦です。
 数学で習う座標と若干異なり、ここでは、左上が(0,0)、右下は(320,176)になります。 2次元ゲームの上下の大きくなる方向は、数学と逆なので要注意です。
 ボールのサイズが(32,32)のため、g.iBallX の最大値は 288、g.iBallY の最大値は 144 になります。

速度


 速度も変数で持っています。 こちらもXが横、Yが縦です。 毎フレーム、以下の処理が行われています。
g.iBallX += g.iSpeedX;
g.iBallY += g.iSpeedY;

 「+=」は、左辺の変数に、右辺の値を加算する処理です。 g.iSpeedX がプラスなら右へ、マイナスなら左へ、 g.iSpeedY がプラスなら下へ、マイナスなら上へ動きます。

if


 if は、条件分岐の処理です。以下のように書きます。
if ( 条件 ) {
  条件が真のときの処理;
}

 前述のソースコードでは、条件が「144 <= g.iBallY」でした。 144は g.iBallY の最大値ですので、 g.iBallY が最大値以上なら真、つまり、下の壁にぶつかったら真という意味です。

g.iSpeedY = -g.iSpeedY


 if文の中の処理 g.iSpeedX = -g.iSpeedX; は、条件が真だった場合にのみ実行されます。
 「=」(イコール)は、右辺の値を左辺の変数に代入する処理です。
 g.iSpeedY は初期値 8 でしたので、 -g.iSpeedY は -8 です。 それを左辺の変数 g.iSpeedY に代入します。
 これはつまり、g.iSpeedY のプラスマイナスを反転する処理です。 g.iSpeedY は上下方向に動かす速度です。 プラスマイナスを反転すると、進む方向が上下反転します。

プログラム再掲


 つまり、プログラムを再掲しますが以下は、「下の壁にぶつかったら、進む方向を上下反転」する処理、ということです。
if ( 144 <= g.iBallY ) {
  g.iSpeedY = -g.iSpeedY;
}

右壁でも反転させてみる


 では右壁で反転させる処理を追加しましょう。 以下を実行してみてください。 どうでしょうか。 想像通りの動きになりましたか?
if ( 144 <= g.iBallY ) {
  g.iSpeedY = -g.iSpeedY;
}
if ( 288 <= g.iBallX ) {
  g.iSpeedX = -g.iSpeedX;
}

上下左右で反転させてみる


 では上下左右で反転させてみましょう。 以下にプログラムを記述しますが、 ぜひ、ここまで理解したことを踏まえて、ご自身で考えてみてください。
if ( g.iBallX <= 0 || 288 <= g.iBallX ) g.iSpeedX = -g.iSpeedX;
if ( g.iBallY <= 0 || 144 <= g.iBallY ) g.iSpeedY = -g.iSpeedY;

「||」は論理和


 if の 条件部分の中に出てくる「||」は、論理和です。 「条件1 || 条件2」で、条件1と条件2のどちらかが真なら真になります。
 なお、筆者は「OR(おあ)」あるいは「OR OR (おあ おあ)」と呼んでいますが、一般的にはわかりません。
 参考までに「条件1 && 条件2」と書くことで、条件1と条件2の両方が真なら真という式になります。 こちらは論理積です。 筆者は「AND(あんど)」あるいは「AND AND (あんど あんど)」と呼んでいます。

if文の別の書き方


 JavaScript において if文は、{ と } を使用しない書き方もあり、上記はそれを用いました。
if ( 条件 ) 条件が真の時の処理;

要注意(少し高度なお話)


 筆者は、この方がソースコードが読みやすいと思えば、積極的にこの記述方式を採用しています。 ただし、例えば、以下のように書くこともできてしまうので、要注意です。
(例1)
if ( 条件 ) 処理1; 処理2;
(例2) if ( 条件 ) 処理1; 処理2;

 これは、例1、例2ともに、以下と同じ意味です。
if ( 条件 ) {
  処理1; 
}
処理2;

 特に(例2)の書き方は誤解しやすいので、 コーディングルールで禁止しておいた方が良いでしょう。
 余談ですが、Python では以下の形にインデントを強制されるので、このような誤解はありません。 これが、Python が近年ではよく使われている言語の1つである理由かもしれませんね。
(Pythonの例)
if  条件:
	処理1; 
処理2;


まとめ


ボールを上下左右の壁で跳ね返すプログラミング【絵が動くゲームを作ってみよう】  本記事では、ボールを動かすプログラムはすでにある状態で、四方の壁にぶつかったときの跳ね返りの部分のプログラミング体験をしました。
 そのプログラミングでは、変数が徐々に変化していく処理が登場しました。 初心者には少し難しかったかもしれません。 実はこれが、プログラマーになるためには超えなければならない、おそらく最大の壁です。
 筆者は当時、これを理解するのに半年かかりました。 もしよくわからなくても、焦らず楽しんで、何度も試してみてください。 本記事のプログラムは壁で跳ね返されますが、プログラマーとしての壁は超えていきましょう。

補足

・今回使用しているプログラミング言語はWeb業界で一般的に使われる「JavaScript」です。
・(本記事公開後)速度変数を使用する形に大幅に改修しました。
・(本記事公開後)初期に提示していたプログラム記述ギミックを2025年5月にセキュリティー上の都合で閉じました。


カテゴリー:絵が動くゲームを作ってみよう,絵を動かす
[PR]