2017-09-18 14 views
0

whileループを持つスレッドを呼び出すゲームを作成しようとしています。私は基本的にボタンを押すと画面を切り替えるJFrameを使用しています。私が取得しようとしているのは、ボタンを押すと、タイルを描画してスレッドを呼び出します。しかし、私がボタンを押すと、ただ凍ります。ボタンが押されていて変更されない画面上にとどまります。私はスレッドを呼び出さないと変更されることに注意してください。また、私はwhileループの位置を変更しようとしましたが、どちらもうまくいきませんでした。Whileループを使用するとスクリプト全体がフリーズする

ドロースクリプト:

void loadLevel(String level) { 
    panel.remove(searchTA); 
    panel.remove(titleL); 
    panel.remove(search2B); 
    panel.repaint(); 

    this.level = level; 

    int x = 160; 
    int y = 140; 

    int tile = 0; 
    int line = 0; 

    for (int i = 0; i < 13; i++) { 
     for (int j = 0; j < 13; j++) { 
      String formula = (String 
        .valueOf(readFile("resources/Base Levels/Back Layer/" + level, line).charAt(tile)) 
        + String.valueOf(readFile("resources/Base Levels/Front Layer/" + level, line).charAt(tile))); 
      if (formula.equals("00")) { 
       try { 
        BufferedImage img; 
        BufferedImage c; 
        img = ImageIO.read(clear); 
        c = resize(img, 50, 50); 
        JLabel lb = new JLabel(new ImageIcon(c)); 
        lb.setLocation(x, y); 
        lb.setSize(50, 50); 
        panel.add(lb); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } else if (formula.equals("01")) { 
       try { 
        BufferedImage img; 
        BufferedImage c; 
        img = ImageIO.read(goal); 
        c = resize(img, 50, 50); 
        JLabel lb = new JLabel(new ImageIcon(c)); 
        lb.setLocation(x, y); 
        lb.setSize(50, 50); 
        panel.add(lb); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } else if (formula.equals("02")) { 
       try { 
        BufferedImage img; 
        BufferedImage c; 
        img = ImageIO.read(wall); 
        c = resize(img, 50, 50); 
        JLabel lb = new JLabel(new ImageIcon(c)); 
        lb.setLocation(x, y); 
        lb.setSize(50, 50); 
        panel.add(lb); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
      x = x + 50; 
      tile++; 
     } 
     tile = 0; 
     line++; 
     x = 160; 
     y = y + 50; 
    } 

    play.run(); 
} 

スレッド:

public Thread play = new Thread(new Runnable() { 
    public void run() { 

     panel.revalidate(); 
     panel.repaint(); 

     String tileOn = new String(); 

     String[] tiles = new String[169]; 

     int tile = 0; 

     for (int i = 1; i < 14; i++) { 
      for (int b = 1; b < 14; b++) { 

       tiles[tile] = String 
         .valueOf(readFile("resources/Base Levels/Back Layer/" + level, i - 1).charAt(b - 1)) 
         + String.valueOf(readFile("resources/Base Levels/Front Layer/" + level, i - 1).charAt(b - 1)); 

       tile++; 
      } 
     } 

     while (!tileOn.equals("01")) { 

     } 

    } 
}); 

そして私は凍結を言うとき、私は凍結を意味します。それを閉じるためにJFrameの右上にあるXを押すことさえできません。 Eclipse(IDE)に戻り、スクリプトを停止する必要があります。またwhileループを削除しようとしたためにwhileループが問題を引き起こしていることがわかりました。

+2

の凍結を解除する必要があります。 – markspace

+0

'tileon'はどのように値を変更しますか? – VHS

+0

もちろん、フリーズします。タイル "01"でない場合、whileループの終了条件はありません。whileループを終了するには、その条件をfalseにします。 – Tyler

答えて

1

問題は、Johny Rathboneのanswserに記載されている問題とそのanswserに関するコメントの組み合わせです。

whileループでは、新しい文字列として初期化した直後にwhile (!tileOn.equals("01"))を実行します。したがって、これは無限のループになります。しかし、これはバックグラウンドスレッド上で実行しようとするので問題はありません。

play.start()の代わりにplay.run()を使用すると、これはメインスレッドで実行されます。

これらの2つの方法との違いはstart()が実際に新しいスレッドを開始し、run()を呼び出すと、メインスレッド上でrun()メソッドを実行する一方で、その上にrun()メソッドを実行していることです。

あなたはplay.start()play.run()を変更するのであれば、それは、実行() ``(開始、スレッドを起動しません) `し`を呼び出すのでもしか

0
while (!tileOn.equals("01")) { 

この行は、新しい文字列として呼び出すときを除いて、 'tileOn'への唯一の参照です。そこに「01」と等しくないので、これは常に真実です。そして、あなたはループ内に何も持っていないので、whileループは常に実行されます。なぜなら、そのループ内にその条件を解除するものは何もないからです。

+1

私は彼がバックグラウンドスレッドでそのループを起動しようとしていると思うし、無限ループは実際に彼のプログラムをフリーズしないだろう。彼のエラーは 'start()'の代わりに 'run()'を呼び出す可能性が高いです。 – markspace

関連する問題