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

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

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

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

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

Q&A

解決済

1回答

5085閲覧

JavaFXにて、Thread.sleep()が望む動作をしてくれません。どなたか助けてください。

nuiri1343

総合スコア54

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

Java

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

0グッド

0クリップ

投稿2016/06/04 07:17

###現状の説明
長くなってしまってもうしわけないのですが、
下のソースコードは、丸とバツを交互につけていって
先に3個ならんだら勝ちというあのゲームをJavaFXにて実装しようとしたものです。

まだ製作途中なので、コンピューターは完全にランダムでマークを付ける状態なのですが
そこで、コンピューターが考えているふりをさせようと、
Thread.sleep(1000);
を挿入しました。

しかし、下のコードをコンパイルして実行しますと
プレイヤーがクリック→1秒待ってプレイヤーとコンピューターのマークが同時に描画される
という形になってしまっています。

自分の望んでいるのは、
プレイヤーがクリック→プレイヤーのマークが描画される→1秒待つ→コンピューターのマークが描画されるというものです。

Platform.runLaterを使えばいいのかとやってみましたが、
それでも結果は全くかわりませんでした。

質問
1, どうして下のコードだと自分の望むものが実装できないのでしょうか?
2, また、どうやれば望むものを実装できますか?

###該当のソースコード

java

