当前位置:   article > 正文

java 图形化小工具Abstract Window Toolit :画笔Graphics,画布Canvas(),弹球小游戏_java graphics类绘制折线 drawpolygon

java graphics类绘制折线 drawpolygon

画笔Graphics

Java中提供了Graphics类,他是一个抽象的画笔,可以在Canvas组件(画布)上绘制丰富多彩的几何图和位图

Graphics常用的画图方法如下:

  • drawLine(): 绘制直线
  • drawString(): 绘制字符串
  • drawRect(): 绘制矩形
  • drawRoundRect(): 绘制带圆角的矩形
  • drawOval():绘制椭圆形
  • drawPolygon():绘制多边形边框
  • drawArc():绘制一段圆弧(可能是椭圆的圆弧)
  • drawPolyline():绘制折线
  • fillRect():填充一个矩形区域
  • fillRoundRect():填充一个圆角矩形区域
  • fillOval():填充椭圆形
  • fillPolygon():填充多边形边框
  • fillArc():填充一段圆弧(可能是椭圆的圆弧)
  • drawImage():绘制位图

AWT专门提供了一个Canvas类作为绘图的画布,程序可以通过创建Canvas的子类,并重写它的paint()方法来实现绘图。

测试代码:

  • Canvas()画布类 paint方法画图,方法中传入画笔形参
  • Canvas()画布类 setSize(250,250);方法设置画布大小
  • Canvas()画布类 repaint(); //清除后重新绘制
  • Graphics().setColor方法设置画笔颜色,画笔执行画图动作(红色值,绿色值,蓝色值) 红绿蓝三色取值范围0-255 组合起来可以组成人类可见的任何颜色
 
  1. import java.awt.*;
  2. import java.awt.event.*;
  3. import java.util.Random;
  4. import java.util.concurrent.atomic.AtomicReference;
  5. /**
  6. * @ClassName DrawSimple
  7. * @projectName: object1
  8. * @author: Zhangmingda
  9. * @description: XXX
  10. * date: 2021/5/7.
  11. */
  12. public class DrawSimple {
  13. public static void main(String[] args) {
  14. //窗口
  15. Frame frame = new Frame("简单画图示例");
  16. //窗口关闭按钮动作
  17. WindowListener closeListener = new WindowAdapter() {
  18. @Override
  19. public void windowClosing(WindowEvent e) {
  20. System.out.println("窗口关闭");
  21. System.exit(0);
  22. }
  23. };
  24. frame.addWindowListener(closeListener);
  25. //绘制图形形状变量
  26. AtomicReference<String> shape = new AtomicReference<>();
  27. //画布
  28. Canvas canvas = new Canvas(){
  29. Random random = new Random();
  30. @Override
  31. public void paint(Graphics g) { //g为画笔
  32. System.out.println("画图中");
  33. if (shape.get() != null){
  34. switch (shape.get()){
  35. case "rect":
  36. //设置画笔颜色Color(红色值,绿色值,蓝色值) 红绿蓝三色取值范围0-255 组合起来可以组成人类可见的任何颜色
  37. g.setColor(new Color(255,0,0));
  38. //画矩形,x,y分别为起始位置,后面两个参数为宽,高 Random.nextInt(200) 为伪随机数
  39. g.drawRect(20,20,random.nextInt(200),random.nextInt(200));
  40. break;
  41. case "oval":
  42. //画椭圆
  43. g.setColor(new Color(10,100,30));
  44. g.drawOval(40,20,random.nextInt(200),random.nextInt(200));
  45. }
  46. }
  47. }
  48. };
  49. canvas.setSize(250,250);
  50. frame.add(canvas);
  51. //容器
  52. Panel panel = new Panel();
  53. //按钮
  54. Button drawRectBtn = new Button("画矩形");
  55. Button drawOvalBtn = new Button("画椭圆");
  56. //按钮绑定事件
  57. drawRectBtn.addActionListener(e ->{
  58. shape.set("rect");
  59. canvas.repaint(); //清除后重新绘制
  60. });
  61. drawOvalBtn.addActionListener(e ->{
  62. shape.set("oval");
  63. canvas.repaint(); //清除后重新绘制
  64. });
  65. panel.add(drawOvalBtn);
  66. panel.add(drawRectBtn);
  67. frame.add(panel,BorderLayout.SOUTH);
  68. //窗口自动调整大小
  69. frame.setLocation(400,300);
  70. frame.pack();
  71. frame.setVisible(true);
  72. }
  73. }

开发弹球小游戏

开发思路:动画,就是间隔一定的时间(通常小于1秒)重新绘制新的图像,两次绘制的图像之间差异较小,肉眼看起来就成了所谓的动画。这个程序我们要借助Swing包的一个Timer类。

Timer(int delay, ActionListener listener): 每间隔delay秒,系统自动出发ActionListener监听器里的事件处理器(actionPerformed方法)

