上一节中,我们用Java显示了一张图片,这一节我们来尝试着用Java来显示一个超简单的动画。
先说点和代码无关的事情。动画的话,其实就是利用了人眼的视觉停留特性。如果眼前的画面以0.1秒的间隔来更换的话,就会给人一种画面在运动的感觉,小时候在书角画小人时利用的也是这一点。
首先,我们需要找一组连续起来的图片,制作过GIF动画图片的朋友应该体会的就更深一点。
代码方面是在第一节的基础上修改制成的,Main和MyFrame这两个类没有做修改。
面板源码:
- package simple;
- import java.awt.Dimension;
- import java.awt.Graphics;
- import java.awt.Graphics2D;
- import java.awt.Image;
- import java.awt.Panel;
- import java.awt.image.BufferedImage;
- public class MyPanel extends Panel implements Runnable{
- private final int width=519;
- private final int height=569;
- private final Image screenImage = new BufferedImage(width, height, 2);
- private final Graphics2D screenGraphic = (Graphics2D) screenImage.getGraphics();
- private Image backgroundImage;
- private Image[] images;
- private int index;
- private Thread animator;
- public MyPanel() {
- loadImage();
- // 设定焦点在本窗体
- setFocusable(true);
- // 设定初始构造时面板大小,这里先采用图片的大小
- setPreferredSize(new Dimension(width,height));
- // 绘制背景
- drawView();
- animator=new Thread(this);
- start();
- }
- private void start() {
- animator.start();
- }
- /**
- * 载入图像
- */
- private void loadImage() {
- //因为图片更改了位置,所以换成用工具类来获取图片
- backgroundImage = FileUtility.getBackground();
- images = FileUtility.getImages("f");
- }
- private void drawView() {
- screenGraphic.drawImage(backgroundImage, 0, 0, null);
- }
- @Override
- public void update(Graphics g) {
- paint(g);
- }
- public void paint(Graphics g) {
- int animWidth = images[index].getWidth(null);
- int animHeight = images[index].getHeight(null);
- screenGraphic.drawImage(images[index], (width - animWidth) / 2+5,(height - animHeight) / 2+5, null); //图片选择的不太好,需要微调一下。如果选择了OK的图片就不必+5了
- g.drawImage(screenImage, 0, 0, null);
- }
- public void run() {
- Thread me = Thread.currentThread();
- while (animator == me) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- break;
- }
- synchronized (this) {
- index++;
- if (index >= images.length) {
- index = 0;
- }
- }
- repaint();
- }
- }
- }
新增的工具类源码:
- package simple;
- import java.awt.Image;
- import java.io.File;
- import javax.swing.ImageIcon;
- public class FileUtility {
- /**
- * 获得文件夹下*.png文件的个数
- *
- * @return
- */
- public static int getFileCount() {
- // 获得真实路径
- String userDir = System.getProperty("user.dir");
- // 获得文件分隔符(在 UNIX 系统中是"/")
- String se = System.getProperty("file.separator");
- File file= new File(userDir+se+"image");
- if (!file.isDirectory()) {
- return 0;
- }
- String[] fileStr = file.list();
- int count = 0;
- for (String s : fileStr) {
- String tail = s.substring(s.lastIndexOf("."), s.length()); // 小尾巴
- if (".png".equalsIgnoreCase(tail)) { //不区分大小写
- count++;
- }
- }
- return count;
- }
- public static Image getBackground() {
- String userDir = System.getProperty("user.dir");// 获得真实路径
- String se = System.getProperty("file.separator"); // 获得文件分隔符(在 UNIX 系统中是"/")
- ImageIcon icon = new ImageIcon(userDir+se+"image"+se+"background.png");
- if(icon.getImage().getWidth(null)<0) {
- return null; //如果未找到图片则返回空
- }
- return icon.getImage();
- }
- /**
- * 获得指定人物的动画效果图
- *
- * @param name
- * @return
- */
- static Image[] getImages(String name) {
- String userDir = System.getProperty("user.dir");// 获得真实路径
- String se = System.getProperty("file.separator"); // 获得文件分隔符(在 UNIX 系统中是"/")
- Image[] images=new Image[getFileCount()-1]; //减掉的1是背景图片
- for(int i=0;i<images.length;i++) {
- ImageIcon icon = new ImageIcon(userDir+se+"image"+se+"f"+i+".png");
- images[i]=icon.getImage();
- }
- return images;
- }
- /** 测试用主方法 */
- public static void main(String[] args) {
- System.out.println(getFileCount());
- }
- }
在MyPanel类中引入了线程,每0.1秒从图片数组中取出下一次元素刷新一次画面
总结:这几个类其实写的很粗糙,最多只是抛砖引玉喽。
源代码:http://download.csdn.net/detail/w93223010/4529090
FROM: http://blog.csdn.net/w93223010/article/details/7912606