java swing 绘制简单的运动圆- 2019-11-18 23:25:03- java: java,game,游戏,swing
    —-
    思考:
    1.为什么我没有想到要提供canvasWidth和canvasHeight的get方法?而且只提供get方法?为什么不提供set方法?
    因为canvasWidth和canvasHeight是窗口的宽和高,给外部提供set方法之后,就可以被外部随意修改产生安全问题。
    2.画板的部分为什么提供内部类?
    因为画板是这个窗口的一部分。

    1. /**
    2. * 入口启动
    3. */
    4. public static void main(String[] args) {
    5. int sceneWidth = 800;
    6. int sceneHeight = 800;
    7. int count = 10;
    8. MyCircleRun myCircleRun = new MyCircleRun(sceneWidth, sceneHeight, count);
    9. myCircleRun.run("我的圈圈");
    10. }
    11. /**
    12. * 启动类
    13. * @Author Bai
    14. * @Date 2019-11-24 18:12
    15. */
    16. public class MyCircleRun {
    17. /**
    18. * 窗口宽
    19. */
    20. private Integer sceneWidth;
    21. /**
    22. * 窗口高
    23. */
    24. private Integer sceneHeight;
    25. /**
    26. * 要绘制的数据
    27. */
    28. private Circle[] circles;
    29. public MyCircleRun(int sceneWidth, int sceneHeight, int count) {
    30. this.sceneHeight = sceneHeight;
    31. this.sceneWidth = sceneWidth;
    32. circles = new Circle[count];
    33. double r = 70;
    34. for (int i = 0; i < count; i++) {
    35. //sceneWidth - 2 * r 画布的宽-直径 作为随机取值的最大值 +r是为了不让圆在画布边缘随生成
    36. double x = (Math.random() * (sceneWidth - 2 * r)) + r;
    37. double y = (Math.random() * (sceneHeight - 2 * r)) + r;
    38. //随机生成速度
    39. double vx = (Math.random() * 11) - 5;
    40. double vy = (Math.random() * 11) - 5;
    41. circles[i] = new Circle(x, y, r, vx, vy);
    42. }
    43. }
    44. public void run(String windowTitle) {
    45. EventQueue.invokeLater(() -> {
    46. MyCircleJFrame frame = new MyCircleJFrame(windowTitle, sceneWidth, sceneHeight);
    47. new Thread(() -> {
    48. // TODO: 2019/11/24 为什么用循环? 不停的重新绘制
    49. while (true) {
    50. // 绘制数据
    51. frame.render(circles);
    52. AlgoVisHelper.pause(20);
    53. // 更新数据(重新绘制后生效)
    54. for (Circle circle : circles) {
    55. circle.move(sceneWidth, sceneHeight);
    56. }
    57. }
    58. }).start();
    59. });
    60. }
    61. }
    62. /**
    63. * 要绘制的类
    64. */
    65. @Data
    66. public class Circle {
    67. private double x;
    68. private double y;
    69. private double r;
    70. private double xv;
    71. private double yv;
    72. public Circle(double x, double y, double r, double xv, double yv) {
    73. this.x = x;
    74. this.y = y;
    75. this.r = r;
    76. this.xv = xv;
    77. this.yv = yv;
    78. }
    79. /**
    80. * 移动
    81. */
    82. public void move(int sceneWidth, int sceneHeight) {
    83. //碰到画布边缘自动弹回来
    84. //计算最小边缘
    85. double yMin = r;
    86. double xMin = r;
    87. //计算最大边缘
    88. double yMax = sceneHeight - r;
    89. double xMax = sceneWidth - r;
    90. //移动速度可以是负的 往反方向移动
    91. if (x >= xMax || x <= xMin) {
    92. xv = -xv;
    93. }
    94. if (y >= yMax || y <= yMin) {
    95. yv = -yv;
    96. }
    97. x += xv;
    98. y += yv;
    99. }
    100. }
    101. /**
    102. * 绘制工具类
    103. */
    104. public class AlgoVisHelper {
    105. private AlgoVisHelper() {
    106. }
    107. public static void strokeCircle(Graphics2D g, double x, double y, double r) {
    108. Ellipse2D circle = new Ellipse2D.Double(x - r, y - r, 2 * r, 2 * r);
    109. g.draw(circle);
    110. }
    111. public static void fillCircle(Graphics2D g, int x, int y, int r) {
    112. Ellipse2D circle = new Ellipse2D.Double(x - r, y - r, 2 * r, 2 * r);
    113. g.fill(circle);
    114. }
    115. public static void setColor(Graphics2D g, Color color) {
    116. g.setColor(color);
    117. }
    118. public static void setStrokeWidth(Graphics2D g, int w) {
    119. int strokeWidth = w;
    120. g.setStroke(new BasicStroke(strokeWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    121. }
    122. /**
    123. * 绘制等待时间
    124. *
    125. * @param t
    126. */
    127. public static void pause(int t) {
    128. try {
    129. Thread.sleep(t);
    130. } catch (InterruptedException e) {
    131. System.out.println("Error sleeping");
    132. }
    133. }
    134. }