Image 如何使用图像JavaFX填充形状

Image 如何使用图像JavaFX填充形状,image,javafx,shapes,Image,Javafx,Shapes,我目前正在尝试创建一个游戏,游戏中有坠落的“小行星”,飞船必须躲避。我目前已经创建了一个窗格,它是一个由多个小圆圈堆叠而成的大圆圈。不幸的是,窗格的“hitbox”是正方形/矩形,而不是圆形,这令人沮丧。解决这个问题的另一种方法是创建一个圆,并用小行星的图像填充它,但我在任何地方都找不到。我知道: circle.setFill(Color.WHATEVER); 但我希望它看起来像一颗小行星,而不仅仅是一个简单的灰色圆圈。总而言之,如何将图像设置为形状?或者,如果有一种方法可以更改stackpa

我目前正在尝试创建一个游戏,游戏中有坠落的“小行星”,飞船必须躲避。我目前已经创建了一个窗格,它是一个由多个小圆圈堆叠而成的大圆圈。不幸的是,窗格的“hitbox”是正方形/矩形,而不是圆形,这令人沮丧。解决这个问题的另一种方法是创建一个圆,并用小行星的图像填充它,但我在任何地方都找不到。我知道:

circle.setFill(Color.WHATEVER);
但我希望它看起来像一颗小行星,而不仅仅是一个简单的灰色圆圈。总而言之,如何将图像设置为形状?或者,如果有一种方法可以更改stackpane的hitbox,那么这种方法也有助于解决我的问题

非常感谢您的帮助!谢谢

编辑: 下面是4个文件,它们将使我的游戏的简化版本能够处理相同的问题:

道奇品牌:

package javafxapplication6;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class DodgerRemake extends Application
{
    private Spaceship thisSpaceShip = new Spaceship();
    private BoxPane gamePane = new BoxPane(thisSpaceShip);
    BorderPane pane = new BorderPane();
    private BooleanProperty upPressed = new SimpleBooleanProperty();
    private BooleanProperty rightPressed = new SimpleBooleanProperty();
    private BooleanProperty downPressed = new SimpleBooleanProperty();
    private BooleanProperty leftPressed = new SimpleBooleanProperty();
    private BooleanBinding anyPressed = upPressed.or(rightPressed).or(downPressed).or(leftPressed);


    protected BorderPane getPane()
    {
        StackPane centerPane = new StackPane();
        centerPane.getChildren().add(gamePane);
        pane.setCenter(centerPane);

        Button thisButton = new Button("Start");
        thisButton.setAlignment(Pos.CENTER);
        thisButton.setFocusTraversable(false);
        thisButton.setOnAction(new startGame());  
        pane.setLeft(thisButton);

        return pane;
    }

    @Override
    public void start(Stage primaryStage) {    
         // Create a scene and place it in the stage
        Scene scene = new Scene(getPane(), 960, 800);
        primaryStage.setTitle("Dodger"); // Set the stage title
        primaryStage.setScene(scene); // Place the scene in the stage
        primaryStage.setResizable(false);
        primaryStage.show(); // Display the stage

        scene.setOnKeyPressed(e -> {
            if (e.getCode() == KeyCode.UP) {
                upPressed.set(true);
            }
            if (e.getCode() == KeyCode.DOWN) {
                downPressed.set(true);
            }
            if (e.getCode() == KeyCode.RIGHT) {
                rightPressed.set(true);
            }
            if (e.getCode() == KeyCode.LEFT) {
                leftPressed.set(true);
            }
        });

        scene.setOnKeyReleased(e -> {
            if (e.getCode() == KeyCode.UP) {
                upPressed.set(false);
            }
            if (e.getCode() == KeyCode.DOWN) {
                downPressed.set(false);
            }
            if (e.getCode() == KeyCode.RIGHT) {
                rightPressed.set(false);
            }
            if (e.getCode() == KeyCode.LEFT) {
                leftPressed.set(false);
            }
        });

        AnimationTimer timer = new AnimationTimer()
        {
            @Override
            public void handle(long timestamp) {

                if (upPressed.get()){
                    gamePane.moveShipUp();
                }
                if (downPressed.get()){
                    gamePane.moveShipDown();
                }
                if (rightPressed.get()) {
                    gamePane.moveShipRight();
                }
                if (leftPressed.get()) {
                    gamePane.moveShipLeft();
                }
            }
        };

        anyPressed.addListener((obs, wasPressed, isNowPressed) ->
        {
            if (isNowPressed) {
                timer.start();
            } else {
                timer.stop();
            }
        });
    }

    class startGame implements EventHandler<ActionEvent>
    {
        @Override
        public void handle(ActionEvent e)
        {
            gamePane.addSpaceship();
            gamePane.startGame();
        }
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

希望这有帮助,谢谢

你能多分享一点你的代码吗?@SamuelP。当然,我添加了displayAsteroid函数。如果您希望我添加任何其他内容或指定任何内容,请务必让我知道!您能分享一下吗?这样我们就可以很容易地复制您的问题了?可能的副本请查看及其使用。另请看一下。你能多分享一点你的代码吗?@SamuelP。当然,我添加了displayAsteroid函数。如果您希望我添加任何其他内容或指定任何内容,请务必让我知道!您能分享一下吗?这样我们就可以很容易地复制您的问题了?可能的副本请查看及其使用。也来看看。
package javafxapplication6;

import java.util.Random;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.layout.Pane;
import javafx.util.Duration;

class BoxPane extends Pane
{
    private Spaceship spaceShip;
    private Timeline asteroids;
    private double x;
    private double y;

    BoxPane(Spaceship thisSpaceShip)
    {        
        spaceShip = thisSpaceShip;
        spaceShip.setRotate(180);
    }

    public void addSpaceship()
    {
        getChildren().add(spaceShip);
        x = 400 - spaceShip.getWidth()/2;
        y = 740;
        spaceShip.setTranslateX(x);
        spaceShip.setTranslateY(y);
    }

    public void moveShipLeft()
    {
        if(x > 0)
        {
            spaceShip.setTranslateX(x-5);
            x = x-5;
        }
        else
        {
            spaceShip.setTranslateX(0);
            x = 0;
        }
    }

    public void moveShipRight()
    {
        if(x+spaceShip.getWidth() < getWidth())
        {
            spaceShip.setTranslateX(x+5);
            x = x+5;
        }
        else
        {
            spaceShip.setTranslateX(getWidth() - spaceShip.getWidth());
            x = getWidth() - spaceShip.getWidth();
        }

    }

    public void moveShipUp()
    {
        if(y > 0)
        {
            spaceShip.setTranslateY(y-5);
            y = y-5;
        }
        else
        {
            spaceShip.setTranslateY(0);
            y = 0;
        }
    }

    public void moveShipDown()
    {
        if(y+spaceShip.getHeight() < getHeight())
        {
            spaceShip.setTranslateY(y+5);
            y = y+5;
        }
        else
        {
            spaceShip.setTranslateY(getHeight() - spaceShip.getHeight());
            y = getHeight() - spaceShip.getHeight();
        }
    } 

    public void startGame()
    {
        //addSpaceship();
        asteroids = new Timeline(new KeyFrame(Duration.seconds(.5), e -> displayAsteroid()));
        asteroids.setCycleCount(Timeline.INDEFINITE);
        asteroids.play();
    }

    public void displayAsteroid()
    {
        Asteroid asteroid = new Asteroid();
        getChildren().add(asteroid); 

        Random rand = new Random();
        int randomNum = rand.nextInt((int) (getWidth() - asteroid.getWidth()));
        asteroid.setY(-200);
        asteroid.setX(randomNum);
        asteroid.setTranslateY(asteroid.getY());
        asteroid.setTranslateX(asteroid.getX());

        Timeline timeline = new Timeline();
        KeyFrame keyFrame = new KeyFrame(Duration.millis(50), event -> {
            if(asteroid.getY() > getHeight()|| asteroid.getBoundsInParent().intersects(spaceShip.getBoundsInParent()))
            {
                timeline.stop();
                getChildren().remove(asteroid);
            }
            else
            {
                asteroid.setY(asteroid.getY()+5);
                asteroid.setTranslateY(asteroid.getY());
            }
        });
        timeline.setCycleCount(Animation.INDEFINITE);
        timeline.getKeyFrames().add(keyFrame);
        timeline.play();
    }
}
package javafxapplication6;

import javafx.geometry.Pos;
import java.util.Random;
import java.util.Vector;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Ellipse;

public class Asteroid extends StackPane
{
    private Ellipse asteroid = new Ellipse(); 
    private Ellipse hole1 = new Ellipse();
    private Ellipse hole2 = new Ellipse();
    private Ellipse hole3 = new Ellipse();
    private int speed;
    private double y = 0;
    private double x = 0;

    Asteroid()
    {       
        Random rand = new Random();
        int asteroidNum = rand.nextInt(10);
        if(asteroidNum < 6)
        {
            asteroidNum = 0;
        }
        else if(asteroidNum < 8)
        {
            asteroidNum = 1;
        }
        else
        {
            asteroidNum = 2;
        }
        StackPane thisAsteroid = new StackPane();
        VBox vbox = new VBox();
        HBox hbox = new HBox();
        vbox.setAlignment(Pos.CENTER);
        hbox.setAlignment(Pos.CENTER);

        asteroid.setFill(Color.GREY);
        asteroid.setStroke(Color.DIMGREY);
        hole1.setFill(Color.DIMGREY);
        hole1.setStroke(Color.BLACK);
        hole2.setFill(Color.DIMGREY);
        hole2.setStroke(Color.BLACK);
        hole3.setFill(Color.DIMGREY);
        hole3.setStroke(Color.BLACK);

        switch(asteroidNum)
        {
            case 0: asteroid1();
                    vbox.setSpacing(10);
                    hbox.setSpacing(10);
            break;
            case 1: asteroid2();
                    vbox.setSpacing(15);
                    hbox.setSpacing(15);
            break;
            case 2: asteroid3();
                    vbox.setSpacing(25);
                    hbox.setSpacing(25);
            break;
        }

        int holeLayout = rand.nextInt(3);
        switch(holeLayout)
        {
        case 0: hbox.getChildren().addAll(hole1, hole2);
                vbox.getChildren().addAll(hole3, hbox);
                thisAsteroid.getChildren().addAll(asteroid, vbox);
                break;
        case 1: vbox.getChildren().addAll(hole2, hole3);
                hbox.getChildren().addAll(vbox, hole1);
                thisAsteroid.getChildren().addAll(asteroid, hbox);

                break;
        case 2: vbox.getChildren().addAll(hole1, hole3);
                hbox.getChildren().addAll(hole2, vbox);
                thisAsteroid.getChildren().addAll(asteroid, hbox);
                break;
        case 3: hbox.getChildren().addAll(hole1, hole2);
                vbox.getChildren().addAll(hbox, hole3);
                thisAsteroid.getChildren().addAll(asteroid, vbox);
                break;

        }

        this.getChildren().add(thisAsteroid);
    }

    public void asteroid1()
    {
        speed = 10;
        asteroid.setRadiusX(40);
        asteroid.setRadiusY(35);
        asteroid.setStrokeWidth(3);
        hole1.setRadiusX(7);
        hole1.setRadiusY(8);
        hole2.setRadiusX(9);
        hole2.setRadiusY(6);
        hole3.setRadiusX(6);
        hole3.setRadiusY(5);
    }

    public void asteroid2()
    {
        speed = 6;
        asteroid.setRadiusX(60);
        asteroid.setRadiusY(50);
        asteroid.setStrokeWidth(5);
        hole1.setRadiusX(10);
        hole1.setRadiusY(12);
        hole2.setRadiusX(12);
        hole2.setRadiusY(10);
        hole3.setRadiusX(14);
        hole3.setRadiusY(13);
    }

    public void asteroid3()
    {
        speed = 4;
        asteroid.setRadiusX(100);
        asteroid.setRadiusY(90);
        asteroid.setStrokeWidth(8);
        hole1.setRadiusX(20);
        hole1.setRadiusY(18);
        hole2.setRadiusX(18);
        hole2.setRadiusY(22);
        hole3.setRadiusX(23);
        hole3.setRadiusY(19);
    }

    public void setY(double nY)
    {
        y = nY;
    }

    public void setX(double nX)
    {
        x = nX;
    }

    public double getX()
    {
        return x;
    }

    public double getY()
    {
        return y;
    }

    public int getSpeed()
    {
        return speed;
    }
}
package javafxapplication6;

import javafx.geometry.Pos;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Ellipse;
import javafx.scene.shape.Rectangle;

public class Spaceship extends StackPane
{
    private Rectangle leftWingBottom = new Rectangle();
    private Rectangle leftWingGun = new Rectangle();
    private Rectangle leftWingDesign = new Rectangle();
    private Rectangle leftWingAttachment = new Rectangle();
    private Rectangle leftTransparent = new Rectangle();
    private Rectangle rightWingBottom = new Rectangle();
    private Rectangle rightWingGun = new Rectangle();
    private Rectangle rightWingDesign = new Rectangle();
    private Rectangle rightWingAttachment = new Rectangle();
    private Rectangle rightTransparent = new Rectangle();
    private Rectangle centerCompartmentBottom = new Rectangle();
    private Rectangle centerCompartmentDesign = new Rectangle();
    private Ellipse centerCompartmentTop = new Ellipse();

    Spaceship()
    {
        HBox ship = new HBox();
        VBox leftWing = new VBox();
        VBox rightWing = new VBox();
        VBox leftAttachment = new VBox();
        VBox rightAttachment = new VBox();

        StackPane leftWingStack = new StackPane();
        StackPane rightWingStack = new StackPane();
        StackPane centerCompartmentShip = new StackPane();

        leftTransparent.setFill(Color.TRANSPARENT);
        rightTransparent.setFill(Color.TRANSPARENT);

        // creates the right wing
        rightWingBottom.setHeight(30);
        rightWingBottom.setWidth(8);
        rightWingBottom.setStrokeWidth(1);
        rightWingDesign.setHeight(25);
        rightWingDesign.setWidth(3);
        rightWingStack.setAlignment(Pos.CENTER);
        rightWingStack.getChildren().addAll(rightWingBottom, rightWingDesign);
        rightWingGun.setHeight(5);
        rightWingGun.setWidth(2);
        rightWing.setAlignment(Pos.TOP_CENTER);
        rightWing.getChildren().addAll(rightWingStack, rightWingGun);

        // creates the left wing and gun
        leftWingBottom.setHeight(30);
        leftWingBottom.setWidth(8);
        leftWingBottom.setStrokeWidth(1);
        leftWingDesign.setHeight(25);
        leftWingDesign.setWidth(3);
        leftWingStack.setAlignment(Pos.CENTER);
        leftWingStack.getChildren().addAll(leftWingBottom, leftWingDesign);
        leftWingGun.setHeight(5);
        leftWingGun.setWidth(2);
        leftWing.setAlignment(Pos.TOP_CENTER);
        leftWing.getChildren().addAll(leftWingStack, leftWingGun);

        // attaches the cockpit and right wing together
        rightTransparent.setHeight(5);
        rightTransparent.setWidth(5);
        rightWingAttachment.setHeight(3);
        rightWingAttachment.setWidth(5);
        rightAttachment.setAlignment(Pos.TOP_CENTER);
        rightAttachment.getChildren().addAll(rightTransparent, rightWingAttachment);

        // attaches the cockpit and left wing together
        leftTransparent.setHeight(5);
        leftTransparent.setWidth(5);
        leftWingAttachment.setHeight(3);
        leftWingAttachment.setWidth(5);
        leftAttachment.setAlignment(Pos.TOP_CENTER);
        leftAttachment.getChildren().addAll(leftTransparent, leftWingAttachment);

        // creates the cockpit
        centerCompartmentBottom.setHeight(25);
        centerCompartmentBottom.setWidth(20);
        centerCompartmentBottom.setStrokeWidth(2);
        centerCompartmentTop.setRadiusX(10);
        centerCompartmentTop.setRadiusY(25);
        centerCompartmentTop.setStrokeWidth(2);
        centerCompartmentDesign.setHeight(25);
        centerCompartmentDesign.setWidth(5);
        centerCompartmentShip.setAlignment(Pos.TOP_CENTER);
        centerCompartmentShip.getChildren().addAll(centerCompartmentTop, centerCompartmentBottom, centerCompartmentDesign);

        rightWingBottom.setFill(Color.WHITE);
        rightWingBottom.setStroke(Color.GREY);
        leftWingBottom.setFill(Color.WHITE);
        leftWingBottom.setStroke(Color.GREY);
        rightWingGun.setFill(Color.WHITE);
        leftWingGun.setFill(Color.WHITE);
        rightWingDesign.setFill(Color.TRANSPARENT);
        leftWingDesign.setFill(Color.TRANSPARENT);
        rightWingAttachment.setFill(Color.WHITE);
        rightWingAttachment.setStroke(Color.GREY);
        leftWingAttachment.setFill(Color.WHITE);
        leftWingAttachment.setStroke(Color.GREY);
        centerCompartmentBottom.setFill(Color.WHITE);
        centerCompartmentBottom.setStroke(Color.GREY);
        centerCompartmentTop.setFill(Color.WHITE);
        centerCompartmentTop.setStroke(Color.GREY);
        centerCompartmentDesign.setFill(Color.TRANSPARENT);

        // adds everything to final hbox
        ship.getChildren().addAll(rightWing,
                                  rightAttachment,
                                  centerCompartmentShip,
                                  leftAttachment,
                                  leftWing);

        // adds it to the SpaceShip object
        this.getChildren().add(ship);
    }
}