2016-12-19 4 views
0

私は現在、JavaFXでちょっと試合をしています。私はkeyEventsを捕まえるのにいくつかの問題がありました。JavaFX fireEvent StackOverflowError

今私はそれらをキャッチすることができますが、プログラムはjava.lang.StackOverflowErrorを投げて、キーが押されたときに期待したことをしませんでした。ここで

はメインクラスです:

public class WarbladeFX extends Application { 

    Game root; 

    public void start(Stage primaryStage) { 
     root = new Game(); 
     Scene scene = new Scene(root, 800, 600); 
     scene.setFill(new Color(0,0,0,1)); 


     scene.setOnKeyPressed(new EventHandler<KeyEvent>() { 
      public void handle(KeyEvent event) { 
       Event.fireEvent(root, event); 
      } 
     }); 
     scene.setOnKeyReleased(new EventHandler<KeyEvent>() { 
      public void handle(KeyEvent event) { 
       Event.fireEvent(root, event); 
      } 
     }); 


     primaryStage.setTitle("WarbladeFX"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 


    public static void main(String[] args) { 
     launch(args); 
    } 

} 

そして、ゲームのクラス:

public class Game extends Group { 

    Entity ship; 
    long delta; 
    HashSet<String> input = new HashSet<>(); 

    public Game() { 
     File f = new File("src/ressources/ship.gif"); 
     ship = new Entity(new Image("file:///" + f.getAbsolutePath().replace("\\", "/")) ,300, 300); 
     getChildren().add(ship); 

     setOnKeyPressed(new EventHandler<KeyEvent>() { 
      @Override 
      public void handle(KeyEvent event) { 
       //System.out.println(".handle()"); 
       String code = event.getCode().toString(); 

       if(!input.contains(code)) 
        input.add(code); 
      } 
     }); 

     setOnKeyReleased(new EventHandler<KeyEvent>() { 
      @Override 
      public void handle(KeyEvent event) { 
       String code = event.getCode().toString(); 
       input.remove(code); 
      } 
     }); 

     new AnimationTimer(){ 
      @Override 
      public void handle(long now) { 
       if(input.contains("LEFT")) 
        ship.setVelX(-1); 
       if(input.contains("RIGHT")) 
        ship.setVelX(1); 

       ship.move(now); 
       getChildren().clear(); 
       getChildren().add(ship); 
      } 
     }.start(); 
    } 
} 

いくつかの助けは非常に素晴らしいことです。

+1

を行うことができますスタックトレースを投稿してください。 –

+0

シーングラフのノードで発生したイベントは、親に親の親、親の親、最終的にはシーンまで「バブルアップ」します。シーンのイベントハンドラは、イベントを「ルート」に「リファイア」し、シーンにバブルして再び処理され、ルートに戻されます...など、実際には何を考えていますか?シーンのイベントハンドラを行うには? –

+0

私はゲームクラスのイベントを処理しようとしていますが、fireEventがなければ何もしません – Dicegamer

答えて

0

シーングラフのノードで発生したイベントは、親と親の親に、そして最終的にはシーンまですべて「上に」バブルアップします。したがって、シーンで定義したイベントハンドラは、rootにイベントを「リファイア」し、シーンにバブルして再び処理され、再びrootに戻されます。

Ifシーンのどこでもイベントをキャッチして、Gameクラスでそれらを処理したい場合は、Gameにいくつかのメソッドを定義してイベントを処理し、それらのメソッドを呼び出す必要があります。イベントを「浄化しない」。例えば

public class Game extends Group { 

    Entity ship; 
    long delta; 
    HashSet<String> input = new HashSet<>(); 

    public Game() { 
     File f = new File("src/ressources/ship.gif"); 
     ship = new Entity(new Image("file:///" + f.getAbsolutePath().replace("\\", "/")) ,300, 300); 
     getChildren().add(ship); 



     new AnimationTimer(){ 
      @Override 
      public void handle(long now) { 
       if(input.contains("LEFT")) 
        ship.setVelX(-1); 
       if(input.contains("RIGHT")) 
        ship.setVelX(1); 

       ship.move(now); 
       getChildren().clear(); 
       getChildren().add(ship); 
      } 
     }.start(); 
    } 

    public void keyDown(String key) { 
     if(!input.contains(key)) 
      input.add(key);  
    } 

    public void keyUp(String key) { 
     input.remove(code); 
    } 
} 

、その後、あなたが

public class WarbladeFX extends Application { 

    Game root; 

    public void start(Stage primaryStage) { 
     root = new Game(); 
     Scene scene = new Scene(root, 800, 600); 
     scene.setFill(new Color(0,0,0,1)); 


     scene.setOnKeyPressed(new EventHandler<KeyEvent>() { 
      public void handle(KeyEvent event) { 
       game.keyDown(event.getCode().toString()); 
      } 
     }); 
     scene.setOnKeyReleased(new EventHandler<KeyEvent>() { 
      public void handle(KeyEvent event) { 
       game.keyUp(event.getCode().toString()); 
      } 
     }); 


     primaryStage.setTitle("WarbladeFX"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 


    public static void main(String[] args) { 
     launch(args); 
    } 

} 
+0

これは動作しています、ありがとう! – Dicegamer

0

event-handleメソッドでイベントを再度発生させると、無限ループが生成されます。この方法でイベントを処理しようとします。つまり、ユーザーの入力に反応します。

+0

私はイベントを発生させないと、私はゲームクラス – Dicegamer

+0

のイベントを再処理するのではなく、イベントを処理するGameクラスのメソッド – user7291698