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

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

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

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

Android Studio

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

Q&A

解決済

1回答

1766閲覧

Androidアプリにおいて、カスタムビューを任意のタイミングで再描画したい

退会済みユーザー

退会済みユーザー

総合スコア0

Java

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

Android Studio

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

0グッド

0クリップ

投稿2019/02/03 06:21

こんにちは。Androidアプリ開発を勉強中のものです。

今、自分vsCPUのオセロアプリを作成しており、最低限オセロと呼べるものはできたのですが、描画処理が上手くいかず困っています。

作成したい流れとしては、画面をタッチしたとき
1.自分のターンなら駒を置く
2.描画
3.「数秒待機」
4.CPUの駒を置く
5.描画

のような感じにしたいのですが、3.「数秒待機」がなかなかうまくいかず困っています。
ソースコードだとこんな感じにしたいです

Java

1// カスタムビュー内 2@Override 3public boolean onTouchEvent(MotionEvent event) { 4 if (isPlayerTurn()) { // 自分のターン時のみ処理 5 putPlayerPiece() // 1.自分の駒を置く 6 invalidate(); // 2.描画 7 8 Thread.sleep(1000); // 3.待機 例外処理は省略 9 10 putCPUPiece(); // 4.CPUの駒を置く 11 invalidate(); // 5.描画 12 } 13 return super.onTouchEvent(event); 14}

しかし、invalidate()は呼ばれた瞬間すぐに実行されるわけではないようで、上記のコードだと2の描画が実行されません。

そこまでは分かったのですが、じゃあどうしようかと考えてもいい案が思いつかず困っています。
一応、下記のように別スレッドで実行させれば表示上ではうまくいくのですが、タッチすれば表示の待機を待たずにどんどん置けてしまうので、これも思い通りの実装ではないです

Java

1@Override 2public boolean onTouchEvent(MotionEvent event) { 3 if (isPlayerTurn()) { // 自分のターン時のみ処理 4 putPlayerPiece() // 1.自分の駒を置く 5 invalidate(); // 2.描画 6 7 new Handler().post(() -> { 8 Thread.sleep(1000); // 3.待機 例外処理は省略 9 10 putCPUPiece(); // 4.CPUの駒を置く 11 invalidate(); // 5.描画 12 }); 13 } 14 return super.onTouchEvent(event); 15}

何かいい方法を教えていただけると助かります。よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

CPU側の手がすぐ決まっていますのに, なぜ数秒待たないといけないのかが少し疑問ですが.(ゲーム性が悪くなりませんか?)

「考えているフリ」をするのでしたら, AsyncTask で時間を潰し, その前後でプログレスを出して操作をブロックすれば良いのではないでしょうか.

投稿2019/02/03 11:09

jimbe

総合スコア12646

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

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

退会済みユーザー

退会済みユーザー

2019/02/07 08:06

そうですね、おっしゃる通り「考えているフリ」をさせたい状況です。 AsyncTaskですか、初めて聞きました。実際に試してみたのですがなかなか上手くいきません・・・ 別スレッドに処理を任せる、という点では同じことをしているように思ったのですが、AsyncTaskはまた違うのでしょうか?(軽く調べただけですので見当違いの質問だったらすいません) もう少し試行錯誤してみます
jimbe

2019/02/08 01:50 編集

まさしく別スレッドに任せるという同じ形です. そして, 時間がかかる処理をする際の基本的なクラスと思います. ただ, この回答の主は「別スレッド」では無く「プログレスによるブロック」です. Windows で重い処理をさせると, マウスカーソルが砂時計や円になってグルグル回りますね. そうなると, 処理が終わって矢印に戻るまで何も出来ません. それと同じにするということです. もし本当に CPU が自分の手を考えるのに時間が掛かっている場合も, このようにしなければならないはずです. CPU が手を打つ前にプレイヤが打つ訳には行かないですから. そして, AsyncTask はこのような場合に意識が必要な Android 特有の制限を, あまり意識しなくてすむように作られています. 「画面表示関係はメインスレッドで行う」ということと, 「メインスレッドでは時間のかかる処理を行わない」ということです. AsyncTask は, 主体である『別スレッドで』実行される doInBackground の他, その実行前後に『メインスレッドから』呼び出されるメソッドが定義できます. (進捗を表示するためのメソッドもあります.) 実行前メソッドでプログレスを表示し(画面をブロックし), doInBackground では(例えば2~5秒をランダムに)sleepし, 実行後メソッドでプログレスを消し(ブロックを解除し) CPU の手を表示してプレイヤの入力を待つ…という事がそのまま表現できます.
jimbe

2019/02/07 19:06

回答に書き忘れていましたが, invalidate は「画面を再表示する必要がある」とマーキングするだけです. 実際に再表示が行われるのはメインスレッドでそのマーキングが認識されてからです. そしてメインスレッドではその瞬間は onTouchEvent を実行中です. ですので, プレイヤの表示は「実行されない」のでは無く, onTouchEvent が終わった後に表示されたと思います.
退会済みユーザー

退会済みユーザー

2019/02/08 01:45

無事、実装することができました! 今見返すと、確かに回答の趣旨をはき違えてますね、 詳しい解説、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問