【Android Studio】ゲームアプリ開発入門 第6回「衝突判定とスコアラベル更新」
ここまでの記事はこちら
今回は「ボックスとボールの衝突判定」と「スコアラベルの更新」です。
衝突判定というと複雑そうに見えるかもしれませんが、ここではできる限りシンプルな方法をご紹介します。
それでは始めていきましょう!
解説
1. hitCheck メソッドの用意
衝突判定は hitCheck メソッドを用意して書いていきます。
3・11~13行目を追加します。
changePos メソッドでボックスとボールを動かす前に、毎回 hitCheck メソッドを呼んで衝突判定を行います。
2. オレンジボールの衝突判定
まずはオレンジボールの衝突判定をします。
hitCheck メソッド内の3~11行目を追加します。
Warning が出ている箇所があると思いますが、最後に修正するのでそのままにしておいて下さい。
衝突判定の書き方はどれほど厳密に判定するかで変わりますが、このゲームでは
ボールの中心座標が青いボックスの中に入ったら衝突(ヒット)
と判定します。
Step 1
まずは、オレンジボールの中心座標を取得します。
float orangeCenterX = orangeX + orange.getWidth() / 2;
float orangeCenterY = orangeY + orange.getHeight() / 2;
Step 2
次に書いている if 文がボールの中心座標が青いボックスの中に入ったかの条件式です。
if (0 <= orangeCenterX && orangeCenterX <= boxSize &&
boxY <= orangeCenterY && orangeCenterY <= boxY + boxSize) {
条件は
- オレンジの中心 X 座標が 0 と boxSize の間にある
- オレンジの中心 Y 座標が boxY と boxY + boxSize の間にある
の2つです。
この2つの条件を満たしていると、ボールの中心がボックスの中にある状態なので「ヒット」とします。
Step 3
orangeX = -10.0f;
score += 10;
ヒットと判定されたら orangeX をマイナスの値にします。
マイナスにすることで changePos メソッドに書いた if (orangeX < 0) { の条件式に一致して、新しい位置から再びボールが出てくるようになります。
スコアもここで加算します。
3. スコアラベルの更新
スコアラベルに最新のスコアが表示されるようにします。
4行目を追加します。
10行目を追加します。
7行目を追加します。
Warning が出ている箇所があると思いますが、最後に修正するのでそのままにしておいて下さい。
4. アプリを実行する
ここでアプリを実行してください。
オレンジボールを取ったときに、スコアが 10 ポイントずつ加算されていれば成功です。
5. ピンクボールの衝突判定
オレンジボールの衝突判定の下に、以下のコードを追加します。
Warning が出ている箇所があると思いますが、最後に修正するのでそのままにしておいて下さい。
オレンジボールと同じように中心座標を取得して衝突判定を行なっています。
スコアは 30 ポイント加算しています。
6. 黒いトゲトゲの衝突判定
ピンクボールの衝突判定の下に、以下のコードを追加します。
Warning が出ている箇所があると思いますが、最後に修正するのでそのままにしておいて下さい。
黒いトゲトゲに当たった場合はゲームオーバーです。
タイマーをキャンセル(停止)して結果画面を表示します。(結果画面は次回書いていきます。)
7. アプリを実行する
ここでアプリを実行します。
スコアが加算されること、黒いトゲトゲに当たった時にタイマーが止まることを確認して下さい。
補足:処理をまとめる
衝突判定を3つ書きましたが、 if 文はどれも似ていて何度も書くのが面倒ですよね。
ここではメソッドを用意して処理をまとめる方法を紹介します。
hitStatus メソッドを追加して、衝突判定の if 文を書き換えます。
追加・変更するのは7・16・25・36~39行目です。
hitStatus メソッドでは、衝突した場合は true を、衝突しなかった場合は false を返しています。
1行で書きましたが、以下のコードをまとめているだけです。
if (0 <= centerX && centerX <= boxSize &&
boxY <= centerY && centerY <= boxY + boxSize) {
return true;
} else {
return false;
}
さらに簡略化して、このように書くこともできます。
public boolean hitStatus(float centerX, float centerY) {
return (0 <= centerX && centerX <= boxSize &&
boxY <= centerY && centerY <= boxY + boxSize);
}
前回、ボールの Y 座標を Math.random() を使って作成しましたが、この処理も同じように共通化することができそうです。
orangeY = (float)Math.floor(Math.random() * (frameHeight – orange.getHeight()));
ぜひ挑戦してみてください!
次に行うこと
これでゲーム画面は全て完成です!次回からは結果画面を作成していきます。
ここまでのコード
- MainActivity.java
java学習初学者です。
androidゲーム開発に興味があり、参考にさせていただいております。
ヒントをいただきたく質問です。
今回の記事の最後に、ボールのY座標のランダム化のコーディングのリファクタリングについて投げかけられていますが、自分で試してみたところ当初と違う動きをしてしまい要因がわかりません…
もしよろしければコードを添削していただけませんでしょうか?
よろしくお願いいたします。
hiroshimaeasyさん
記事をお読みいただきありがとうございます。
コードをこちらのコメント欄に貼り付け、または codeforfun.jp@gmail.com まで送っていただけますか?
確認させて頂きます
Sara より