ゲームアプリ (Catch the Ball)

【Android Studio】ゲームアプリ開発入門 第6回「衝突判定とスコアラベル更新」

Sara

2023年11月 Android Studio Giraffe | 2022.3.1 で動作確認済み。

ここまでの記事はこちら

今回は「ボックスとボールの衝突判定」と「スコアラベルの更新」です。

衝突判定というと複雑そうに見えるかもしれませんが、ここではできる限りシンプルな方法をご紹介します。

それでは始めていきましょう!

解説

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) {

条件は

  1. オレンジの中心 X 座標が 0 と boxSize の間にある
  2. オレンジの中心 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()));

ぜひ挑戦してみてください!

次に行うこと

これでゲーム画面は全て完成です!次回からは結果画面を作成していきます。

ここまでのコード

Q
MainActivity.java
Subscribe
Notify of
2 Comments
古い順
新しい順 人気順
Inline Feedbacks
View all comments
hiroshimaeasy
5 years ago

java学習初学者です。
androidゲーム開発に興味があり、参考にさせていただいております。

ヒントをいただきたく質問です。
今回の記事の最後に、ボールのY座標のランダム化のコーディングのリファクタリングについて投げかけられていますが、自分で試してみたところ当初と違う動きをしてしまい要因がわかりません…
もしよろしければコードを添削していただけませんでしょうか?
よろしくお願いいたします。

ABOUT ME
Sara
Sara
運営者
書籍やオンライン講座でプログラミングを勉強してフリーランスのプログラマーになりました。
このサイトでは「わかりやすく・シンプル」をモットーに、プログラミングの基礎からアプリ開発まで紹介します。
独学でプログラミングを勉強をしている方、基礎は勉強したけれど次に何をすれば良いか分からない...という方のお役に立てるサイトを目指しています。
主な使用言語:Java / Kotlin / PHP
>> 詳しいプロフィール
>> お問い合わせ
>> 書籍を出版しました!
本格的に学びたい方へ

Code for Fun プログラミング講座

POINT 01

動くコード

プログラミングの文法を学んでも、そこからどのようにアプリ開発ができるのかイメージが湧きにくいものです。

Code for Fun のプログラミング講座では、ゲームやカレンダーなどアプリとして機能するものを作りながらプログラミングを学ぶことができます。

POINT 02

自分のペースで

オンライン講座なので、ご自身のペースで学習を進めて頂けます。

受講期限もないので、いつでも前のレッスンに戻ることができるので安心です。

お申し込みしたその日からすぐに始めることができます。

POINT 03

個別サポート

プログラミング学習では、エラーが起きることはよくあります。そんな時はお気軽にお問い合わせください!

コメント欄またはメールによるサポートを回数無制限でご利用頂けます。(*講座に関連するご質問のみ対応)

今すぐ無料でお試し

2
0
この記事にコメントするx
記事URLをコピーしました