ゲームアプリ (Catch the Ball)

【Android Studio】 ゲームアプリ開発入門 第4回 「タイマーで画像を動かす」

ここまでの記事はこちら
 

前回はタップするたびに青いボックスを少しだけ上に動くようにしました。

今回はタイマーを使って

  • 画面をタップしている間は上に移動
  • 画面から指を離すと下に移動

のように、青いボックスを上下に動かしてみます。
 
 


 

動画

【Android Studio】ゲームアプリ開発入門 #4 青いボックスを上下に動かす

 
 

タイマーでボックスを動かす

タイマーを作成

毎秒・毎分など、一定間隔で処理を実行するときはタイマーを使います。
 

MainActivity.java を開いて、4・5行目と18~28行目を追加します。

 
必要な import は3つです。

import android.os.Handler;
import java.util.Timer;
import java.util.TimerTask;

 
 

タイマーの処理は少し複雑にみえるかも知れませんが、分解して見てみましょう。

まずは timer.schedule(…) です。

schedule(TimerTask task, long delay, long period)

 

TimerTask task実行する処理(タスク)
long delayタスクを実行するまでに待機する時間(ミリ秒で指定)
long periodタスクの実行間隔(ミリ秒で指定)

 

このゲームでは「待機時間は無しで、20ミリ秒毎にタスクを実行する」と設定しています。
 

次に TimerTask task の部分です。

新しい TimerTask を作成して、run() メソッドを用意します。

この run() メソッドの中に、繰り返し実行したい処理を書きます。


 

繰り返し実行したい処理は changePos() メソッドです。(この後書いていきます。)

changePos() メソッドでは

  • 画像の位置を変更
  • スコアラベルを更新

をするための処理を書きます。
 

しかし Android 開発では「メインスレッド外で UI を変更することはできない」という決まりがあります。

言い換えると「TimerTask からはスコアラベルを更新できない」ということです。
 

このとき使うのが Handler です。

handler.post で UI スレッドに Runnable を渡して UI を更新するという方法で、changePos メソッドを実行します。


 
 

Handler を使わないと
Only the original thread that created a view hierarchy can touch its views.
というエラーメッセージが表示されます。

このエラーが出た場合は、タイマー処理を見直してみてください。

*このエラーは API 26 以上のエミュレーター・実機では表示されませんが、API 25 以下の場合はアプリが強制終了となるので注意してください。

 
 

changePos() メソッドを用意

先ほど用意したタイマーで定期的に実行する changePos() メソッドを書きます。

5~7行目を追加して、タッチイベント内の box.setY(boxY); は消します。

 
 

タッチイベントの処理を変更

現在は、画面をタップするごとにボックスが少しだけ上に移動するようになっています。
 

ここでは

  • 画面をタップしている間はボックスが上に移動
  • 画面に触れていないとボックスは下に移動

となるようにします。
 

6行目を追加します。

 

changePos と onTouchEvent を以下のように書き換えます。

 
まず「画面をタップしているか、画面に触れていないか」を判定するために action_flg を用意しました。
 

そして、onTouchEvent 内で

  • 画面に触れたら action_flg を true
  • 画面から離したら action_flg を false

にします。
 

ボックスの位置を変更する changePos では、

  • action_flg が true だったら boxY を上へ
  • action_flg が false だったら boxY を下へ

移動させています。
 
 

アプリを実行

ここでアプリを実行してみます。

 

青いボックスが消えてしまいました。

原因は、onCreate() でタイマーがスタートしていることで、青いボックスが下に落ち続けているからです。画面をタップし続けると上がってきます。

画面をタップしたらタイマーが起動するように修正していきましょう。

 
 

タイマー開始のタイミングを修正

ゲーム開始の判定は start_flg で行います。

2行目を追加します。

 

onTouchEvent を以下のように書き換えます。
* onCreate 内の「startLabel.setVisibility(View.INVISIBLE);」「タイマー処理」は削除してください。

 

start_flg が

  • false の時はゲーム開始前
  • true の時はゲームプレイ中

となります。
 

onTouchEvent では、初めて画面がタップされた時に

  1. start_flg を true にする
  2. startLabel を消す
  3. タイマーを開始

という処理を行います。
 

ゲームが始まって start_flg が true になると、21~27行目の action_flg の判定処理が行われるようになります。
 

startLabel の非表示について

startLabel.setVisibility(View.INVISIBLE);
startLabel.setVisibility(View.GONE);

 

