• JavaFX、合并碰撞的弹球


     

    1. package collection;
    2. import javafx.animation.KeyFrame;
    3. import javafx.animation.Timeline;
    4. import javafx.application.Application;
    5. import javafx.beans.property.DoubleProperty;
    6. import javafx.geometry.Point2D;
    7. import javafx.geometry.Pos;
    8. import javafx.scene.Node;
    9. import javafx.scene.Scene;
    10. import javafx.scene.control.Button;
    11. import javafx.scene.control.ScrollBar;
    12. import javafx.scene.layout.BorderPane;
    13. import javafx.scene.layout.HBox;
    14. import javafx.scene.layout.Pane;
    15. import javafx.scene.paint.Color;
    16. import javafx.scene.paint.Paint;
    17. import javafx.scene.shape.Circle;
    18. import javafx.stage.Stage;
    19. import javafx.util.Duration;
    20. import java.security.SecureRandom;
    21. import java.util.ConcurrentModificationException;
    22. public class MultipleBouncePane extends Application {
    23. @Override
    24. public void start(Stage primaryStage) throws Exception {
    25. MultipleBallPane ballPane = new MultipleBallPane(); //创建多球面板
    26. ballPane.setStyle("-fx-border-color: darkseagreen;");
    27. Button suspend = new Button("Suspend"); //按钮
    28. Button resume = new Button("Resume");
    29. Button add = new Button("+");
    30. Button subtract = new Button("-");
    31. HBox hBox = new HBox(10, suspend, resume, add, subtract);
    32. hBox.setAlignment(Pos.CENTER);
    33. suspend.setOnAction(event -> ballPane.pause()); //按钮注册动作事件
    34. resume.setOnAction(event -> ballPane.play());
    35. add.setOnAction(event -> ballPane.add());
    36. subtract.setOnAction(event -> ballPane.subtract());
    37. ballPane.setOnMousePressed(event -> ballPane.pause()); //多球面板注册鼠标按下事件
    38. ballPane.setOnMouseReleased(event -> ballPane.play());
    39. ScrollBar speed = new ScrollBar(); //滚动条
    40. speed.setMax(20); //设置最大值
    41. speed.setValue(10); //设置值
    42. ballPane.rateProperty().bind(speed.valueProperty()); //多球面板速度属性绑定滚动条值属性
    43. BorderPane pane = new BorderPane(ballPane); //总面板
    44. pane.setTop(speed);
    45. pane.setBottom(hBox);
    46. Scene scene = new Scene(pane, 350, 250);
    47. primaryStage.setScene(scene);
    48. primaryStage.setTitle("MultipleBouncePane");
    49. primaryStage.show();
    50. }
    51. /** 内部类(多球面板) */
    52. private class MultipleBallPane extends Pane {
    53. private Timeline animation; //时间线动画
    54. public MultipleBallPane() {
    55. animation = new Timeline(new KeyFrame(Duration.millis(50), event -> moveBall()));
    56. animation.setCycleCount(Timeline.INDEFINITE);
    57. animation.play();
    58. }
    59. /** 添加弹球 */
    60. public void add() {
    61. Color color = new Color(Math.random(), Math.random(), Math.random(), 0.5); //创建半透明的随机颜色对象
    62. Ball ball = new Ball(30, 30, 2+new SecureRandom().nextInt(19), color); //创建弹球对象
    63. getChildren().add(ball); //多球面板添加弹球
    64. //弹球注册鼠标按下事件
    65. ball.setOnMousePressed(event -> {
    66. if (ball.isPressed()) { //如果被按下
    67. animation.stop();
    68. getChildren().remove(ball); //移除当前弹球
    69. animation.play();
    70. }
    71. });
    72. }
    73. /** 减少弹球 */
    74. public void subtract() {
    75. if (getChildren().size() > 0) { //移除最大半径的弹球
    76. Ball temp = (Ball)getChildren().get(0);
    77. for (Node node: getChildren()) {
    78. if (((Ball)node).getRadius() > temp.getRadius())
    79. temp = (Ball)node;
    80. }
    81. getChildren().remove(temp);
    82. }
    83. }
    84. /** 播放动画 */
    85. public void play() {
    86. animation.play();
    87. }
    88. /** 暂停动画 */
    89. public void pause() {
    90. animation.pause();
    91. }
    92. /** 加速动画 */
    93. public void increaseSpeed() {
    94. animation.setRate(animation.getRate() + 0.1);
    95. }
    96. /** 减速动画 */
    97. public void decreaseSpeed() {
    98. animation.setRate(animation.getRate() <= 0 ? 0 : animation.getRate()-0.1);
    99. }
    100. /** 返回动画速度属性 */
    101. public DoubleProperty rateProperty() {
    102. return animation.rateProperty();
    103. }
    104. /** 移动弹球 */
    105. protected void moveBall() {
    106. try {
    107. for (Node node : this.getChildren()) { //遍历弹球列表
    108. Ball ball = (Ball)node;
    109. //到达边界时改变方向
    110. if (ball.getCenterX() < ball.getRadius() || ball.getCenterX() > getWidth()-ball.getRadius())
    111. ball.dx *= -1;
    112. if (ball.getCenterY() < ball.getRadius() || ball.getCenterY() > getHeight()-ball.getRadius())
    113. ball.dy *= -1;
    114. //设置新坐标
    115. ball.setCenterX(ball.dx + ball.getCenterX());
    116. ball.setCenterY(ball.dy + ball.getCenterY());
    117. //合并弹球(在边界时弹球半径的突然增大会呈水平或垂直方向(拉伸场景可解决))
    118. for (Node node1: this.getChildren()) { //再次遍历列表
    119. Ball ball1 = (Ball)node1;
    120. //如果俩球不相等且相交
    121. if (!ball1.equals(ball) && (new Point2D(ball.getCenterX(), ball.getCenterY()).distance(ball1.getCenterX(),
    122. ball1.getCenterY()) <= ball.getRadius()+ball1.getRadius())) {
    123. int index1 = getChildren().indexOf(ball); //获取弹球下标
    124. int index2 = getChildren().indexOf(ball1);
    125. //移除后面的球
    126. if (index1 < index2) {
    127. ball.setRadius(ball.getRadius() + ball1.getRadius());
    128. getChildren().remove(ball1);
    129. } else {
    130. ball1.setRadius(ball1.getRadius() + ball.getRadius());
    131. getChildren().remove(ball);
    132. }
    133. }
    134. }
    135. }
    136. } catch (ConcurrentModificationException ex) { //捕获并发修改异常
    137. }
    138. }
    139. }
    140. /** 内部类(弹球类) */
    141. class Ball extends Circle {
    142. private double dx = 1, dy = 1;
    143. public Ball(double centerX, double centerY, double radius, Paint fill) {
    144. super(centerX, centerY, radius, fill);
    145. }
    146. }
    147. }

     

  • 相关阅读:
    class09:ejs模块
    MIPI CSI-2笔记(17) -- 数据格式(RGB图像数据)
    Java:强引用、软引用、弱引用与虚引用
    Python进阶学习之阅读代码
    基于JavaWeb+SpringBoot+Vue房屋租赁系统微信小程序系统的设计和实现
    取消检验批过账(取消检验批UD判定到Rerel,再把非限性库存转到质检库存,然后就可以取101收货了)
    deepstream·在python中安装pyds包
    Java 对象序列化
    【神印王座】易军献身为林鑫挡箭,万万没想到林鑫太坑,大跌眼镜
    下海建龙宫
  • 原文地址:https://blog.csdn.net/m0_62659797/article/details/126239798