1import javafx.application.Application; 2import javafx.application.Platform; 3import javafx.stage.Stage; 4import javafx.stage.Modality; 5import javafx.scene.Scene; 6import javafx.scene.canvas.Canvas; 7import javafx.scene.canvas.GraphicsContext; 8import javafx.scene.layout.VBox; 9import javafx.geometry.Pos; 10import javafx.scene.input.MouseEvent; 11import javafx.scene.layout.HBox; 12import javafx.geometry.Insets; 13import javafx.scene.control.Label; 14import javafx.scene.control.Button; 15 16public class Marubatsu extends Application{ 17 18 int[][] check = new int[3][3]; //0は何もなし、1はプレイヤー、2はコンピューター 19 int player = 0; //1なら先手、2なら後手 20 21 Canvas canvas = new Canvas(200,200); 22 GraphicsContext gc = canvas.getGraphicsContext2D(); 23 int turn = 0; 24 Boolean GameOver = false; 25 public void start(Stage stage){ 26 stage.setTitle("Marubatsu"); 27 stage.setResizable(false); 28 Stage primaryStage = new Stage(); 29 primaryStage.initOwner(stage); 30 primaryStage.initModality(Modality.APPLICATION_MODAL); 31 32 Button button1 = new Button("先手"); 33 Button button2 = new Button("後手"); 34 HBox hroot = new HBox(); 35 hroot.getChildren().addAll(button1,button2); 36 hroot.setPadding(new Insets(10,5,10,5)); 37 hroot.setSpacing(10.0); 38 hroot.setAlignment(Pos.CENTER); 39 primaryStage.setScene(new Scene(hroot)); 40 41 Label label = new Label("Game Start!"); 42 43 button1.setOnAction(event -> { 44 player = 1; 45 hroot.getChildren().clear(); 46 hroot.getChildren().add(label); 47 label.setOnMouseClicked(levent -> { 48 primaryStage.close(); 49 }); 50 }); 51 button2.setOnAction(event -> { 52 player = 2; 53 hroot.getChildren().clear(); 54 hroot.getChildren().add(label); 55 label.setOnMouseClicked(levent -> { 56 primaryStage.close(); 57 strokeCompute(); 58 }); 59 60 }); 61 62 VBox root = new VBox(); 63 root.setAlignment(Pos.CENTER); 64 65 root.getChildren().add(canvas); 66 67 gc.setLineWidth(4.0); 68 gc.strokeLine(80,40,80,160); 69 gc.strokeLine(120,40,120,160); 70 gc.strokeLine(40,80,160,80); 71 gc.strokeLine(40,120,160,120); 72 canvas.setMouseTransparent(false); 73 canvas.setOnMouseClicked(event -> { 74 strokePlayer(event); 75 }); 76 77 stage.setScene(new Scene(root)); 78 stage.show(); 79 primaryStage.show(); 80 for(int i=0;i<3;i++) 81 for(int j=0;j<3;j++) 82 check[i][j] = 0; 83 } 84 85 public void drawMark(int x,int y,int p){//マルかバツを書く 86 87 if(p==1){ 88 if(player == 1){ 89 gc.strokeOval(50+40*x,50+40*y,20,20); 90 }else{ 91 gc.strokeLine(50+40*x,50+40*y,70+40*x,70+40*y); 92 gc.strokeLine(50+40*x,70+40*y,70+40*x,50+40*y); 93 } 94 }else{ 95 if(player == 2){ 96 gc.strokeOval(50+40*x,50+40*y,20,20); 97 }else{ 98 gc.strokeLine(50+40*x,50+40*y,70+40*x,70+40*y); 99 gc.strokeLine(50+40*x,70+40*y,70+40*x,50+40*y); 100 } 101 } 102 } 103 public void strokePlayer(MouseEvent event){//プレイヤーが書く 104 int x=-1; 105 int y=-1; 106 if(GameOver) return; 107 if(event.getX()>=40&&160>=event.getX()&&event.getY()>=40&&160>=event.getY()){ 108 x = (int)((event.getX()-40)/40.0); 109 y = (int)((event.getY()-40)/40.0); 110 }else return; 111 if(check[x][y] == 1||check[x][y] == 2) return; 112 113 check[x][y] = 1; 114 turn++; 115 drawMark(x,y,1); 116 if(isGameEnd()) return; 117 118 119 120 Platform.runLater(new Runnable() { 121 @Override 122 public void run() { 123 strokeCompute() ;//コンピューターの次の手 124 } 125 }); 126 } 127 public void strokeCompute(){//コンピューターが書く 128 int x,y; 129 if(GameOver) return; 130 131 //考えているふりをする。 132 try{ 133 Thread.sleep(1000); 134 }catch(Exception e){} 135 136 while(true){ 137 x = new java.util.Random().nextInt(3); 138 y = new java.util.Random().nextInt(3); 139 if(check[x][y] != 0)continue; 140 break; 141 } 142 check[x][y] = 2; 143 turn++; 144 drawMark(x,y,2); 145 if(isGameEnd()) 146 return; 147 148 } 149 Boolean isGameEnd(){//勝敗がついているかどうか 150 if(turn <5) return false; 151 int iWin = 0; 152 for(int i=1;i<3;i++){ 153 if(check[0][0] == i&&check[1][1] == i&&check[2][2] == i){ 154 iWin = i; 155 } 156 if(check[2][0] == i&&check[1][1] == i&&check[0][2] == i){ 157 iWin = i; 158 } 159 } 160 for(int k=1;k<3;k++){ 161 for(int i=0;i<3;i++){ 162 if(check[0][i]==k&&check[1][i]==k&&check[2][i]==k){ 163 iWin=k; 164 break; 165 } 166 } 167 if(iWin>0) break; 168 } 169 for(int k=1;k<3;k++){ 170 for(int i=0;i<3;i++){ 171 if(check[i][0]==k&&check[i][1]==k&&check[i][2]==k){ 172 iWin=k; 173 break; 174 } 175 } 176 if(iWin>0) break; 177 } 178 if(iWin==0 && turn<9) 179 return false; 180 181 if(iWin==0) 182 System.out.println("引き分け"); 183 else if(iWin==1) 184 System.out.println("プレイヤーが勝ち"); 185 else 186 System.out.println("コンピューターが勝ち"); 187 GameOver = true; 188 return true; 189 } 190} 191

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

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

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

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

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

guest

回答1

0

ベストアンサー

JavaFXのUIスレッド上でsleepさせてしまうと画像更新ごと止まってしまいます。
sleepを行うのであれば、別スレッド上で待たせたうえで、
Platform.runLaterを使ってもとの処理に戻してやることでうまく動作します。

解決例としては、Threadを新規に作成し、
Runnable内でsleepさせたあとにPlatform.runLaterを使って
もとのUIスレッドに処理を戻してやり、strokeComputeを呼び出してやればよいかと思います。
すでに1秒待ったあとなので、strokeComputeの中で1秒待っていたコードは削除してよいです。

new Thread(new Runnable() { @Override public void run() { //考えているふりをする。 try { Thread.sleep(1000); } catch (Exception e) { } Platform.runLater(new Runnable() { @Override public void run() { strokeCompute();//コンピューターの次の手 } }); } }).start();

投稿2016/06/04 09:18

masaya_ohashi

総合スコア9206

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

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

nuiri1343

2016/06/04 17:15

この通りに書き直したら望む通りの動作が得られました! ありがとうございます! 質問が変わってしまい大変恐縮なのですが、 UIスレッドとはなんでしょうか? Runnableとはなんでしょうか new Thread().start(); というのはどういう意味なのでしょうか こういうこと全然わからないです。 どうか教えていただけないでしょうか 自分はJavaFXの勉強にあたり、JavaFX&Java8プログラミングという参考書を使っていますが こういう、詳しい動作やなぜそうなるのかといったことが全然説明されて無く 応用して自分で何かを作る時に全く役に立たないです。 どうやって勉強したらいいでしょうか おすすめの参考書やサイト、勉強方法などあればそれも教えていただけると助かります。 よろしくお願いいたします。
masaya_ohashi

2016/06/05 01:03 編集

例えばOSを現場監督者、スレッドを作業者とします。 UIスレッドさんは絵を書いたり、ボタンを押されたかどうかを監視するのが得意で、現場監督にそれらを一任されています。 UIスレッドさんは、絵を描き終わって手が空いたときに、絵を現場監督へ届け、現場監督はそれを我々ユーザに見せてくれます。つまり描き換わる絵をリアルタイムに我々が見ているわけではありません。 ボタンが押されたのを見たUIスレッドさんは、さて丸を描くかと働き始めます。そしてそのあとの手順書には1秒休み、バツを描けと書かれています。UIスレッドさんはバツを描いた「後に」手が空くので、現場監督に届くのは丸とバツが描かれたあとのものが提出されます。 これが同時に出てしまっていた理由です。 そこで現場監督は新しい作業者を雇います。別スレッドさん(new Thread().start())です。彼は渡された手順書(Runnable)を見て、自分は1秒後にUIスレッドさんにバツを描いてくれとお願いしに行く(Platform.runLater)ことになっています。 丸を描き終えたUIスレッドさんは、新しく雇われた別スレッドさんに、「この手順書でいまから作業して」と言うだけで、そのあとは手が空きます。UIスレッドさんは無事丸を描いたものを現場監督へ届けました。 UIスレッドさんから作業をお願いされた別スレッドさんは1秒後、UIスレッドさんに改めてバツを描く作業を始めてくださいとお願いするのです。 JavaFXは歴史が浅く、awtやSwingを使っていたユーザには苦手意識を持たれた可哀想なやつです。私もほとんど手探りで調べたものです。JavaFXについては私も「頑張ってください」としか言えず申し訳ないです。が、Javaのことならいろいろと為になるサイトはあります。参考書で躓いた時はそういったサイトを見て理解を深めていくとよいと思います。 JavaDrive http://www.javadrive.jp とほほのJava入門 http://www.tohoho-web.com/java/index.htm
nuiri1343

2016/06/05 07:30

とってもわかりやすい説明でありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問