58同城烟台网站建设百度助手app下载安装
画笔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 组合起来可以组成人类可见的任何颜色
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.concurrent.atomic.AtomicReference;/*** @ClassName DrawSimple* @projectName: object1* @author: Zhangmingda* @description: XXX* date: 2021/5/7.*/
public class DrawSimple {public static void main(String[] args) {//窗口Frame frame = new Frame("简单画图示例");//窗口关闭按钮动作WindowListener closeListener = new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.out.println("窗口关闭");System.exit(0);}};frame.addWindowListener(closeListener);//绘制图形形状变量AtomicReference<String> shape = new AtomicReference<>();//画布Canvas canvas = new Canvas(){Random random = new Random();@Overridepublic void paint(Graphics g) { //g为画笔System.out.println("画图中");if (shape.get() != null){switch (shape.get()){case "rect"://设置画笔颜色Color(红色值,绿色值,蓝色值) 红绿蓝三色取值范围0-255 组合起来可以组成人类可见的任何颜色g.setColor(new Color(255,0,0));//画矩形,x,y分别为起始位置,后面两个参数为宽,高 Random.nextInt(200) 为伪随机数g.drawRect(20,20,random.nextInt(200),random.nextInt(200));break;case "oval"://画椭圆g.setColor(new Color(10,100,30));g.drawOval(40,20,random.nextInt(200),random.nextInt(200));}}}};canvas.setSize(250,250);frame.add(canvas);//容器Panel panel = new Panel();//按钮Button drawRectBtn = new Button("画矩形");Button drawOvalBtn = new Button("画椭圆");//按钮绑定事件drawRectBtn.addActionListener(e ->{shape.set("rect");canvas.repaint(); //清除后重新绘制});drawOvalBtn.addActionListener(e ->{shape.set("oval");canvas.repaint(); //清除后重新绘制});panel.add(drawOvalBtn);panel.add(drawRectBtn);frame.add(panel,BorderLayout.SOUTH);//窗口自动调整大小frame.setLocation(400,300);frame.pack();frame.setVisible(true);}
}
开发弹球小游戏
开发思路:动画,就是间隔一定的时间(通常小于1秒)重新绘制新的图像,两次绘制的图像之间差异较小,肉眼看起来就成了所谓的动画。这个程序我们要借助Swing包的一个Timer类。
Timer(int delay, ActionListener listener): 每间隔delay秒,系统自动出发ActionListener监听器里的事件处理器(actionPerformed方法)
知识点:
- KeyListener 实现监听键盘按键 触发移动球拍
- 画图逻辑:球到了画布的X轴左右端,向相反方向移动位置,到了Y轴顶端位置0,或者到了球拍接触区域向相反方向移动位置
- Timer定时器,每隔毫秒级别重新画图
- 用到的变量全部定义为类变量
示例代码:
import com.sun.source.tree.NewClassTree;import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;/*** @ClassName Pinball* @projectName: object1* @author: Zhangmingda* @description: XXX* date: 2021/5/7.*/
public class Pinball {//定义球拍初始位置用随机对象private Random random = new Random();/*** 设置画布大小:宽高*/private int canvaWidth = 300;private int canvaHeight = 400;/*** 球拍初始参数*///拍子大小位置private int rectX = random.nextInt(200); //拍子所在横坐标位置,要在画布范围之内,private int rectY = 355; //拍子所在Y轴坐标位置小于400,和底部留一定空隙private int rectWidth = 60; //宽度60private int rectHeight = 15; //厚度//拍子按下按键拍子移动的像素大小(步伐)int pace =10;/*** 小球的尺寸位置初始参数*/private int ballSize =15;private int ballX = random.nextInt(200);private int ballY = random.nextInt(100);/*** 小球运动速度值*/private int ballYSpeed = 5; //Y 轴移动速度private double xyRate = random.nextDouble() - 0.5; //X轴相对比Y轴运动速度的比率,返回一个-0.5 ~0.5之间的数,移动方向为向左或者向右private int ballXSpeed = (int) (ballYSpeed * xyRate * 2); // X 轴运动的速度/*** 定时器Timer*/private Timer timer;/*** 游戏是否结束*/private boolean gameOver = false;/*** 方法*/public void play(){/*** 定义窗口,设置位置和关闭动作*/Frame frame = new Frame("弹球小游戏");frame.setLocation(400,300);frame.addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.out.println("关闭游戏");System.exit(0);}});/*** 定义画布*/Canvas canvas = new Canvas(){@Overridepublic void paint(Graphics g) {//如果没有结束if (!gameOver){//画球g.setColor(new Color(30,200,150));g.fillOval(ballX,ballY,ballSize, ballSize);//画下面的矩形拍子g.setColor(new Color(75, 79, 194));g.fillRect(rectX, rectY, rectWidth, rectHeight);}else { //gameOver了g.setColor(Color.RED);g.setFont(new Font("Times",Font.BOLD,30)); // 设置字体格式字体g.drawString("Game Over",70, 200);}}};//设置画布大小canvas.setPreferredSize(new Dimension(canvaWidth,canvaHeight));frame.add(canvas);/*** 游戏核心逻辑:动画效果*/timer = new Timer(50, new ActionListener() {@Overridepublic void actionPerformed(ActionEvent actionEvent) {/*** 如果到了X轴的两端,就向反方向画图*/if (ballX < 0 || ballX >= canvaWidth - ballSize)ballXSpeed = -ballXSpeed;/*** 如果球接触到了球拍的X轴和Y轴区域内,或者跑到顶端(ballY 坐标小于0)就把Y轴反向移动*/if (ballY < 0 || (ballY >= rectY - ballSize && ballY < rectY - ballSize/2) && ballX + ballSize /2 >= rectX && ballX + ballSize /2 <= rectX + rectWidth) {System.out.println("ballX:"+ ballX + "ballY:"+ ballY + "rectX:" + rectX + "rectY:" +rectY);ballYSpeed = -ballYSpeed; //反向速度}else if (ballY >= canvaHeight){ //如果球已经掉到画布之外或者 球拍下 就停止timer循环timer.stop();gameOver = true;}ballX += ballXSpeed;ballY += ballYSpeed;canvas.repaint();}});timer.start();/*** 窗口监听键盘*/KeyListener keyListener = new KeyAdapter() { //添加键盘监听器@Overridepublic void keyPressed(KeyEvent e) { //当键盘被按下时触发
// System.out.println("按下键盘");int KeyCode = e.getKeyCode(); //获取按下的键盘代号switch (KeyCode){case KeyEvent.VK_LEFT://左键按下if(rectX - pace > 0){rectX -= pace;}else {rectX = 0;}break;case KeyEvent.VK_RIGHT://右键按下if (rectX + pace < canvaWidth - rectWidth){rectX += pace;}else {rectX = canvaWidth -rectWidth;}break;}canvas.repaint();}};frame.addKeyListener(keyListener);/*** 窗口大小自动调节到最优,显示窗口*/frame.pack();frame.setVisible(true);}public static void main(String[] args) {new Pinball().play();}
}