質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Java EE

Java EE(Java Enterprise Edition)はJavaベースのテクノロジーとその相互運用の仕様をまとめたものです。サーバとクライアントのアーキテクチャを規定し、特定アプリケーションのクラス用に定義されたテクノロジー設定のプロファイルを使用します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Q&A

解決済

1回答

1292閲覧

onTouchEventの動きで不明点があるので、解決して欲しいです。

ryuya1204

総合スコア12

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

Java EE

Java EE(Java Enterprise Edition)はJavaベースのテクノロジーとその相互運用の仕様をまとめたものです。サーバとクライアントのアーキテクチャを規定し、特定アプリケーションのクラス用に定義されたテクノロジー設定のプロファイルを使用します。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

0グッド

0クリップ

投稿2021/08/11 15:58

onTouchEventの処理が不明なので教えていただきたいです。

現在、Android Studioを使用しており、タッチをしている間はキャラクターが上昇し、タッチをしない間はキャラクターが下降する処理を記述しています。
動作自体は問題ないのですが、なぜその動きになるのか疑問な点があります。

疑問点は以下になります。

①onTouchEventでstart_flg = falseで1回目の処理を行う
②start_flg = trueに置き換えて、changePos()を実行して、キャラクター上昇
③onTouchEventが"指を離す"で実行されて、if文がstart_flg = trueで実行
④else以下のif文が読み込まれ、action_flgが書き換えられて処理が逆に下降で実行

以上の処理までは考え方として合っているのでしょうか?
その考えの場合、start_flgをfalseに書き換えているタイミングが理解できません。
start_flgがfalseで読み込まれているのは、最初の1回だけになってしまいます。
ただ、changePos()を記述しているのは、start_flg = falseの処理なので、キャラクターが移動する処理として何度もこのコードが実行されているはずです。
フィールド変数として記載しているstart_flg = falseに戻っているのでしょうか?

return true でstart_flg = trueで返却していると思いますが、一生、if文の中のstart_flg = falseが読み込まれないような気がしています。

どこかで勘違いしていると思うのですが、どこか分からない状態です。
どういった処理の流れをしているか教えていただければ幸いでございます。
お手数おかけしますがご確認よろしくお願いいたします。

java

