java - JavaFX:如何将图像添加到已用另一种方法初始化的矩形?
问题描述
我制作了 SpaceInvaders 的粗略副本以了解 JavaFX,并想知道如何用图形替换我用作 Sprite 的矩形。
它适用于玩家精灵和舞台背景,但我不知道如何用图形替换红色敌人方块。
我尝试将图像对象放在nextLevel () 方法中并将其填充到那里的精灵中,但这只会给我一个 FileNotFoundException 错误。
nextLevel() 方法:
private void nextLevel() {
// Image img2 = Image(newFileInputStream("C:\\Users\\user\\Pictures\\y.jpg"));
for (int i = 0; i < 5; i++) {
Sprite enemy = new Sprite (90 + i*100, 150, 30, 30, "enemy", Color.RED);
// enemy.setFill(new ImagePattern(img2));
root.getChildren().add(enemy);
}
}
我只能在start方法中初始化 Image ,但是我不知道如何将它分配给敌人的方格,因为它们还没有被初始化。即使我把它放在调用nextLevel()方法和 Stage的createContent()方法之后,仍然无法解决敌人。
启动方法:
@Override
public void start(Stage stage) throws Exception {
Image img2 = new Image(new FileInputStream("C:\\Users\\user\\Pictures\\x.jpg"));
Image img = new Image(new FileInputStream("C:\\Users\\user\\Pictures\\y.png"));
player.setFill(new ImagePattern(img));
// enemy.setFill(new ImagePattern(img2));
stage.setTitle("Box");
stage.setResizable(false);
Scene scene = new Scene(createContent());
scene.setFill(new ImagePattern(img2));
scene.setOnKeyPressed(e ->{
switch (e.getCode()) {
case A:
player.moveLeft();
break;
case D:
player.moveRight();
break;
case SPACE:
shoot(player);
break;
}
});
stage.setScene(scene);
stage.show();
}
createContent() 方法:
private Parent createContent() {
root.setPrefSize(600,800);
root.getChildren().add(player);
AnimationTimer timer = new AnimationTimer() {
@Override
public void handle(long now) {
update();
}
};
timer.start();
nextLevel();
return root;
}
如果有人需要,这里是完整的代码:
import java.io.FileInputStream;
import java.util.List;
import java.util.stream.Collectors;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.ImagePattern;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class SpaceInvaders extends Application {
private double t = 0;
private final Pane root = new Pane();
private final Sprite player = new Sprite (300,700,80,80, "player",Color.BLUE);
private Parent createContent() {
root.setPrefSize(600,800);
root.getChildren().add(player);
AnimationTimer timer = new AnimationTimer() {
@Override
public void handle(long now) {
update();
}
};
timer.start();
nextLevel();
return root;
}
private void nextLevel() {
for (int i = 0; i < 5; i++) {
Sprite enemy = new Sprite (90 + i*100, 150, 30, 30, "enemy", Color.RED);
root.getChildren().add(enemy);
}
}
private List<Sprite> sprites(){
return root.getChildren().stream().map(n -> (Sprite)n).collect(Collectors.toList());
}
private void update() {
t += 0.016;
sprites().forEach(s -> {
switch (s.type) {
case "enemybullet":
s.moveDown();
if (s.getBoundsInParent().intersects(player.getBoundsInParent())) {
player.dead = true;
s.dead = true;
}
break;
case "playerbullet":
s.moveUp();
sprites().stream().filter(e -> e.type.equals("enemy")).forEach(enemy ->{
if (s.getBoundsInParent().intersects(enemy.getBoundsInParent())) {
enemy.dead = true;
s.dead = true;
}
});
break;
case "enemy":
if (t > 2) {
if (Math.random() < 0.3) {
shoot2(s);
}
}
break;
}
});
root.getChildren().removeIf(n -> {
Sprite s = (Sprite) n;
return s.dead;
});
if (t > 2) {
t = 0;
}
}
private void shoot(Sprite who) {
Sprite s = new Sprite((int) who.getTranslateX() + 40, (int) who.getTranslateY(), 5, 20, who.type + "bullet", Color.BLACK);
root.getChildren().add(s);
}
private void shoot2(Sprite who) {
Sprite s = new Sprite((int) who.getTranslateX() + 20, (int) who.getTranslateY() + 5, 5, 20, who.type + "bullet", Color.BLACK);
root.getChildren().add(s);
}
@Override
public void start(Stage stage) throws Exception {
Image img2 = new Image(new FileInputStream("C:\\Users\\Alexxx\\Pictures\\ibama.jpg"));
Image img = new Image(new FileInputStream("C:\\Users\\Alexxx\\Pictures\\pinguin.png"));
player.setFill(new ImagePattern(img));
stage.setTitle("Nordpol-Defender 2");
stage.setResizable(false);
Scene scene = new Scene(createContent());
scene.setFill(new ImagePattern(img2));
scene.setOnKeyPressed(e ->{
switch (e.getCode()) {
case A:
player.moveLeft();
break;
case D:
player.moveRight();
break;
case SPACE:
shoot(player);
break;
}
});
stage.setScene(scene);
stage.show();
}
private static class Sprite extends Rectangle {
boolean dead = false;
final String type;
Sprite(int x, int y, int w, int h, String type, Color colour){
super(w, h, colour);
this.type = type;
setTranslateX(x);
setTranslateY(y);
}
Sprite(int x, int y, int w, int h, String type, Color colour, Image img){
super(w, h, colour);
this.type = type;
setFill(new ImagePattern(img));
setTranslateX(x);
setTranslateY(y);
}
void moveLeft() {
setTranslateX(getTranslateX() - 5);
}
void moveRight() {
setTranslateX(getTranslateX() + 5);
}
void moveUp() {
setTranslateY(getTranslateY() - 5);
}
void moveDown() {
setTranslateY(getTranslateY() + 5);
}
}
public static void main(String[] args) {
launch(args);
}
}
解决方案
以下最小的、可重现的示例 (1)演示了Rectangle
在运行时更改图像:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.ImagePattern;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class ChangeImageInShape extends Application {
private int imageSelected = 0;
private Sprite player;
private static final String[] fishImages = {
"https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/160/lg/57/tropical-fish_1f420.png",
"https://www.shareicon.net/data/128x128/2015/03/28/14104_animal_256x256.png",
"https://cdn1.iconfinder.com/data/icons/DarkGlass_Reworked/128x128/apps/gnome-fish.png",
"http://www.iconsalot.com/asset/icons/freepik/pet-shop-13/128/010-fish-2-icon.png"
};
private final Image[] images = new Image[fishImages.length];
@Override
public void start(Stage stage) throws Exception {
for(int i = 0 ; i < images.length ; i++){
images[i] = new Image(fishImages[i]); //loading images takes some time
}
player = new Sprite (0,0,80,80, "player",Color.BLUE);
changeImageInSprite();
Button btn = new Button("Change Image In Sprite");
btn.setOnAction(e->changeImageInSprite());
Pane root = new BorderPane(player, null, null, btn, null);
root.setPrefSize(300,200);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
private void changeImageInSprite() {
player.setFill(new ImagePattern(images[imageSelected++]));
imageSelected = imageSelected >= images.length ? 0 : imageSelected;
}
private static class Sprite extends Rectangle {
Sprite(int x, int y, int w, int h, String type, Color colour){
super(w, h, colour);
}
}
public static void main(String[] args) {
launch(args);
}
}
(1) 它使用公开可用的资源,它尽可能短,并且不代表你的应用程序而是问题。
考虑在问题和答案中添加 mre。