简体   繁体   English

如何在javafx中拥有一个场景

[英]how to have a scene over another in javafx

I'm writing a small game. 我正在写一个小游戏。 And i want a pause menu over the blured game menu to be shown when esc is pressed in the middle of the game. 我希望在游戏中间按下esc时显示模糊游戏菜单上的暂停菜单。 What I do is that i make a new scene which has a stackPane wrapping the past root and the pause menu root and then i set the opacity of the past root 0.4 . 我做的是我创建一个新场景,其中stackPane包裹过去的根和暂停菜单根,然后我设置过去根0.4的不透明度。

Then when the resume button in the pause menu is clicked i change the opacity back to 1 and set the past scene on stage but then its freezed. 然后,当单击暂停菜单中的恢复按钮时,我将不透明度更改回1并在舞台上设置过去的场景,然后将其冻结。 does anyone know why? 有谁知道为什么? can anyone help me achieve this? 谁能帮我实现这个目标?

Here is the part i make the new scene and then i put this on stage: 这是我制作新场景的部分然后我把它放在舞台上:

        StackPane wrapper = new StackPane();
        previousScene = main.getPrimaryStage().getScene();
        previousScene.getRoot().setOpacity(.4);
        vBox.setId("pausedWrapper");
        wrapper.getChildren().add(previousScene.getRoot());
        wrapper.getChildren().add(vBox);
        scene = new Scene(wrapper, 1200, 700);
        return scene;

Here is the part i change it back to where it was: 以下是我将其更改回原来的部分:

        resumeGame.setOnAction(event -> {
            System.out.println("game resumed!");
            previousScene.getRoot().setOpacity(1);
            main.getPrimaryStage().setScene(previousScene);
        });

But then it does not work and the opacity does not change back to normal and the strange thing is when i check the sound on box the music is played but the box does not get checked like everything works but the view is freezed. 但它不起作用,不透明度不会恢复正常,奇怪的是当我检查音箱上的声音时播放音乐,但是盒子没有得到检查,就像一切正常但视图被冻结了。

A node cannot be part of two different scene graphs. 节点不能是两个不同场景图的一部分。 This happens in your code to the root of previousScene , because it is part of both previousScene and the new scene you create in your first block of code. 这在您的代码中发生在previousScene的根目录中,因为它是previousScene和您在第一个代码块中创建的新场景的一部分。 Most likely what is happening is that it is removed from the first scene when you add it to the second (though it is hard to tell from the code you posted). 最有可能发生的事情是,当你将它添加到第二个场景时,它会从第一个场景中删除(尽管从你发布的代码中很难说出来)。

Consider instead using a Popup to display the pauseMenu on top of the existing window, or just use a modal Stage with undecorated StageStyle , as in the following SSCCE: 请考虑使用Popup在现有窗口的顶部显示pauseMenu ,或者只使用带有未修饰的StageStyle的模式Stage ,如下面的SSCCE所示:

import javafx.animation.Animation;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Modality;
import javafx.stage.Popup;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.util.Duration;

public class PauseExample extends Application {

    @Override
    public void start(Stage primaryStage) {

        Rectangle rect = new Rectangle(50, 50, 50, 50);
        rect.setFill(Color.CORAL);

        TranslateTransition animation = createAnimation(rect);

        Button pauseButton = new Button("Pause");

        Pane pane = new Pane(rect);
        pane.setMinSize(600, 150);

        BorderPane root = new BorderPane(pane, null, null, pauseButton, new Label("This is\nthe main\nscene"));

        pauseButton.setOnAction(e -> {
            animation.pause();
            root.setEffect(new GaussianBlur());

            VBox pauseRoot = new VBox(5);
            pauseRoot.getChildren().add(new Label("Paused"));
            pauseRoot.setStyle("-fx-background-color: rgba(255, 255, 255, 0.8);");
            pauseRoot.setAlignment(Pos.CENTER);
            pauseRoot.setPadding(new Insets(20));

            Button resume = new Button("Resume");
            pauseRoot.getChildren().add(resume);

            Stage popupStage = new Stage(StageStyle.TRANSPARENT);
            popupStage.initOwner(primaryStage);
            popupStage.initModality(Modality.APPLICATION_MODAL);
            popupStage.setScene(new Scene(pauseRoot, Color.TRANSPARENT));


            resume.setOnAction(event -> {
                root.setEffect(null);
                animation.play();
                popupStage.hide();
            });

            popupStage.show();
        });

        BorderPane.setAlignment(pauseButton, Pos.CENTER);
        BorderPane.setMargin(pauseButton, new Insets(5));
        Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private TranslateTransition createAnimation(Rectangle rect) {
        TranslateTransition animation = new TranslateTransition(Duration.seconds(1), rect);
        animation.setByX(400);
        animation.setCycleCount(Animation.INDEFINITE);
        animation.setAutoReverse(true);
        animation.play();
        return animation;
    }

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM