我目前正在尝试制作一款带有坠落的“小行星”的游戏,船只必须躲避它。我目前创建了一个窗格,该窗格是一个大圆圈,上面叠有多个小圆圈。不幸的是,窗格的“ hitbox”是一个正方形/矩形,而不是一个圆形,这令人沮丧。解决此问题的另一种替代方法是创建一个圆并用小行星的图像填充它,但我在任何地方都找不到。我知道:
circle.setFill(Color.WHATEVER);
但是我希望它看起来像一颗小行星,而不仅仅是一个坠落的简单灰色圆圈。综上所述,如何设置图像的形状?或者,如果有一种方法可以更改堆栈窗格的点击框,那么也可以帮助解决我的问题!
任何帮助将不胜感激!谢谢!
编辑: 以下是使我的游戏的简化版工作相同的问题的4个文件:
DodgerRemake:
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);
}
}
BoxPane:
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);
}
}
希望这会有所帮助,谢谢!