![]()
右の絵をブロックに使用して出してみましょう。
ブロックの大きさは、横が32ピクセル。縦が16ピクセルです。 配置は、横は端から32ピクセル単位で8個並べてみます。 縦の位置は適当です。
![]()
: :
↓ブロック当たり判定イメージ |
![]() |
テストしていただければお分かりと思いますが、 表示しただけでは、本当に表示しただけです。 ブロックとボールがぶつかったら跳ね返るべきでしょう!
当たり判定関数
ここで、ブロックは8個ありますが、 それらは一つ一つ消していくと言う意味で、 一つのブロックに対する当たり判定用の関数を作ります。
ここでは、 ブロックの左端がボールの右端より小さくて、 ブロックの右端がボールの左端より大きければ、 左右は当たっていると考えます。
上下も同様ですので、それを踏まえて→の説明と、 ↓の当たり判定の関数のプログラムをご覧ください。
縦に長くなっているのでちょっと違和感があるかも知れませんが、 式の途中で改行を入れるのはなんら問題はありません。 念のためにそれも書いておきますネ。 単語を途中で、例えばreturnをretとurnにしちゃうのはダメですケド。 あんまり一行が長すぎても読みにくいので、 適当に改行して作って下さいね。
//------------------------------------------------ // ボールとブロックの当たり判定 // lyr = ブロックレイヤー名 //------------------------------------------------ function hitchkBlock( lyr ) { return( lyrGetLeft( lyr ) < ballx + 15 && ballx < lyrGetLeft( lyr ) + 31 && lyrGetTop( lyr ) < bally + 15 && bally < lyrGetTop( lyr ) + 15 ); } 当たり判定関数の呼び出し
上記の関数は、ブロックのレイヤー名を受け取って処理します。 だから、呼び出す側ではブロックの全レイヤー名を渡さなければなりません。 こんな感じです。
一気に跳ね返る処理まで書いちゃいましたが、 ここはラケットや上の壁に当たった時と同様ですから 大丈夫ですね!?
// ボールとブロックとの当たり判定 if ( hitchkBlock( "lyrblock1" ) || hitchkBlock( "lyrblock2" ) || hitchkBlock( "lyrblock3" ) || hitchkBlock( "lyrblock4" ) || hitchkBlock( "lyrblock5" ) || hitchkBlock( "lyrblock6" ) || hitchkBlock( "lyrblock7" ) || hitchkBlock( "lyrblock8" ) ) { speedy = -speedy; // 上下に跳ね返す }
跳ね返り関数
まずは準備として、跳ね返る処理を関数にしちゃいます。
//------------------------------------------------ // ボールをブロックで跳ね返す //------------------------------------------------ function ballReflect() { speedy = -speedy; // 上下に跳ね返す } 表示を消しましょう
ブロックを消す方法はわかりますでしょうか? 以前作ったレイヤーを消す関数を使えばできますよね。 忘れてしまった方はここをご覧ください。
// ブロック1を消す if ( hitchkBlock( "lyrblock1" ) ) { lyrSetVisibility( "lyrblock1" , false ); // 表示抹消 ballReflect(); // 跳ね返り } else if ( hitchkBlock( "lyrblock2" ) ) { : } ちょっと解説
- else if
この命令は新登場ですね。上記の意味ですが、まあ実は説明無くてもわかりますよね? 理解を深めるために、 「4-c.レイヤーを操作してみましょう」 の中のifの説明とも見比べてみてください。
if ( 条件A ) { 条件Aが true の場合の処理 } else if ( 条件B ) { 条件Aが false で、条件Bが true の場合の処理 } else if ( 条件C ) { 条件Aと条件Bが false で、条件Cが true の場合の処理 : } else { すべての条件が false の場合の処理 }
さてこれを用いてどうしているかというと、 ブロックとボールは2つ同時に当たる可能性があるのですが、 if文だけだとその両方にあたってしまい、 ボールは突き抜けてしまいます。(※何故かは考えてみてください) そこで当たり判定に成功した最初のブロックだけを処理するようにします。 それが else if を用いた本プログラムになります。
今回採用した手法以外にも解決方法はありますので、 ご自分で色々と工夫してみてください。当たり判定を消しましょう
さて、予想できているかと思いますが、 表示が消えただけでは当たり判定は消えません。 だからこのままでは、見えないブロックに当たってしまう ゲームになってしまいます(^_^;
これらをブロック数分書けば、うまくいくわけです。 8個くらいなので書いてしまいましょう。
そこで、ブロックが表示されているかどうかを表す変数を用意します。 名前は blockf としておきます。 この変数 blockf は、最初すなわちまだブロックが表示されている間は true にしておきます。 そしてボールが当たった時点、すなわちブロックが消えた時に false にします。
そして、当たり判定をするときに、まずこの変数 blockf を見ます。 blockf が true だったら当たり判定を行いますが、false なら当たり判定を行いません。
こうすれば、一つのブロックが表示されている間は当たり判定を行って、 当たって消えてしまった場合には当たり判定は行われないという 処理にする事ができます。
なお実際には、ブロック毎に変数を作らなければならないので、 変数は blockf という名前ではなくて、 blockf1 ~ blockf8 の8種類を使用します。 ブロック1のプログラムはこんな感じです。
var blockf1; // ブロックの表示フラグ blockf1 = true; ・ ・ if ( blockf1 && hitchkBlock( "lyrblock1" ) ) { lyrSetVisibility( "lyrblock1" , false ); // 表示抹消 ballReflect(); // 跳ね返り blockf1 = false; // 当たり判定削除 } ・ ・
さて、どうでしょう?もう充分ゲームになっていますよね? ちなみに今のままだと繰り返しできないことに気付きましたか? ブロックが消えてしまうので続けてできないんですね。 なのでちょっとした工夫としてですが、 スタートしたときに全ブロックレイヤーを表示する処理を入れるのが良いでしょう。 方法はもうお分かりですね。 全ブロック分lyrSetVisibilityを、 引数visfをtrueにして呼び出すだけです。
次の章ではもう少し工夫します。いよいよ、あと少しで完成です!
前章「8.ラケットを動かす」までを理解された方で、 本章「9.ブロック」についても一区切りついた方にお願いです(必須ではありません)。 よろしければ、「9-a.ブロックを表示してみましょう」~「9-c.当たったブロックを消しましょう」について、 最もあてはまるものを選んでいただいて 「アンケートを送信する」を押してください。
ご協力ありがとうございます。