我试图创建一个游戏,每次当游戏控制的圆圈与"敌人"精灵相交,将有一个标签显示旁边的圆圈,说"哎哟".

Label ouch = new Label("ouch");
        pane.getChildren().add(ouch);

        for(StackPane s:sprites){
            new AnimationTimer(){
                double speed = (Math.random()*1 +.1 );
                double dx = speed * Math.cos(Math.random()*5 +1);
                double dy = speed * Math.sin(Math.random()*5 +1);
                @Override
                public void handle(long now){
                    s.setLayoutX(s.getLayoutX()+dx);
                    Bounds bounds = pane.getLayoutBounds();
                    s.setLayoutY(s.getLayoutY()+dy);                
                    if((s.getLayoutX() <=(bounds.getMinX()))|| (s.getLayoutX() + s.getWidth() >=(bounds.getMaxX()))){
                        dx = -dx;
                    }
                    if((s.getLayoutY() -10 <=(bounds.getMinY())) || (s.getLayoutY() + s.getHeight() +10 >=(bounds.getMaxY()))){
                        dy = -dy;
                    }
                    if(c.getBoundsInParent().intersects(s.getBoundsInParent())){
                        ouch.setVisible(true);
                        ouch.setTranslateX(c.getTranslateX());
                        ouch.setTranslateY(c.getTranslateY()+c.getRadius()+20);

                    }
                    else{ouch.setVisible(false);}
                }
            }.start();
        }

以下是完整的代码,如果需要:

import java.util.Random;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.scene.control.Button;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.PasswordField;
import javafx.scene.control.Label;
import javafx.geometry.Pos;
import javafx.scene.control.TextField;
import javafx.scene.text.Font;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.animation.KeyFrame;
import javafx.scene.text.FontWeight;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.Pane;
import javafx.geometry.Insets;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Polygon;
import javafx.scene.shape.CubicCurve;
import javafx.scene.shape.Line;
import javafx.util.Duration;
import javafx.animation.Timeline;
import javafx.scene.control.Alert;
import javafx.scene.shape.Arc;
import javafx.scene.input.MouseEvent;
import javafx.scene.Node;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.text.Text;
import javafx.scene.shape.StrokeType;
import java.util.ArrayList;
import javafx.geometry.Bounds;

public class Game extends Application{
    Stage window;

    Text bottomText = new Text();
    private final Integer startTime = 10;
    private Integer seconds = startTime;
    private Integer score = 30;
    