INVISIBLE は非表示にするだけ、GONE は完全に消すという違いがあります。

どちらを使っても問題ありませんが、ゲームが始まったら startLabel は不要なので GONE で完全に消してしまいましょう。

 
 

アプリを実行

アプリを実行してみます。
このように動けば成功です。

 

今のままでは、青いボックスが画面の外に移動できてしまいます。
次はここを修正していきましょう。

 
 

青いボックスが画面から出ないようにする

必要なのは、

  • frameLayout の高さ
  • 青いボックスの Y 座標
  • 青いボックスのサイズ
  • の3つです。


     

    5,6行目を追加します。

     

    7~11行目を追加します。

     

    必要な import は1つです。

    import android.widget.FrameLayout;

     

    青いボックスの画像は正方形なので box.getHeight() で高さだけ取得しています。
     
     

    なぜ onCreate に書かないのか?

    もしかしたら「どうして onCreate 内でサイズを取得しないのか?」と思う方がいるかもしれません。

    理由はonCreate ではビューの描画が完了していないからです。

    ビューの描画が完了していない状態で frameLayout の高さや画像サイズを取得しようとしても 0 が返ってきてしまいます。

    そのため、ビューの描画が確実に完了している onTouchEvent 内でサイズを取得しました。
     
     

    最後に changePos() に 9,11行目を追加します。

     

    if (boxY < 0) boxY = 0;

    boxY が 0 より小さくなった場合は、青いボックスがframe の外に出ている状態です。

    frame から出ないように boxY は 0 未満にはならないようにします。

     

    if (boxY > frameHeight – boxSize) boxY = frameHeight – boxSize;

    青いボックスが画面の一番下にある時、boxY は frame の高さからボックスの高さを引いた値になります。

    これ以上 boxY の値が大きくなると画面から出てしまうので、frameHeight – boxSize よりも大きくならないようにします。
     

     
     

    アプリを実行

    アプリを実行してください。

    以下のように、青いボックスが画面から消えなければ成功です!

     

    上手く動かなかった場合は、一番下にここまでのコードを貼っているので確認してみてください。

     
     

    次に行うこと

    少しずつゲームらしくなってきましたね!
    次回は、オレンジ・ピンク・ブラックボールを動かしていきます。

    第5回 「ボールを動かす」に進む

     

    ここまでのコード

     
     

    ABOUT ME
    Sara
    Sara
    「わかりやすく・シンプル」をモットーに、携帯アプリ・ウェブアプリの作り方を紹介します。 独学でプログラミングを勉強をしている方、基礎は勉強したけれど次に何をすれば良いか分からない...という方のお役に立てるサイトを目指しています🙂
    独学は難しそうと感じたら

     
    独学でプログラミングを勉強するのは難しそう、効率的にプログラミングを学びたいという方はオンラインスクールがオススメです。

    オンラインスクールを選ぶときのポイント

    • 無料体験があること
    • 個別サポートがあること

    自分にあったスタイルを見つけるために、無料体験のご利用をオススメします。(無料体験後に自分には合わないなと感じたらハッキリ断ってしまって問題ありません。)
     
    個別サポートもプログラミング学習に挫折しないために重要なポイントです。エラーや困った時にすぐに個別対応をしてくれるスクールを利用して下さい。

    ここでは3つのオンラインスクールを紹介します。
    全て無料体験がありますので、ぜひ自分に合ったスクールを見つけてみて下さい????
     

    1. TechAcademy(テックアカデミー)

    オンライン完結で勉強できるスクールで、コースがとても充実しています。チャットで質問すればすぐに回答を得られるのが一番のおすすめポイントです。
    オリジナルのサービスやアプリの開発もサポートしてくれるので、開発したいものが決まっている人にもオススメです。

    無料体験はこちら

    2. CodeCamp(コードキャンプ)

    一対一で受講できる個別指導のプログラミングスクールです。
    Webデザイン・Webサービス開発・アプリ開発などを幅広く学習することができます。
    マンツーマンなので自分のペースで学習できて、質問もその都度できるのがメリットです。

    無料体験レッスンはこちら

    3. Treehouse

    英語でも良い、英語とプログラミングを同時に勉強したいという方は Treehouse がオススメです。月25ドルで始めることができて、たくさんのプログラミング言語を学ぶことができます。
    個別サポートはありませんが、掲示板が充実しています。ほとんどの場合、質問してから30分程度で回答を得ることができます。

    7日間の無料体験はこちら

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA