我正在用JavaFX構建Simon Says遊戲。我已經獲得了大部分工作,現在唯一的問題是當你運行遊戲時,它運行一個for循環來生成顏色,取決於你所在的級別。for循環中的JavaFX TimeLine正在跳過KeyFrames
它似乎顯示循環中的一種顏色,但它不會等待KeyFrame在它通過循環的其餘部分並存儲值之前完成。我如何讓循環等待KeyFrame完成,以顯示所有顏色變化?
package assign3;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
import javafx.animation.FillTransition;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.SequentialTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Question2 extends Application
{
public static final int RED = 1;
public static final int GREEN = 2;
public static final int BLUE = 3;
public static final int ORANGE = 4;
private int thisGameScore = 0;
private int level = 1;
private BorderPane obBorder;
private HBox obPane;
private HBox obStart;
private Timeline tlRed;
private Timeline tlBlue;
private Timeline tlGreen;
private Timeline tlOrange;
private SequentialTransition stList = new SequentialTransition();
private Button btStart;
private ArrayList<Integer> colours;
private ArrayList<Integer> guesses;
@Override
public void start(Stage obPrimeStage) throws Exception
{
boolean runGame = true;
int guessIndex = 0;
obBorder = new BorderPane();
obPane = new HBox();
obStart = new HBox();
Button btRed = new Button("Red");
Button btGreen = new Button("Green");
Button btBlue = new Button("Blue");
Button btOrange = new Button("Orange");
btStart = new Button("Start");
class RedTimeLine
{
Timeline tlRed;
RedTimeLine()
{
tlRed = new Timeline();
tlRed.getKeyFrames().add(new KeyFrame(Duration.ZERO,
new KeyValue(obBorder.backgroundProperty(),
new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY)))));
tlRed.getKeyFrames().add(new KeyFrame(Duration.seconds(1),
new KeyValue(obBorder.backgroundProperty(),
new Background(new BackgroundFill(Color.TRANSPARENT, CornerRadii.EMPTY, Insets.EMPTY)))));
}
}
tlBlue = new Timeline();
tlBlue.getKeyFrames().add(new KeyFrame(Duration.ZERO,
new KeyValue(obBorder.backgroundProperty(),
new Background(new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY)))));
tlBlue.getKeyFrames().add(new KeyFrame(Duration.seconds(1),
new KeyValue(obBorder.backgroundProperty(),
new Background(new BackgroundFill(Color.TRANSPARENT, CornerRadii.EMPTY, Insets.EMPTY)))));
tlGreen = new Timeline();
tlGreen.getKeyFrames().add(new KeyFrame(Duration.ZERO,
new KeyValue(obBorder.backgroundProperty(),
new Background(new BackgroundFill(Color.GREEN, CornerRadii.EMPTY, Insets.EMPTY)))));
tlGreen.getKeyFrames().add(new KeyFrame(Duration.seconds(1),
new KeyValue(obBorder.backgroundProperty(),
new Background(new BackgroundFill(Color.TRANSPARENT, CornerRadii.EMPTY, Insets.EMPTY)))));
tlOrange = new Timeline();
tlOrange.getKeyFrames().add(new KeyFrame(Duration.ZERO,
new KeyValue(obBorder.backgroundProperty(),
new Background(new BackgroundFill(Color.ORANGE, CornerRadii.EMPTY, Insets.EMPTY)))));
tlOrange.getKeyFrames().add(new KeyFrame(Duration.seconds(1),
new KeyValue(obBorder.backgroundProperty(),
new Background(new BackgroundFill(Color.TRANSPARENT, CornerRadii.EMPTY, Insets.EMPTY)))));
obStart.getChildren().add(btStart);
obPane.getChildren().addAll(btRed, btGreen, btBlue, btOrange);
obBorder.setCenter(obPane);
obBorder.setBottom(obStart);
obPane.setAlignment(Pos.CENTER);
obStart.setAlignment(Pos.CENTER);
Scene obScene = new Scene(obBorder, 400, 400);
obPrimeStage.setTitle("Simon Says");
obPrimeStage.setScene(obScene);
obPrimeStage.show();
btStart.setOnAction((ActionEvent start) -> {
colours = new ArrayList<>();
guesses = new ArrayList<>();
obChange.handle(start);
stList.play();
System.out.println("Started new game");
});
btRed.setOnAction((ActionEvent e) ->
{
guesses.add(RED);
if(guesses.get(guessIndex) != colours.get(guessIndex))
{
obStart.getChildren().add(btStart);
level = 1;
}
else
{
if(guesses.size() == colours.size())
{
level += 1;
colours = new ArrayList<>();
guesses = new ArrayList<>();
for(int i = 0; i < level; i++)
{
obChange.handle(e);
}
stList.play();
}
}
});
btGreen.setOnAction((ActionEvent e) ->
{
guesses.add(GREEN);
if(guesses.get(guessIndex) != colours.get(guessIndex))
{
obStart.getChildren().add(btStart);
level = 1;
}
else
{
if(guesses.size() == colours.size())
{
level += 1;
colours = new ArrayList<>();
guesses = new ArrayList<>();
for(int i = 0; i < level; i++)
{
obChange.handle(e);
}
stList.play();
}
}
});
btBlue.setOnAction((ActionEvent e) ->
{
guesses.add(BLUE);
if(guesses.get(guessIndex) != colours.get(guessIndex))
{
obStart.getChildren().add(btStart);
level = 1;
}
else
{
if(guesses.size() == colours.size())
{
level += 1;
colours = new ArrayList<>();
guesses = new ArrayList<>();
for(int i = 0; i < level; i++)
{
obChange.handle(e);
}
stList.play();
}
}
});
btOrange.setOnAction((ActionEvent e) ->
{
guesses.add(ORANGE);
if(guesses.get(guessIndex) != colours.get(guessIndex))
{
obStart.getChildren().add(btStart);
level = 1;
}
else
{
if(guesses.size() == colours.size())
{
level += 1;
guesses = new ArrayList<>();
for(int i = 0; i < level; i++)
{
obChange.handle(e);
}
stList.play();
}
}
});
}
class ChangeColour implements EventHandler<ActionEvent>
{
@Override
public void handle(ActionEvent arg0)
{
thisGameScore = 0;
int randomColour = (int)((Math.random() * 4) + 1);
if(randomColour == RED)
{
colours.add(RED);
stList.getChildren().add(new RedTimeLine());
}
else if(randomColour == BLUE)
{
colours.add(BLUE);
stList.getChildren().add(tlBlue);
}
else if(randomColour == GREEN)
{
colours.add(GREEN);
stList.getChildren().add(tlGreen);
}
else if(randomColour == ORANGE)
{
colours.add(ORANGE);
stList.getChildren().add(tlOrange);
}
obStart.getChildren().remove(btStart);
}
}
ChangeColour obChange = new ChangeColour();
public static void main(String[] args)
{
Application.launch(args);
}
}
您不需要發佈如此多的代碼來演示這一點,您可以創建一個[*最小*示例](https://stackoverflow.com/help/mcve),它仍然是可編譯和可運行的,並且僅演示問題在手。這樣做可以讓您獲得更好的答案的機會更大。 – jewelsea
另外:一旦你得到這個工作,我建議你發佈整個程序,就像你最初在http://codereview.stackexchange.com上的這個問題中發佈的那樣,並且讓那裏的人把它分開並給你如何申請的建議更好的代碼標準來提高代碼質量。我的猜測是,你會從中學到很多東西。 – jewelsea
@jewelsea我接受了你的建議,並刪除了這個問題不需要的所有超額代碼。在這一點上,我並不太擔心編碼標準,一旦我理解了語法背後的邏輯,我會整理它。一旦我有一切工作,我有一個編碼標準,我必須解決它遵守。 感謝您的意見! –