    @Override   
    public void start(Stage PrimaryStage){
        
                
        Image mouse = new Image("C:\\Users\\1559990\\Desktop\\images\\mouse.jpg");
        ImageView image = new ImageView(mouse);
        Label label = new Label("Times up!");
        Label label2 = new Label("Your score is: " + score);
        VBox vbox = new VBox(20);
        vbox.getChildren().addAll(image,label,label2);
        vbox.setAlignment(Pos.CENTER);      
        Scene scene2 = new Scene(vbox,600,600);
        
        Color yaleBlue = Color.web("154179");
        Color lightBlue = Color.web("9FC2CC");
        
        window = PrimaryStage;
        window.setTitle("Game");
        BorderPane borderPane = new BorderPane();
        
        bottomText.setFont(Font.font("Calibri",FontWeight.BOLD,100));
        bottomText.setFill(lightBlue);
        //bottomText.setStrokeWidth(2);
        //bottomText.setStroke(lightBlue);
        //bottomText.setStrokeType(StrokeType.OUTSIDE);
        bottomText.setText(startTime.toString());
        
        Text topText = new Text("GAME");
        topText.setFont(Font.font("Arial",FontWeight.BOLD,50));
        topText.setFill(yaleBlue);
        topText.setStrokeWidth(1);
        topText.setStroke(lightBlue);
        topText.setStrokeType(StrokeType.OUTSIDE);
        
        //borderPane.setBottom(bottomText);
        borderPane.setAlignment(bottomText,Pos.CENTER);
        borderPane.setTop(topText);
        borderPane.setAlignment(topText,Pos.CENTER);
        borderPane.setPadding(new Insets(10,10,10,10));

        Scene scene = new Scene(borderPane,600,600);
        window.setScene(scene);
        Pane pane = new Pane();

        ArrayList<StackPane> sprites = new ArrayList<StackPane>();
        String[] browTypes = new String[]{"angry","sad","normal"};
        
        for(int i = 0;i<=5;i++){
            Color randomColor = Color.rgb((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255));  
            int browIndex = (int)(Math.random()*2+1);
            StackPane sprite = new Human(randomColor,0.7,browTypes[browIndex]).getBody();
            sprites.add(sprite);
        }
        
        StackPane sp = new StackPane();
        for(StackPane s:sprites){
            pane.getChildren().addAll(s);
            s.relocate(250,250);
        }
        sp.getChildren().addAll(bottomText,pane);
        
        borderPane.setCenter(sp);
        borderPane.setMaxSize(600,100);
        
        
        //moving
        ArrayList<String> allKeyPressed = new ArrayList<String>();
        Circle c = new Circle(10);
        pane.getChildren().add(c);
        
        //add up/left/right/down from allKeyPressed
        scene.setOnKeyPressed(new EventHandler<KeyEvent>(){
            @Override
            public void handle(KeyEvent event){
                if(event.getCode() == KeyCode.W){
                    if(!(hasMultiple(allKeyPressed,"up"))){
                        allKeyPressed.add("up");
                    }
                }
                if(event.getCode() == KeyCode.A){
                    if(!(hasMultiple(allKeyPressed,"left"))){
                        allKeyPressed.add("left");
                    }
                }
                if(event.getCode() == KeyCode.S){
                    if(!(hasMultiple(allKeyPressed,"down"))){
                        allKeyPressed.add("down");
                    }
                }
                if(event.getCode() == KeyCode.D){
                    if(!(hasMultiple(allKeyPressed,"right"))){
                        allKeyPressed.add("right");
                    }
                }
            }
        });
        
        //remove up/left/right/down from allKeyPressed
        scene.setOnKeyReleased(new EventHandler<KeyEvent>(){
            @Override
            public void handle(KeyEvent event){
                if(event.getCode() == KeyCode.W){
                    if(hasMultiple(allKeyPressed,"up")){
                        allKeyPressed.remove(getIndex(allKeyPressed,"up"));
                    }
                }
                if(event.getCode() == KeyCode.A){
                    if(hasMultiple(allKeyPressed,"left")){
                        allKeyPressed.remove(getIndex(allKeyPressed,"left"));
                    }
                }
                if(event.getCode() == KeyCode.S){
                    if(hasMultiple(allKeyPressed,"down")){
                        allKeyPressed.remove(getIndex(allKeyPressed,"down"));
                    }
                }
                if(event.getCode() == KeyCode.D){
                    if(hasMultiple(allKeyPressed,"right")){
                        allKeyPressed.remove(getIndex(allKeyPressed,"right"));
                    }
                }
            }
        });
        
        //moving
        new AnimationTimer(){
            Bounds bounds = borderPane.getBoundsInLocal();
            @Override
            public void handle(long how){
                if(hasMultiple(allKeyPressed,"up") && (c.getTranslateY() - c.getRadius() -100>= bounds.getMinY())){
                    c.setTranslateY(c.getTranslateY()-5 );
                }
                if(hasMultiple(allKeyPressed,"down") && (c.getTranslateY() + c.getRadius()<= bounds.getMaxY()-80)){
                    c.setTranslateY(c.getTranslateY()+5);
                }
                if(hasMultiple(allKeyPressed,"left") && (c.getTranslateX() >= bounds.getMinX() + 20)){
                    c.setTranslateX(c.getTranslateX()-5);
                }
                if(hasMultiple(allKeyPressed,"right") && (c.getTranslateX() <= bounds.getMaxX()-40)){
                    c.setTranslateX(c.getTranslateX()+5);
                }
            }
        }.start();
        
        Label ouch = new Label("ouch");
        pane.getChildren().add(ouch);

        for(StackPane s:sprites){
            new AnimationTimer(){
                double speed = (Math.random()*1 +.1 );
                double dx = speed * Math.cos(Math.random()*5 +1);
                double dy = speed * Math.sin(Math.random()*5 +1);
                @Override
                public void handle(long now){
                    s.setLayoutX(s.getLayoutX()+dx);
                    Bounds bounds = pane.getLayoutBounds();
                    s.setLayoutY(s.getLayoutY()+dy);                
                    if((s.getLayoutX() <=(bounds.getMinX()))|| (s.getLayoutX() + s.getWidth() >=(bounds.getMaxX()))){
                        dx = -dx;
                    }
                    if((s.getLayoutY() -10 <=(bounds.getMinY())) || (s.getLayoutY() + s.getHeight() +10 >=(bounds.getMaxY()))){
                        dy = -dy;
                    }
                    if(c.getBoundsInParent().intersects(s.getBoundsInParent())){
                        ouch.setVisible(true);
                        ouch.setTranslateX(c.getTranslateX());
                        ouch.setTranslateY(c.getTranslateY()+c.getRadius()+20);

                    }
                    else{ouch.setVisible(false);}
                }
            }.start();
        }
        
        
        Timeline time = new Timeline();
        time.setCycleCount(Timeline.INDEFINITE);
        if(time != null){
            time.stop();
        }
        KeyFrame frame = new KeyFrame(Duration.seconds(1),new EventHandler<ActionEvent>(){
            @Override
            public void handle(ActionEvent event){
                seconds--;
                bottomText.setText(seconds.toString());
                if(seconds<=0){
                    time.stop();
                    //window.setScene(scene2);
                }
            }
        });
        time.getKeyFrames().add(frame);
        time.playFromStart();

        
        window.show();


    }

    
    public static void main(String[] args){
        launch(args);
    }
    //helper detect if up/left/down/right is in allKeyPressed
    private boolean hasMultiple(ArrayList<String> keys,String arrow){
        for(String s:keys){
            if(s.equals(arrow)){
                return true;
            }
        }
        return false;
    }
    
