2016-12-22 12 views
0

私はヘビのゲームを作っていますが、draw()メソッドでキャンバスを更新しようとすると、新しいヘビは描画されません。それはrunスレッドを描画します。私はいろいろなことを試みましたが、それを働かせるようには見えません。グラフィックスコンテキストは1つのスレッドでのみ描画されます

輸入:

import javafx.application.Application; 
import javafx.event.*; 
import javafx.scene.*; 
import javafx.stage.*; 
import javafx.scene.control.*; 
import javafx.scene.layout.*; 
import javafx.geometry.*; 
import java.io.*; 
import java.util.*; 
import javafx.scene.input.KeyEvent; 
import javafx.event.EventHandler; 
import javafx.scene.text.Text; 
import javafx.scene.text.Font; 
import javafx.scene.text.*; 
import javafx.scene.paint.*; 
import javafx.scene.canvas.*; 

実際のクラス:

public class Snake extends Application implements Runnable 
{ 
    //Snake parts and locations 
    boolean dead; 
    int headX=0; 
    int headY=0; 
    // for the game 
    Group root = new Group(); 
    Scene snakeG = new Scene(root, 550, 550,Color.BLACK); 
    final Canvas canvas = new Canvas(550,550); 
    GraphicsContext gc = canvas.getGraphicsContext2D(); 
    //Start Game 
    VBox newGame = new VBox(3); 
    Scene startC = new Scene(newGame, 200, 200); 
    Label info = new Label("Snake Game \nCreated by: Austin James"); 
    Label rules = new Label("Rules\n1.) If you hit the edge you die\n2.) If you touch your snake you die\n3.)Collect fruit to increase your snakes size"); 
    Button startBut = new Button("Start Game"); 
    Stage startS; 

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

    @Override 
    public void start (Stage primaryStage)throws Exception 
    { 
     startS=primaryStage; 
     startS.setTitle("Snake"); 
     newGame.getChildren().addAll(info,rules,startBut); 
     newGame.setAlignment(Pos.CENTER); 
     startS.setScene(startC); 
     startS.show(); 

     startBut.setOnAction(e -> 
     { 
      startGame(); 
     }); 
    } 

    public void startGame() 
    { 
     System.out.println("Success"); 
     headX=275; 
     headY=275; 
     dead = false; 
     gc.clearRect(0,0,800,800); 
     startS.setScene(snakeG); 
     gc.setFill(Color.GREEN); 
     gc.fillRect(headX,headY,10,10); 
     root.getChildren().add(canvas); 
     (new Thread (new Snake())).start();  
    } 

    public void run() 
    { 
     draw(); 
    } 

    // draws the snake 
    public void draw() 
    { 
     System.out.println("DRAW STARTED"); 
     gc.setFill(Color.GREEN); 
     gc.fillRect(50,50,10,10); 
    } 
} 

あなたはJavaFXの中にグラフィックスを描画するためのより良い方法を知っていれば、教えてください。これが私がやっていることのために見つけることができる唯一の方法です。

答えて

3

あなたのアプローチにはいくつか問題があります。

  1. あなた自身のスレッドは必要ありません。
  2. JavaFXスレッドを使用して、アクティブシーングラフ(キャンバスを含む)のみを変更できます。 JavaFX concurrency documentationを読む

    JavaFXアプリケーションのグラフィカル・ユーザ・インタフェースを表すのJavaFXシーングラフ、スレッドセーフではなく、のみアクセスされ、また、JavaFXのアプリケーション・スレッドとして知られているUIスレッドから変更することができます。

  3. メインアプリケーションクラスにRunnableを実装しないでください。

ヒント:

  1. あなたはそれが簡単にあなたのゲームオブジェクトではなく、CanvasためSceneGraphノードを使用することを見つけるかもしれませんが、どちらかが動作するはずです。
  2. game loopAnimationTimerdemoed hereとして実装できます。
  3. ここにはusing an AnimationTimer for displayのサンプルがあります。
+0

自分自身のスレッドで 'GraphicsContext2d'を使用したことはありませんでした。すべての描画操作はUIスレッドから呼び出すことができると思います。私は、ソースを見てPlatform.isFxApplicationThread 'のためのチェックはありません()' – brian

+0

GraphicsContextのJavadocは、明らかに、彼らは、後で キャンバスノードの画像によって上にレンダリングされる場所__Eachコールはバッファ に必要 パラメータを押圧状態 レンダリングスレッド パルス.__このように、スレッドには完全に依存しません。 – Mordechai

+0

@MouseEventスレッドセーフではありません。バッファには同期がないため、バックグラウンドスレッドから変更すると、さまざまなリスクが発生します.FXアプリケーションスレッドがパルスを描画している間にバッファを変更することができます。つまり、FXアプリケーションスレッドは、単一パルス中のバッファの状態が不一致である。 (生存性などの他のリスクもあります) –

関連する問題