英文:
I can't get my solar system simulation to work in JavaFX
问题
在编译和显示窗口之后,除了黑色背景和偶尔会出现一小部分太阳纹理外,我看到的唯一事物是,我不知道如何修复它,以便显示整个布局,我可以在上面看到地球和太阳。
import javafx.application.Application;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class MainApp extends Application {
@Override
public void start(Stage stage) throws Exception {
SolarSystem solarSystem = initSolarSystem();
SolarSystemSimulation simulation = new SolarSystemSimulation(solarSystem);
Scene scene = new Scene(simulation, 1200, 900);
scene.setFill(javafx.scene.paint.Color.BLACK);
PerspectiveCamera camera = new PerspectiveCamera();
camera.setTranslateZ(-10000); // 沿Z轴平移相机
camera.setFarClip(20000); // 渲染对象的距离
scene.setCamera(camera);
stage.setScene(scene);
stage.show();
simulation.start();
// 为太阳设置更大的半径
CelestialBody sun = solarSystem.getBodies().get(0);
sun.setRadius(1000);
}
// 省略其他代码
}
// 其他类的内容不变
你应该至少能看到太阳和地球围绕太阳运动。
英文:
After compiling and displaying the window, the only thing I can see besides a black background and every now and then a piece of the sun texture, and I don't know how to fix it so that it displays the whole layout and I can see both the earth and the sun on it
import javafx.application.Application;
import javafx.scene.PerspectiveCamera;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class MainApp extends Application {
@Override
public void start(Stage stage) throws Exception {
SolarSystem solarSystem = initSolarSystem();
SolarSystemSimulation simulation = new SolarSystemSimulation(solarSystem);
Scene scene = new Scene(simulation, 1200, 900);
scene.setFill(javafx.scene.paint.Color.BLACK);
PerspectiveCamera camera = new PerspectiveCamera();
camera.setTranslateZ(-10000); // Przesunięcie kamery wzdłuż osi Z
camera.setFarClip(20000); // Odległość renderowania obiektów
scene.setCamera(camera);
stage.setScene(scene);
stage.show();
simulation.start();
// Ustawienie większego promienia dla słońca
CelestialBody sun = solarSystem.getBodies().get(0);
sun.setRadius(1000);
}
private SolarSystem initSolarSystem() {
SolarSystem solarSystem = new SolarSystem();
// Tutaj tworzymy ciała niebieskie i dodajemy je do układu słonecznego
// Wszystkie tekstury powinny być zlokalizowane w folderze resources projektu
CelestialBody sun = new CelestialBody("Sun", 1.989 * Math.pow(10, 30), 696340, new Vector3D(0, 0, 0), new Vector3D(0, 0, 0), "sun.jpg");
solarSystem.addBody(sun);
CelestialBody earth = new CelestialBody("Earth", 5.972 * Math.pow(10, 24), 6371, new Vector3D(147.1 * Math.pow(10, 6), 0, 0), new Vector3D(0, 0, 0), "earth.jpg");
solarSystem.addBody(earth);
// ... dodajemy resztę ciał niebieskich, dla których mamy tekstury
return solarSystem;
}
public static void main(String[] args) {
launch(args);
}
}
public class CelestialBody {
private String name;
private double mass;
private double radius;
private Vector3D position;
private Vector3D velocity;
private String textureFilename;
public CelestialBody(String name, double mass, double radius, Vector3D position, Vector3D velocity, String textureFilename) {
this.name = name;
this.mass = mass;
this.radius = radius;
this.position = position;
this.velocity = velocity;
this.textureFilename = textureFilename;
}
public String getName() {
return name;
}
public double getMass() {
return mass;
}
public double getRadius() {
return radius;
}
public Vector3D getPosition() {
return position;
}
public Vector3D getVelocity() {
return velocity;
}
public void setVelocity(Vector3D velocity) {
this.velocity = velocity;
}
public void setPosition(Vector3D position) {
this.position = position;
}
public String getTextureFilename() {
return textureFilename;
}
public void setRadius(double radius) {
this.radius = radius;
}
}
import java.util.ArrayList;
import java.util.List;
public class SolarSystem {
private List<CelestialBody> bodies;
public SolarSystem() {
bodies = new ArrayList<>();
}
public void addBody(CelestialBody body) {
bodies.add(body);
}
public List<CelestialBody> getBodies() {
return bodies;
}
}
import javafx.animation.AnimationTimer;
import javafx.scene.Group;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Sphere;
import java.io.InputStream;
import javafx.scene.image.Image;
import java.util.Map;
import java.util.HashMap;
public class SolarSystemSimulation extends Group {
private SolarSystem solarSystem;
private Map<CelestialBody, Sphere> spheres;
public SolarSystemSimulation(SolarSystem solarSystem) {
this.solarSystem = solarSystem;
this.spheres = new HashMap<>();
for (CelestialBody body : solarSystem.getBodies()) {
Sphere sphere = new Sphere(body.getRadius());
PhongMaterial material = new PhongMaterial();
Image texture = loadImage(body.getTextureFilename());
if (texture != null) {
material.setDiffuseMap(texture);
}
sphere.setMaterial(material);
spheres.put(body, sphere);
getChildren().add(sphere);
}
// Wypisanie promieni sfer
for (CelestialBody body : solarSystem.getBodies()) {
Sphere sphere = spheres.get(body);
System.out.println("Promień " + body.getName() + ": " + sphere.getRadius());
}
}
public void setRadius(CelestialBody body, double radius) {
Sphere sphere = spheres.get(body);
if (sphere != null) {
sphere.setRadius(radius);
}
}
private Image loadImage(String filename) {
InputStream inputStream = getClass().getResourceAsStream("/" + filename);
return new Image(inputStream);
}
public void updatePositions(double deltaTime) {
for (CelestialBody body : solarSystem.getBodies()) {
Vector3D currentPosition = body.getPosition();
Vector3D velocity = body.getVelocity();
Vector3D newPosition = currentPosition.add(velocity.scale(deltaTime));
body.setPosition(newPosition);
}
}
public void start() {
new AnimationTimer() {
private long previousTime = 0;
@Override
public void handle(long now) {
if (previousTime == 0) {
previousTime = now;
return;
}
// Obliczamy różnicę czasu w sekundach
double deltaTime = (now - previousTime) / 1_000_000_000.0;
previousTime = now;
// Wyliczamy nowe pozycje dla ciał niebieskich
for (CelestialBody body : solarSystem.getBodies()) {
// Obliczamy nową prędkość na podstawie sił grawitacyjnych
Vector3D acceleration = calculateGravitationalAcceleration(body);
body.setVelocity(body.getVelocity().add(acceleration.scale(deltaTime)));
// Aktualizujemy pozycję na podstawie prędkości
Vector3D newPosition = body.getPosition().add(body.getVelocity().scale(deltaTime));
body.setPosition(newPosition);
// Aktualizujemy pozycję sfery na scenie
Sphere sphere = spheres.get(body);
sphere.setTranslateX(body.getPosition().getX());
sphere.setTranslateY(body.getPosition().getY());
sphere.setTranslateZ(body.getPosition().getZ());
}
// Oddalanie kamery
getChildren().forEach(child -> {
if (child instanceof Sphere) {
Sphere sphere = (Sphere) child;
sphere.setTranslateZ(sphere.getTranslateZ() - 0.5);
}
});
}
}.start();
}
private Vector3D calculateGravitationalAcceleration(CelestialBody body) {
Vector3D acceleration = new Vector3D(0, 0, 0);
for (CelestialBody otherBody : solarSystem.getBodies()) {
if (body != otherBody) {
// Obliczamy wektor odległości między ciałami
Vector3D distance = otherBody.getPosition().subtract(body.getPosition());
// Obliczamy siłę grawitacyjną między ciałami
double gravitationalForce = calculateGravitationalForce(body, otherBody, distance.magnitude());
// Obliczamy wektor przyspieszenia na podstawie siły i odległości
Vector3D bodyAcceleration = distance.scale(gravitationalForce / body.getMass());
// Dodajemy przyspieszenie od innego ciała do ogólnego przyspieszenia
acceleration = acceleration.add(bodyAcceleration);
}
}
return acceleration;
}
private double calculateGravitationalForce(CelestialBody body1, CelestialBody body2, double distance) {
final double gravitationalConstant = 6.67430e-11;
return gravitationalConstant * (body1.getMass() * body2.getMass()) / (distance * distance);
}
}
public class Vector3D {
private double x;
private double y;
private double z;
public Vector3D(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getZ() {
return z;
}
// Dodaje wektor do obecnego wektora
public Vector3D add(Vector3D other) {
return new Vector3D(this.x + other.x, this.y + other.y, this.z + other.z);
}
// Odejmuje wektor od obecnego wektora
public Vector3D subtract(Vector3D other) {
return new Vector3D(this.x - other.x, this.y - other.y, this.z - other.z);
}
// Mnoży wektor przez skalar
public Vector3D scale(double factor) {
return new Vector3D(this.x * factor, this.y * factor, this.z * factor);
}
// Oblicza długość (magnitude) wektora
public double magnitude() {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
}
}
I should at least see sun and earth orbiting around sun
答案1
得分: 2
scene
对象没有深度缓冲:
Scene scene = new Scene(simulation, 1200, 900);
为了启用深度缓冲,您可以使用以下构造函数之一:
Scene(Parent root, double width, double height, boolean depthBuffer, SceneAntialiasing antiAliasing)
或者:
Scene(Parent root, double width, double height, boolean depthBuffer)
例如:
Scene scene = new Scene(simulation, 1200, 900, true, SceneAntialiasing.BALANCED);
英文:
your scene
object does not have depthBuffer :
Scene scene = new Scene(simulation, 1200, 900);
in order to eneble depthBuffer you can use either this constructor
Scene(Parent root, double width, double height, boolean depthBuffer, SceneAntialiasing antiAliasing)
or this
Scene(Parent root, double width, double height, boolean depthBuffer)
E.g :
Scene scene = new Scene(simulation, 1200, 900,true,SceneAntialiasing.BALANCED);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论