    //help to know the index where the w/s/a/d is at in the allKeyPressed
    private int getIndex(ArrayList<String>keys,String arrow){
        for(int i = 0; i<keys.size();i++){
            if(keys.get(i).equals(arrow)){
                return i;
            }
        }
        return -1;
    }

}

我想到的是在AnimationTimer中设置if—statement,所以如果圆的边界与敌人精灵的边界相交,那么"哎哟"文本将被设置为可见.如果它们不相交,则不会显示"哎哟"的文字 然而,我的问题是,这种效果只会发生在许多精灵中的一个,而不是其他精灵.我测试了我的条件if(圆的边界相交于精灵的边界),让系统打印出一些随机文本,我的条件似乎是因为当圆和精灵相交时,东西确实被打印出来了. 我真的很困惑,我会感谢任何帮助

推荐答案

首先,我同意 comments 中提出的所有建议.请try 考虑这些建议.

然而,我的问题是,这种效果只会发生在一个 很多精灵而不是其他精灵

请注意,100始终是精灵列表中的最后一个精灵;).

说到这个问题,"哎哟"Label只显示在最后一个精灵上而不是其他精灵上的主要原因是你在for循环中包含AnimationTimers代码的方式.

所有的定时器将按顺序执行,重叠判断在其自己的定时器中独立进行.所以,假设Sprite1与Circle相交,并将标签可见性变为true,剩余的Sprite计时器中的下一个判断将将可见性变为false(当它们不重叠时).这就是为什么,只有最后一个精灵是有效的工作,因为没有其他进一步的精灵判断发生(关闭它):)

Solution:

解决这个问题的一种方法是一次判断所有精灵的重叠判断,然后决定标签的可见性,如果至少有一个精灵是重叠的.

因此,我们可以优化代码,使for循环仅使用一个AnimationTimer进行重叠判断.类似于:

new AnimationTimer() {
    double speed = (Math.random() * 1 + .1);
    double dx = speed * Math.cos(Math.random() * 5 + 1);
    double dy = speed * Math.sin(Math.random() * 5 + 1);

    @Override
    public void handle(long now) {
        boolean intersected = false;
        for (StackPane s : sprites) {

            // YOUR LOGIC OF MOVING THE SPRITES HERE

            if (c.getBoundsInParent().intersects(s.getBoundsInParent())) {
                intersected = true;
            }
        }
        if(intersected){
            ouch.setVisible(true);
            ouch.setTranslateX(c.getTranslateX());
            ouch.setTranslateY(c.getTranslateY() + c.getRadius() + 20);
        } else {
            ouch.setVisible(false);
        }
    }
}.start();

但上面的代码有一个问题.所有的精灵都会有相同的速度或位置计算.因此,为了解决这个问题,我们可以将这个逻辑移到它自己的类中(对于每个子画面),然后我们进行重叠判断.

// First create each separate move service for each sprite.
List<SpriteService> spriteServices = sprites.stream().map(sprite -> new SpriteService(sprite, pane)).collect(Collectors.toList());

