赞
踩
Java中提供了Graphics类,他是一个抽象的画笔,可以在Canvas组件(画布)上绘制丰富多彩的几何图和位图。
Graphics常用的画图方法如下:
AWT专门提供了一个Canvas类作为绘图的画布,程序可以通过创建Canvas的子类,并重写它的paint()方法来实现绘图。
测试代码:
- 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() {
- @Override
- public 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();
- @Override
- public 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方法)
知识点:
示例代码:
- 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; //宽度60
- private 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() {
- @Override
- public void windowClosing(WindowEvent e) {
- System.out.println("关闭游戏");
- System.exit(0);
- }
- });
-
- /**
- * 定义画布
- */
- Canvas canvas = new Canvas(){
- @Override
- public 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() {
- @Override
- public 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() { //添加键盘监听器
- @Override
- public 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();
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。