1 2package com.example.catchtheball; 3 4import androidx.appcompat.app.AppCompatActivity; 5 6import android.os.Bundle; 7import android.os.Handler; 8import android.view.MotionEvent; 9import android.view.View; 10import android.widget.FrameLayout; 11import android.widget.ImageView; 12import android.widget.TextView; 13 14import java.util.Timer; 15import java.util.TimerTask; 16 17public class MainActivity extends AppCompatActivity { 18 19 private TextView scoreLabel; 20 private TextView startLabel; 21 private ImageView box; 22 private ImageView orange; 23 private ImageView pink; 24 private ImageView black; 25 26 // サイズ 27 private int frameHeight; 28 private int boxSize; 29 30 // 位置 31 private float boxY; 32 33 // Handler & Timer 34 private Handler handler = new Handler(); 35 private Timer timer = new Timer(); 36 37 // Status 38 private boolean action_flg = false; 39 private boolean start_flg = false; 40 41 @Override 42 protected void onCreate(Bundle savedInstanceState) { 43 super.onCreate(savedInstanceState); 44 setContentView(R.layout.activity_main); 45 46 scoreLabel = findViewById(R.id.scoreLabel); 47 startLabel = findViewById(R.id.startLabel); 48 box = findViewById(R.id.box); 49 orange = findViewById(R.id.orange); 50 pink = findViewById(R.id.pink); 51 black = findViewById(R.id.black); 52 53 orange.setX(-80.0f); 54 orange.setY(-80.0f); 55 pink.setX(-80.0f); 56 pink.setY(-80.0f); 57 black.setX(-80.0f); 58 black.setY(-80.0f); 59 } 60 61 public void changePos() { 62 if (action_flg) { 63 boxY -= 20; 64 65 } else { 66 boxY += 20; 67 } 68 69 if (boxY < 0) boxY = 0; 70 71 if (boxY > frameHeight - boxSize) boxY = frameHeight - boxSize; 72 73 box.setY(boxY); 74 } 75 76 @Override 77 public boolean onTouchEvent(MotionEvent event) { 78 if (start_flg == false) { 79 80 start_flg = true; 81 82 FrameLayout frame = findViewById(R.id.frame); 83 frameHeight = frame.getHeight(); 84 85 boxY = box.getY(); 86 boxSize = box.getHeight(); 87 88 startLabel.setVisibility(View.GONE); 89 90 timer.schedule(new TimerTask() { 91 @Override 92 public void run() { 93 handler.post(new Runnable() { 94 @Override 95 public void run() { 96 changePos(); 97 } 98 }); 99 } 100 }, 0, 20); 101 102 } else { 103 if (event.getAction() == MotionEvent.ACTION_DOWN) { 104 action_flg = true; 105 106 } else if (event.getAction() == MotionEvent.ACTION_UP) { 107 action_flg = false; 108 109 } 110 } 111 return true; 112 } 113} 114

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2021/08/11 19:02

最初のタッチでゲーム開始で、start_flg はゲーム進行中を表すフラグ、その後のタッチでキャラクターを操作ってことですよね。何らかの条件でゲームオーバーになったら、タイマーを止めて start_flg を false にするのでは。 (でも、ゲームループが onTouchEvent にあるのは違和感…。)
ryuya1204

2021/08/12 17:39

ご回答ありがとうございます。 おかげさまで無事解決いたしました。 ありがとうございます!
guest

回答1

0

ベストアンサー

どこかで勘違いしていると思うのですが

途中までは合っているのですが…。

start_flg は onTouchEvent 内において if 文の前半部分を1回実行する為だけに存在し、一度 true になったら false にはなりません。
それは実際に実行して start_flg を表示させても分かるでしょう。

そして、なぜそうしているのかと言えば、その前半部分で各種初期化をしているからです。
その初期化の中に、timer によるスケジューリングがあります。

一番の勘違い部分は「changePos()を記述しているのは、start_flg = falseの処理なので・・・」という部分で、コードとして changePos(); が書かれているのはソコですが、実行されるのは『ソコではない』という点です。

この書き方に慣れていらっしゃらないのかもしれませんが、changePos(); が書かれているのは
public void run() {~} というメソッドの中であり、そのメソッドは new Runnable() {~} というクラス(のインスタンス)の定義であり、それは handler.post(~); という記述により handler オブジェクトのpost メソッドの第一引数です。
この post メソッドは引数のオブジェクトの run メソッドの実行をメッセージキューにスケジューリングするように要求するものです。

https://developer.android.com/reference/android/os/Handler?hl=ja#post(java.lang.Runnable)

handler は new Handler(); として生成されていますので、メッセージキューは UI スレッドのものとなります。
(なお、引数無しのコンストラクタは非推奨となっていまして、正確には new Handler(Looper.getMainLooper()); と書かないと、予期せぬバグが発生する可能性があるようです。)

さらに、handler.post(~); が書かれているのは public void run() {~} というメソッドの中であり、そのメソッドは new TimerTask() {~} というクラス(のインスタンス)の定義であり、それは timer.schedule( ~ , 0, 20); という記述により timer オブジェクトの schedule メソッド第一引数です。
この schedule メソッドは[第二引数]ミリ秒後から、[第三引数]ミリ秒毎に、第一引数の run メソッドを呼び出すように別のスレッドにスケジューリングするものです。

https://developer.android.com/reference/java/util/Timer?hl=ja#schedule(java.util.TimerTask,%20long,%20long)

スケジューリングする"だけ"ですので、この時点では実行されません。

schedule メソッドが終わった後は、 20 ミリ秒毎に(このアクティビティで起きている他のことに関係無く) UIスレッド上で changePos(); が実行されます。
ここで既に start_flg は関係ありません。一度だけスケジューリングすれば良いのですから。

投稿2021/08/11 17:19

編集2021/08/12 17:50
jimbe

総合スコア12756

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ryuya1204

2021/08/12 17:39

ご回答いただきありがとうございます。 内容について拝見し、どこで勘違いしていたか分かりました。 Timerの処理内容とスレッド処理について理解不足を痛感しています。 また機会ありましたらよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問