new AnimationTimer() {
    @Override
    public void handle(long now) {
        boolean intersected = false;
        for (SpriteService spriteService : spriteServices) {
            spriteService.move();
            if (c.getBoundsInParent().intersects(spriteService.getSprite().getBoundsInParent())) {
                intersected = true;
            }
        }
        if (intersected) {
            ouch.setVisible(true);
            ouch.setTranslateX(c.getTranslateX());
            ouch.setTranslateY(c.getTranslateY() + c.getRadius() + 20);
        } else {
            ouch.setVisible(false);
        }
    }
}.start();

class SpriteService {
    double speed = (Math.random() * 1 + .1);
    double dx = speed * Math.cos(Math.random() * 5 + 1);
    double dy = speed * Math.sin(Math.random() * 5 + 1);

    StackPane s;
    Pane pane;

    public SpriteService(StackPane sp, Pane p) {
        s = sp;
        pane = p;
    }

    public void move() {
        s.setLayoutX(s.getLayoutX() + dx);
        s.setLayoutY(s.getLayoutY() + dy);
        Bounds bounds = pane.getLayoutBounds();
        if ((s.getLayoutX() <= (bounds.getMinX())) || (s.getLayoutX() + s.getWidth() >= (bounds.getMaxX()))) {
            dx = -dx;
        }
        if ((s.getLayoutY() - 10 <= (bounds.getMinY())) || (s.getLayoutY() + s.getHeight() + 10 >= (bounds.getMaxY()))) {
            dy = -dy;
        }
    }

    public StackPane getSprite() {
        return s;
    }
}

下面是一个使用上述方法的代码的快速演示.100

enter image description here