知识点:

  • KeyListener 实现监听键盘按键 触发移动球拍
  • 画图逻辑:球到了画布的X轴左右端,向相反方向移动位置,到了Y轴顶端位置0,或者到了球拍接触区域向相反方向移动位置
  • Timer定时器,每隔毫秒级别重新画图
  • 用到的变量全部定义为类变量

 示例代码:

  1. import com.sun.source.tree.NewClassTree;
  2. import javax.swing.*;
  3. import java.awt.*;
  4. import java.awt.event.*;
  5. import java.util.Random;
  6. /**
  7. * @ClassName Pinball
  8. * @projectName: object1
  9. * @author: Zhangmingda
  10. * @description: XXX
  11. * date: 2021/5/7.
  12. */
  13. public class Pinball {
  14. //定义球拍初始位置用随机对象
  15. private Random random = new Random();
  16. /**
  17. * 设置画布大小:宽高
  18. */
  19. private int canvaWidth = 300;
  20. private int canvaHeight = 400;
  21. /**
  22. * 球拍初始参数
  23. */
  24. //拍子大小位置
  25. private int rectX = random.nextInt(200); //拍子所在横坐标位置,要在画布范围之内,
  26. private int rectY = 355; //拍子所在Y轴坐标位置小于400,和底部留一定空隙
  27. private int rectWidth = 60; //宽度60
  28. private int rectHeight = 15; //厚度
  29. //拍子按下按键拍子移动的像素大小(步伐)
  30. int pace =10;
  31. /**
  32. * 小球的尺寸位置初始参数
  33. */
  34. private int ballSize =15;
  35. private int ballX = random.nextInt(200);
  36. private int ballY = random.nextInt(100);
  37. /**
  38. * 小球运动速度值
  39. */
  40. private int ballYSpeed = 5; //Y 轴移动速度
  41. private double xyRate = random.nextDouble() - 0.5; //X轴相对比Y轴运动速度的比率,返回一个-0.5 ~0.5之间的数,移动方向为向左或者向右
  42. private int ballXSpeed = (int) (ballYSpeed * xyRate * 2); // X 轴运动的速度
  43. /**
  44. * 定时器Timer
  45. */
  46. private Timer timer;
  47. /**
  48. * 游戏是否结束
  49. */
  50. private boolean gameOver = false;
  51. /**
  52. * 方法
  53. */
  54. public void play(){
  55. /**
  56. * 定义窗口,设置位置和关闭动作
  57. */
  58. Frame frame = new Frame("弹球小游戏");
  59. frame.setLocation(400,300);
  60. frame.addWindowListener(new WindowAdapter() {
  61. @Override
  62. public void windowClosing(WindowEvent e) {
  63. System.out.println("关闭游戏");
  64. System.exit(0);
  65. }
  66. });
  67. /**
  68. * 定义画布
  69. */
  70. Canvas canvas = new Canvas(){
  71. @Override
  72. public void paint(Graphics g) {
  73. //如果没有结束
  74. if (!gameOver){
  75. //画球
  76. g.setColor(new Color(30,200,150));
  77. g.fillOval(ballX,ballY,ballSize, ballSize);
  78. //画下面的矩形拍子
  79. g.setColor(new Color(75, 79, 194));
  80. g.fillRect(rectX, rectY, rectWidth, rectHeight);
  81. }else { //gameOver了
  82. g.setColor(Color.RED);
  83. g.setFont(new Font("Times",Font.BOLD,30)); // 设置字体格式字体
  84. g.drawString("Game Over",70, 200);
  85. }
  86. }
  87. };
  88. //设置画布大小
  89. canvas.setPreferredSize(new Dimension(canvaWidth,canvaHeight));
  90. frame.add(canvas);
  91. /**
  92. * 游戏核心逻辑:动画效果
  93. */
  94. timer = new Timer(50, new ActionListener() {
  95. @Override
  96. public void actionPerformed(ActionEvent actionEvent) {
  97. /**
  98. * 如果到了X轴的两端,就向反方向画图
  99. */
  100. if (ballX < 0 || ballX >= canvaWidth - ballSize)
  101. ballXSpeed = -ballXSpeed;
  102. /**
  103. * 如果球接触到了球拍的X轴和Y轴区域内,或者跑到顶端(ballY 坐标小于0)就把Y轴反向移动
  104. */
  105. if (ballY < 0 || (ballY >= rectY - ballSize && ballY < rectY - ballSize/2) && ballX + ballSize /2 >= rectX && ballX + ballSize /2 <= rectX + rectWidth) {
  106. System.out.println("ballX:"+ ballX + "ballY:"+ ballY + "rectX:" + rectX + "rectY:" +rectY);
  107. ballYSpeed = -ballYSpeed; //反向速度
  108. }else if (ballY >= canvaHeight){ //如果球已经掉到画布之外或者 球拍下 就停止timer循环
  109. timer.stop();
  110. gameOver = true;
  111. }
  112. ballX += ballXSpeed;
  113. ballY += ballYSpeed;
  114. canvas.repaint();
  115. }
  116. });
  117. timer.start();
  118. /**
  119. * 窗口监听键盘
  120. */
  121. KeyListener keyListener = new KeyAdapter() { //添加键盘监听器
  122. @Override
  123. public void keyPressed(KeyEvent e) { //当键盘被按下时触发
  124. // System.out.println("按下键盘");
  125. int KeyCode = e.getKeyCode(); //获取按下的键盘代号
  126. switch (KeyCode){
  127. case KeyEvent.VK_LEFT://左键按下
  128. if(rectX - pace > 0){
  129. rectX -= pace;
  130. }else {
  131. rectX = 0;
  132. }
  133. break;
  134. case KeyEvent.VK_RIGHT://右键按下
  135. if (rectX + pace < canvaWidth - rectWidth){
  136. rectX += pace;
  137. }else {
  138. rectX = canvaWidth -rectWidth;
  139. }
  140. break;
  141. }
  142. canvas.repaint();
  143. }
  144. };
  145. frame.addKeyListener(keyListener);
  146. /**
  147. * 窗口大小自动调节到最优,显示窗口
  148. */
  149. frame.pack();
  150. frame.setVisible(true);
  151. }
  152. public static void main(String[] args) {
  153. new Pinball().play();
  154. }
  155. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/67498
推荐阅读
相关标签
  

闽ICP备14008679号