图形上下文只会在一个线程中绘制 [英] Graphics Context will only draw in one thread

查看:103
本文介绍了图形上下文只会在一个线程中绘制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作蛇的游戏,但是每当我尝试使用draw()方法更新画布时,新的蛇就不会绘制.它画在run线程中.我尝试了很多不同的方法,但似乎无法正常工作.

I am making a game of snake, but whenever I try to update my canvas in the draw() method, the new snake won't draw. It draws in the run thread. I have tried a bunch of different things, but I can't seem to get it working.

导入:

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");
    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绘制图形的更好方法,请告诉我.这是我可以找到自己正在做的事情的唯一方法.

If you know of a better way to draw graphics in JavaFX, please tell me. This is the only way I could find for what I am doing.

推荐答案

您的方法存在一些问题.

There are some problems with your approach.

  1. 您不需要自己的线程.
  2. 您只能使用JavaFX Thread修改活动场景图(包括画布).阅读 JavaFX并发文档:

JavaFX场景图表示JavaFX应用程序的图形用户界面,它不是线程安全的,只能从UI线程(也称为JavaFX Application线程)进行访问和修改.

The JavaFX scene graph, which represents the graphical user interface of a JavaFX application, is not thread-safe and can only be accessed and modified from the UI thread also known as the JavaFX Application thread.

  • 您的主应用程序类不应实现Runnable.
  • Your main application class should not implement Runnable.
  • 一些建议:

    1. 您可能会发现,将SceneGraph节点用于游戏对象比使用Canvas节点要容易,但两者都可以使用.
    2. 您可以使用游戏循环: //docs.oracle.com/javase/8/javafx/api/javafx/animation/AnimationTimer.html"rel =" nofollow noreferrer> AnimationTimer 作为使用AnimationTimer进行显示的示例.
    1. You may find it easier to use SceneGraph nodes for your game objects rather than a Canvas, but either should work.
    2. You can implement your game loop using an AnimationTimer as demoed here.
    3. Here is a sample of using an AnimationTimer for display.

    这篇关于图形上下文只会在一个线程中绘制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