import javafx.animation.AnimationTimer;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.StrokeType;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Game extends Application {
    Stage window;

    Text bottomText = new Text();
    private final Integer startTime = 10;
    private Integer seconds = startTime;
    private Integer score = 30;

    @Override
    public void start(Stage PrimaryStage) throws MalformedURLException {
        Label label = new Label("Times up!");
        Label label2 = new Label("Your score is: " + score);
        VBox vbox = new VBox(20);
        vbox.getChildren().addAll(label, label2);
        vbox.setAlignment(Pos.CENTER);

        Color yaleBlue = Color.web("154179");
        Color lightBlue = Color.web("9FC2CC");

        window = PrimaryStage;
        window.setTitle("Game");
        BorderPane borderPane = new BorderPane();

        bottomText.setFont(Font.font("Calibri", FontWeight.BOLD, 100));
        bottomText.setFill(lightBlue);
        bottomText.setText(startTime.toString());

        Text topText = new Text("GAME");
        topText.setFont(Font.font("Arial", FontWeight.BOLD, 50));
        topText.setFill(yaleBlue);
        topText.setStrokeWidth(1);
        topText.setStroke(lightBlue);
        topText.setStrokeType(StrokeType.OUTSIDE);

        borderPane.setAlignment(bottomText, Pos.CENTER);
        borderPane.setTop(topText);
        borderPane.setAlignment(topText, Pos.CENTER);
        borderPane.setPadding(new Insets(10, 10, 10, 10));

        Scene scene = new Scene(borderPane, 600, 600);
        window.setScene(scene);
        Pane pane = new Pane();

        List<StackPane> sprites = new ArrayList<StackPane>();
        String[] browTypes = new String[]{"angry", "sad", "normal"};

        for (int i = 0; i <= 5; i++) {
            Color randomColor = Color.rgb((int) (Math.random() * 255), (int) (Math.random() * 255), (int) (Math.random() * 255));
            int browIndex = (int) (Math.random() * 2 + 1);
            StackPane sprite = new Human(randomColor, 0.7, browTypes[browIndex], i).getBody();
            sprites.add(sprite);
        }

        StackPane sp = new StackPane();
        for (StackPane s : sprites) {
            pane.getChildren().addAll(s);
            s.relocate(250, 250);
        }
        sp.getChildren().addAll(bottomText, pane);

        borderPane.setCenter(sp);
        borderPane.setMaxSize(600, 100);


        //moving
        ArrayList<String> allKeyPressed = new ArrayList<String>();
        Circle c = new Circle(10);
        pane.getChildren().add(c);

        //add up/left/right/down from allKeyPressed
        scene.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.W) {
                if (!(hasMultiple(allKeyPressed, "up"))) {
                    allKeyPressed.add("up");
                }
            }
            if (event.getCode() == KeyCode.A) {
                if (!(hasMultiple(allKeyPressed, "left"))) {
                    allKeyPressed.add("left");
                }
            }
            if (event.getCode() == KeyCode.S) {
                if (!(hasMultiple(allKeyPressed, "down"))) {
                    allKeyPressed.add("down");
                }
            }
            if (event.getCode() == KeyCode.D) {
                if (!(hasMultiple(allKeyPressed, "right"))) {
                    allKeyPressed.add("right");
                }
            }
        });

        //remove up/left/right/down from allKeyPressed
        scene.setOnKeyReleased(event -> {
            if (event.getCode() == KeyCode.W) {
                if (hasMultiple(allKeyPressed, "up")) {
                    allKeyPressed.remove(getIndex(allKeyPressed, "up"));
                }
            }
            if (event.getCode() == KeyCode.A) {
                if (hasMultiple(allKeyPressed, "left")) {
                    allKeyPressed.remove(getIndex(allKeyPressed, "left"));
                }
            }
            if (event.getCode() == KeyCode.S) {
                if (hasMultiple(allKeyPressed, "down")) {
                    allKeyPressed.remove(getIndex(allKeyPressed, "down"));
                }
            }
            if (event.getCode() == KeyCode.D) {
                if (hasMultiple(allKeyPressed, "right")) {
                    allKeyPressed.remove(getIndex(allKeyPressed, "right"));
                }
            }
        });

        //moving
        new AnimationTimer() {
            Bounds bounds = borderPane.getBoundsInLocal();

            @Override
            public void handle(long how) {
                if (hasMultiple(allKeyPressed, "up") && (c.getTranslateY() - c.getRadius() - 100 >= bounds.getMinY())) {
                    c.setTranslateY(c.getTranslateY() - 5);
                }
                if (hasMultiple(allKeyPressed, "down") && (c.getTranslateY() + c.getRadius() <= bounds.getMaxY() - 80)) {
                    c.setTranslateY(c.getTranslateY() + 5);
                }
                if (hasMultiple(allKeyPressed, "left") && (c.getTranslateX() >= bounds.getMinX() + 20)) {
                    c.setTranslateX(c.getTranslateX() - 5);
                }
                if (hasMultiple(allKeyPressed, "right") && (c.getTranslateX() <= bounds.getMaxX() - 40)) {
                    c.setTranslateX(c.getTranslateX() + 5);
                }
            }
        }.start();

        Label ouch = new Label("ouch");
        pane.getChildren().add(ouch);

        // previousAnimationTimer(sprites, pane, c, ouch);
        modifiedAnimationTimer(sprites, pane, c, ouch);

        Timeline time = new Timeline();
        time.setCycleCount(Timeline.INDEFINITE);
        if (time != null) {
            time.stop();
        }
        KeyFrame frame = new KeyFrame(Duration.seconds(1), new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                seconds--;
                bottomText.setText(seconds.toString());
                if (seconds <= 0) {
                    time.stop();
                    //window.setScene(scene2);
                }
            }
        });
        time.getKeyFrames().add(frame);
        time.playFromStart();
        window.show();
    }


    private void previousAnimationTimer(List<StackPane> sprites, Pane pane, Circle c, Label ouch) {
        for (StackPane s : sprites) {
            new AnimationTimer() {
                double speed = (Math.random() * 1 + .1);
                double dx = speed * Math.cos(Math.random() * 5 + 1);
                double dy = speed * Math.sin(Math.random() * 5 + 1);

                @Override
                public void handle(long now) {
                    s.setLayoutX(s.getLayoutX() + dx);
                    Bounds bounds = pane.getLayoutBounds();
                    s.setLayoutY(s.getLayoutY() + dy);
                    if ((s.getLayoutX() <= (bounds.getMinX())) || (s.getLayoutX() + s.getWidth() >= (bounds.getMaxX()))) {
                        dx = -dx;
                    }
                    if ((s.getLayoutY() - 10 <= (bounds.getMinY())) || (s.getLayoutY() + s.getHeight() + 10 >= (bounds.getMaxY()))) {
                        dy = -dy;
                    }
                    if (c.getBoundsInParent().intersects(s.getBoundsInParent())) {
                        ouch.setVisible(true);
                        ouch.setTranslateX(c.getTranslateX());
                        ouch.setTranslateY(c.getTranslateY() + c.getRadius() + 20);
                    } else {
                        ouch.setVisible(false);
                    }
                }
            }.start();
        }
    }

    private void modifiedAnimationTimer(List<StackPane> sprites, Pane pane, Circle c, Label ouch) {
        // First create each separate move service for each sprite.
        List<SpriteService> spriteServices = sprites.stream().map(sprite -> new SpriteService(sprite, pane)).collect(Collectors.toList());

        new AnimationTimer() {
            @Override
            public void handle(long now) {
                boolean intersected = false;
                for (SpriteService spriteService : spriteServices) {
                    spriteService.move();
                    if (c.getBoundsInParent().intersects(spriteService.getSprite().getBoundsInParent())) {
                        intersected = true;
                    }
                }
                if (intersected) {
                    ouch.setVisible(true);
                    ouch.setTranslateX(c.getTranslateX());
                    ouch.setTranslateY(c.getTranslateY() + c.getRadius() + 20);
                } else {
                    ouch.setVisible(false);
                }
            }
        }.start();
    }

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

    //helper detect if up/left/down/right is in allKeyPressed
    private boolean hasMultiple(ArrayList<String> keys, String arrow) {
        for (String s : keys) {
            if (s.equals(arrow)) {
                return true;
            }
        }
        return false;
    }

    //help to know the index where the w/s/a/d is at in the allKeyPressed
    private int getIndex(ArrayList<String> keys, String arrow) {
        for (int i = 0; i < keys.size(); i++) {
            if (keys.get(i).equals(arrow)) {
                return i;
            }
        }
        return -1;
    }

    class Human {
        Color c;
        int id;

        public Human(Color randomColor, double v, String browType, int i) {
            c = randomColor;
            id = i;
        }

        public StackPane getBody() {
            StackPane sp = new StackPane(new Label(id + ""));
            sp.setBackground(new Background(new BackgroundFill(c, CornerRadii.EMPTY, Insets.EMPTY)));
            sp.setMinSize(25, 25);
            sp.setMaxSize(25, 25);
            return sp;
        }
    }

    class SpriteService {
        private double speed = (Math.random() * 1 + .1);
        private double dx = speed * Math.cos(Math.random() * 5 + 1);
        private double dy = speed * Math.sin(Math.random() * 5 + 1);

        private StackPane s;
        private Pane pane;

        public SpriteService(StackPane sp, Pane p) {
            s = sp;
            pane = p;
        }

        public void move() {
            s.setLayoutX(s.getLayoutX() + dx);
            s.setLayoutY(s.getLayoutY() + dy);
            Bounds bounds = pane.getLayoutBounds();
            if ((s.getLayoutX() <= (bounds.getMinX())) || (s.getLayoutX() + s.getWidth() >= (bounds.getMaxX()))) {
                dx = -dx;
            }
            if ((s.getLayoutY() - 10 <= (bounds.getMinY())) || (s.getLayoutY() + s.getHeight() + 10 >= (bounds.getMaxY()))) {
                dy = -dy;
            }
        }

        public StackPane getSprite() {
            return s;
        }
    }
}

Java相关问答推荐

Selenium Java:无法访问IFRAME内部的元素

了解Android Studio中的调试器输出

Kubernetes的Java客户端检索状态.处于终止状态的Pod的阶段';正在运行';

';com.itextpdf.ext.html.WebColors已弃用

如何集成语义发布和BitBucket(Java项目)

根本不显示JavaFX阿拉伯字母

Spring Boot中的应用程序.properties文件中未使用的属性

如何在Java springboot中从一个端点发送多个时间响应?

Android Studio模拟器没有互联网

S数学.exp的相同错误保证也适用于StrictMath.exp吗?

在Spring Boot JPA for MySQL中为我的所有类创建Bean时出错?

如何调整JButton的大小以适应图标?

根据应用程序 Select 的语言检索数据

Java 21内置http客户端固定运营商线程

由于可为null,无法在kotlin中实现java接口

如何在Java中正确实现填字游戏求解器

在外部类和内部类之间,当调用外部类内部或外部的主方法时,它们的静态初始化程序的运行顺序不同

Jackson YAML:支持锚点扩展/覆盖

为什么 log4j 过滤器在appender中不起作用

Xml Reader 将 BMP 外部的字符解析为代理项对,这会导致无效的 xml