Java / JavaFX事件处理程序和setFill()有问题

时间:2017-07-16 19:33:00

标签: java javafx colors mouseevent

我正在编写一款受Conway“生命游戏”启发的游戏。

虽然我已经计算出整体游戏逻辑(但没有编码),但是一旦玩家的第一次转弯结束,我仍然无法更改矩形对象的填充颜色。当我运行我的程序时,它会跳过对玩家一种颜色的要求(Color.BLUE)并直接进入玩家二的颜色(Color.RED)。

以下是代码:

//William Fisher
//July.11.2017
package cellularautomatagame;

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.canvas.*;
import javafx.scene.input.MouseEvent;
import static javafx.scene.paint.Color.*;


public class CellularAutomataGame extends Application {

@Override
public void start(Stage stage) {

   Group root = new Group();
   Scene s = new Scene(root, 300, 300, Color.BLACK);

   Canvas canvas = new Canvas(1280,720);
   GraphicsContext gc = canvas.getGraphicsContext2D();

   root.getChildren().add(canvas);

   stage.setScene(s);
   stage.show();

   gc.setFill(WHITE);
   gc.fillRect(0, 0, 5, 720);
   gc.fillRect(0, 0, 1280, 5);
   gc.fillRect(0, 715, 1280, 5);
   gc.fillRect(1275, 0, 5, 720);


    Player player1 = new Player();
    Player player2 = new Player();


    player1.playerFirstMove(root,canvas,Color.BLUE);
    player2.playerFirstMove(root,canvas,Color.RED);
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    launch(args);
}

}

//William Fisher
// July.11.2017
package cellularautomatagame;

import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import static javafx.scene.paint.Color.*;
import javafx.scene.shape.Rectangle;

public class Player {
    int firstMove = 0;

public void playerFirstMove(Group root,Canvas canvas,Color color){

    canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>(){
       @Override
        public void handle (MouseEvent e){
            while(firstMove < 1){
                if(e.getClickCount() == 1){
                    Rectangle r = new Rectangle(e.getX(),e.getY(),5,5);
                    r.setFill(color);
                    root.getChildren().add(r);
                    firstMove++;
                }
            }
       }
    });
    firstMove--;
}
}

/** (07/11/2017)Current Problem: The first player is unable to make their first move. Only the 
 * second player is able to make a first move.
 * 
 * (07/16/2017)Current Problem: Same as previous problem, changed the code so that a rectangle
 * object would spawn upon mouse click event. Problem possibly has to do with "setFill()" function.
 */

在主JavaFX方法的第52行,它显示了player1的第一个转弯,它应该调用playerFirstMove方法,并且一旦点击鼠标就允许产生蓝色矩形,如播放器第18行开始的playerFirstMove方法所示类。但是,单击鼠标时,会生成一个红色矩形而不是蓝色矩形。就好像程序跳过第52行的player1.playerfirstMove(...)并直接进入第53行的player2.playerfirstMove(...)。我已经试了好几个小时来解决这个小问题,阅读JavaFX API和搜索互联网。该程序正在做我想要它做的事情(每次鼠标点击只产生一个矩形),但似乎它正在跳过第52行的指令(player1.playerfirstMove(...))。

对我来说,似乎可能存在涉及setFill()函数的错误?

我会非常感谢任何帮助。

全部谢谢!

1 个答案:

答案 0 :(得分:1)

如果我理解正确,每次鼠标点击都应绘制当前玩家的矩形并转向下一个玩家。如果是这样,我重新编写代码以使Player具有颜色并仅绘制矩形逻辑:

class Player {
    private final Color color;

    Player(final Color color) {
        this.color = color;
    }

    void doSomething(final Group root, final double x, final double y) {
        Rectangle r = new Rectangle(x, y, 5, 5);
        r.setFill(color);
        root.getChildren().add(r);
    }
}

在主类中,我组织了循环迭代(使用Google guava collection utils),迭代器只允许当前玩家使用:

Player player1 = new Player(Color.BLUE);
Player player2 = new Player(Color.RED);
Player player3 = new Player(Color.YELLOW);

final Iterator<Player> playerIterator = Iterators.cycle(player1, player2, player3);

canvas.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
    if (e.getClickCount() == 1) {
        playerIterator.next().doSomething(root, e.getX(), e.getY());
    }
});

结果我甚至可能有3名玩家,每次点击只触发下一个玩家:

enter image description here

顺便说一句,这个解决方案允许拥有所需数量的玩家。