所以我得到了这个代码,我试图让移动的圆圈在墙壁上反弹,这样他们就不会走出舞台了。我曾试图用moveCircle方法做到这一点,但我感觉真的超出了我的舒适区。
import javafx.animation.Animation.Status;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.Orientation;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollBar;
import javafx.scene.effect.Light;
import javafx.scene.effect.Lighting;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.util.Duration;
public class TimelineSample extends Application {
Timeline timeline;
private void init(Stage primaryStage) {
double height = primaryStage.getHeight();
double width = primaryStage.getWidth();
BorderPane root = new BorderPane();
primaryStage.setScene(new Scene(root, width, height));
double radius = 30;
Circle circle = new Circle(radius, radius, radius, Color.BLUE);
Circle circle2 = new Circle(radius, radius, radius, Color.RED);
Light.Distant light = new Light.Distant();
light.setAzimuth(-135.0);
Label label = new Label(
"Space för starta spelet\nSpace för att pausa spelet\nTryck på cirklarna för att byta färg på dem");
Label label2 = new Label("44");
root.setStyle("-fx-background-color: green;");
label2.setStyle(("-fx-padding : 100;"));
root.setBottom(label2);
root.setCenter(label);
Screen screen = Screen.getPrimary();
Rectangle2D bounds = screen.getVisualBounds();
ScrollBar sbSpeed = new ScrollBar();
sbSpeed.setMax(50);
sbSpeed.setValue(25);
sbSpeed.setOrientation(Orientation.VERTICAL);
circle.opacityProperty().bind(sbSpeed.valueProperty().divide(30));
circle2.opacityProperty().bind(sbSpeed.valueProperty().divide(30));
sbSpeed.setOnScroll(e -> {
circle.setTranslateX(+50);
});
circle.centerXProperty().bind(root.widthProperty().divide(2));
circle.centerYProperty().bind(root.heightProperty().divide(2));
circle.radiusProperty().bind(Bindings.min(root.widthProperty().divide(10),
root.heightProperty().divide(10)));
circle2.centerXProperty().bind(root.widthProperty().divide(2));
circle2.centerYProperty().bind(root.heightProperty().divide(2));
circle2.radiusProperty().bind(Bindings.min(root.widthProperty().divide(10),
root.heightProperty().divide(10)));
root.setTop(sbSpeed);
primaryStage.setWidth(bounds.getWidth() * 0.40);
primaryStage.setHeight(bounds.getHeight() * 0.40);
Lighting lighting = new Lighting();
lighting.setLight(light);
lighting.setSurfaceScale(5.0);
circle.setEffect(lighting);
circle2.setEffect(lighting);
timeline = new Timeline();
timeline.setCycleCount(Timeline.INDEFINITE);
timeline.setAutoReverse(true);
timeline.getKeyFrames().addAll
(new KeyFrame(Duration.ZERO, new KeyValue(circle.translateXProperty(),
0)),
new KeyFrame(new Duration(5000), new KeyValue(circle
.translateXProperty(), width - (radius * 2))));
timeline.getKeyFrames().addAll(
new KeyFrame(Duration.ZERO, new KeyValue(
circle2.translateYProperty(), 0)),
new KeyFrame(new Duration(5000), new KeyValue(circle2
.translateYProperty(), height - (radius * 2))));
timeline.play();
root.getChildren().addAll(circle, circle2);
boolean a = true;
root.requestFocus();
root.setOnKeyPressed(e -> {
if (e.getCode().equals(KeyCode.SPACE)) {
if (timeline.statusProperty().getValue().equals(Status.RUNNING)) {
timeline.pause();
} else
timeline.play();
}
});
circle.setOnMousePressed(event -> {
if (circle.getFill().equals(Color.BLACK))
circle.setFill(Color.YELLOW);
else if (circle.getFill().equals(Color.BLUE))
circle.setFill(Color.BROWN);
else if (circle.getFill().equals(Color.YELLOW))
circle.setFill(Color.BROWN);
else if (circle.getFill().equals(Color.BROWN))
circle.setFill(Color.BLACK);
else
circle.setFill(Color.BLUE);
});
circle2.setOnMousePressed(event -> {
if (circle2.getFill().equals(Color.BLACK))
circle2.setFill(Color.YELLOW);
else if (circle2.getFill().equals(Color.BLUE))
circle2.setFill(Color.BROWN);
else if (circle2.getFill().equals(Color.YELLOW))
circle2.setFill(Color.BROWN);
else if (circle2.getFill().equals(Color.BROWN))
circle2.setFill(Color.BLACK);
else
circle2.setFill(Color.BLUE);
// }
});
}
protected void moveCircle(Circle circle) {
if (circle.getCenterX() < circle.getRadius() ||
circle.getCenterX() > circle.getCenterY() - circle.getRadius()) {
circle.translateYProperty();
}
if (circle.getCenterY() < circle.getRadius() ||
circle.getCenterY() > circle.getCenterX() - circle.getRadius()) {
circle.translateXProperty();}
}
public void pause() {
timeline.pause();
}
@Override
public void start(Stage primaryStage) throws Exception {
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
只需要启动球就可以了。
答案 0 :(得分:0)
现在这是类似这样的通用伪代码,虽然不是特定于你的问题,但这是使这种“反弹”离开屏幕边缘的一般方法。
首先你需要5条信息,圆形速度(在x和y上,作为变量或向量2),圆形半径(或直径),圆形位置(在x和y上,作为变量或向量2) )和屏幕的宽度和高度。
此外,取决于圆的原点是否为中心(您将需要半径),左下角或左上角(您将需要直径)。在我的例子中,我们假设原点是在圆圈的中间爆炸。
一般的想法是这样的:
int windowWidth = 800, windowHeight = 600;
Circle c;
// Check if the left or right side of the circle leaves the screen bounds
// if so, reverse the velocity (mirror it)
if(c.x - c.radius < 0 || c.x + c.radius > windowWidth)
c.velocityX = -x.velocityX;
// Check if the top or bottom side of the circle leaves the screen bounds
// if so, reverse the velocity (mirror it)
if(c.y - c.radius < 0 || c.y + c.radius > windowHeight)
c.velocityY = -c.velocityY;
希望这是有道理的,这是检查圆是否通过屏幕边界并简单地镜像给定轴上的速度的情况。因此,如果球以5.0的速度(直接向右)移动然后超出窗口宽度,我们想要在x上取速度并取消它,所以现在速度变为-5,0(直接左)
这个问题的一个问题是线性外观,您可以轻松添加一些其他变量,如加速度,恢复原状,摩擦力和拖动力,以使其更逼真。