【老白学 Java】简单位移动画

简单位移动画

文章来源:《Head First Java》修炼感悟。

上一篇文章中,老白利用内部类的特性完成了多个事件的处理,感觉还不错。 为了更深入理解内部类,本篇文章继续使用内部类创建一个画板,完成简单的位移动画,感兴趣的小伙伴可以继续往下看。

怎样实现位移动画

把一个图案从一个位置移动到另一个位置,我们看到的移动过程称为位移动画。 实现位移动画很简单,你可以这样考虑:

  1. 在起始位置绘制图案;
  2. 改变绘制坐标重新绘制这个图案;
  3. 以一个合适的频率不断重复上述操作,直到绘制到终点。

这里有几个关键点需要注意:

  • 如何更新绘制位置;
  • 如何调用绘制方法;
  • 如何使用内部类充当画板。

下面我们通过一个例子来演示生成位移动画的过程。

程序代码

为简单起见,例子中仅绘制了一个简单的椭圆形图案,当然你也可以绘制一张图片,效果会更好。

以下是完整代码:

java 复制代码
import javax.swing.*;
import java.awt.*;
/**
 * 文件:SimpleAnimation.java
 * 描述:利用内部类实现画板功能,完成一个简单的位移动画。
 */
public class SimpleAnimation {
	private int x = 50;			// 绘制坐标x
	private int y = 50;			// 绘制坐标y
	private DrawPanel panel;	// 自定义画板
	
	public static void main(String[] args) {
		new SimpleAnimation().go();
	}
	
	public void go() {
		JFrame frame = new JFrame();
		panel = new DrawPanel();

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().add(panel);
		frame.setSize(300, 300);
		frame.setVisible(true);

		draw();	// 绘制方法
	}
	// 绘制方法
	private void draw() {
		for (int i = 0; i < 130; i++) {
			x++;
			y++;
			
			panel.repaint();	// 重绘,由系统调用绘制方法
			
			try {
				Thread.sleep(50);	// 刻意让线程休息 50ms
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	// 自定义的画板
	class DrawPanel extends JPanel {
		public void paintComponent(Graphics g) {
			g.setColor(Color.GREEN);
			g.fillOval(x, y, 40, 40);
		}
	}
}

需要注意,每次绘制结束后都要清屏,即便是内容没有变化也要这样做。所谓「清屏」就是指把过期画面清除,然后再重新绘制新内容,不然会出现类似「拖尾」的诡异画面,就像这样:

清屏很简单,只要使用背景颜色重新填充整个画面就可以了,就像这样:

java 复制代码
// 绘制方法
public void paintComponent(Graphics g) {
	// 清屏,使用白色填充整个背景
	g.setColor(Color.WHITE);
	g.fillRect(0, 0, this.getWidth(), this.getHeight());
	// 填充图案
	g.setColor(Color.GREEN);
	g.fillOval(x, y, 40, 40);
}

再来看看效果:

看起来还不错。

其实动画原理很简单,比如游戏中的角色行走动画,实际上就是不断绘制一组序列图片再加上位移动画,看起来就像是在不断行走。

内容预告

前面添加组件的方式多少有些投机取巧的成分,下一篇文章老白会为你详细解读 GUI 组件的布局管理器。


《 上一篇 处理多发事件
相关推荐
折哥的程序人生 · 物流技术专研4 小时前
第4篇:Lambda 简化策略模式(Java 8+)
java·设计模式·策略模式·函数式编程·lambda·代码简化·扩充系列
researcher-Jiang4 小时前
高性能计算之OpenMP——超算习堂学习1
android·java·学习
西门吹-禅6 小时前
java springboot N+1问题
java·开发语言·spring boot
DLYSB_6 小时前
生命通道:如何用 HIS 医疗系统直连网络声光终端,打造“零延误”的危急值响应网关?
java·网络·数据库·报警灯
skywalk81636 小时前
设计并实现段言的 C FFI 绑定机制 @Trae
c语言·开发语言·python·编程
weixin_BYSJ19876 小时前
SpringBoot + MySQL 乒乓球运动员信息管理系统项目实战--附源码04954
java·javascript·spring boot·python·django·flask·php
AI小码6 小时前
LLM 应用的缓存工程:当每次 API 调用都在燃烧成本
java·人工智能·spring·计算机·llm·编程·api
Hui Baby7 小时前
Spring Security
java·后端·spring
IT笔记8 小时前
【Rust】Rust Match 模式匹配详解
java·开发语言·rust
2zcode8 小时前
免费开源项目文档:基于MATLAB卷积神经网络的口罩佩戴检测系统
开发语言·matlab·cnn