且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

史上最扯Java图形绘制(J2SE)之一JAVA动画效果

更新时间:2022-09-20 14:10:13

很多主一听说Java界面,一水的头大外带血压高,兄弟我倒觉得没什么必要。
     
    其实Java这东西吧,就简便性和其初衷而言,真他妈就在GUI 这地界是有优势的,单就其2D界面开发的易用性来说,借用《地下交通站》里黑瞎子——黑藤太君骂贾队长的话来说“全中国,不,全东亚,还能找出你这样空前 绝后的脸吗?”。所以它不普及,无外两点,1.搞Java的多半不指着这东西混饭吃,比如兄弟目前还被逼用 SSH(Struts+Spring+Hibernate)混饭吃。2.效率低,为了改变本来AWT的可移植性而开发Swing,结果搞得层次过多,效率 低下,反倒是走回AWT老路的SWT比较吃香,害得SUN从1.6开始又给AWT扩充新类,谁让Swing玩底层要靠AWT的……

  兄弟不才,大家也碰上个愣主,我就准备以闲扯的方式鼓捣鼓捣这爹不亲娘不爱的玩意。

  既然提到UI,那怎么也得有图像吧?图像,再次也得弄张图来操作吧?所以咱爷们就先从Java图像的加载入手,操练起来~

package org.test;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.URL;

/**
 * <p>
 * Title: 史上最扯Java图形绘制(J2SE)教程之一,图像变换。
 * </p>
 * <p>
 * Description:图像变换
 * </p>
 * <p>
 * Copyright: Copyright (c) 2007
 * </p>
 * 
 * @author chenpeng
 * @email:[email]ceponline@yahoo.com.cn[/email]
 * @version 0.1
 */
public class SimpleAnime extends Frame {

    /**
     * 这个例子我用AWT来讲解,实际上,我们都知道使用Swing时,对图 像绘制上有很多的优化,但是在AWT中,这些都是要我们手动来做得,
     * 所以入门我还是以AWT开始。(其实大家都知道,组件名加个J就变 Swing了……几乎不用改别的。)
     */

    private static final long serialVersionUID = 1L;

    // 用于存储图片
    Image act;

    // 俗称的帆布啦,做手机开发的话很常见
    Canvas canvas = new Canvas() {

        private static final long serialVersionUID = 1L;

        /**
         * 绘制图像,直接调用update方法(顺便说一下,若以paint调用update,
         * 再用update调用paint,会出现很好玩的事。^^)
         */
        public void paint(Graphics g) {
            update(g);
        }

        /**
         * 此方法仅在在发生变更时绘制图形
         */
        public void update(Graphics g) {
            // 参数分别为加载图像,所在Graphics上的left,所在top,图像width,图像height,目标对象
            g.drawImage(act, getWidth() / 2 - act.getWidth(null) / 2,
                    getHeight() / 2 - act.getHeight(null) / 2, act
                            .getWidth(null), act.getHeight(null), this);
        }
    };

    /**
     * 简单动画的构造
     * 
     */
    public SimpleAnime() {
        setTitle("图像变换");
        setSize(400, 400);
        // 设定背景为黑色
        setBackground(Color.BLACK);
        // 直接以class路径读取图片资源
        URL imageUrl = getClass().getResource("/image/act.jpg");
        // 获取image图像实体
        act = Toolkit.getDefaultToolkit().createImage(imageUrl);
        // 加载帆布作为背景
        add(canvas);
        class AnimeMouseListener extends MouseAdapter {
            // 鼠标进入变更
            public void mouseEntered(MouseEvent e) {
                // 顺便说一下,水平反转图的效果,是可以用代码做到的,后面讲解。
                URL imageUrl = getClass().getResource("/image/act0.jpg");
                act = Toolkit.getDefaultToolkit().createImage(imageUrl);
                canvas.repaint();
            }

            // 鼠标离开变更
            public void mouseExited(MouseEvent e) {
                URL imageUrl = getClass().getResource("/image/act.jpg");
                act = Toolkit.getDefaultToolkit().createImage(imageUrl);
                canvas.repaint();
            }
        }
        //在帆布上添加鼠标监听
        canvas.addMouseListener(new AnimeMouseListener());
    }

    /**
     * 主函数
     * 
     * @param args
     */
    public static void main(String[] args) {
        // 实例化本类
        SimpleAnime sa = new SimpleAnime();
        // 显示窗体
        sa.setVisible(true);
    }
}
(鼠标移入)
史上最扯Java图形绘制(J2SE)之一JAVA动画效果

(鼠标在外)
史上最扯Java图形绘制(J2SE)之一JAVA动画效果

这他妈才几个字母,抛除我那些狗屁都未必同通得了的注释,不到俩半字,这日本的花姑娘(正经说一句,这是月姬的同人图……)就给小爷跳上舞了,那位缺德主要加个死循环的线程进去,嘿,不赶上停电死机的,还就真格停不下来了。

闲得无聊,丧心病狂的我给加上个线程。

package org.test;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.net.URL;
/**
 * @author chenpeng
 * @email:[email]ceponline@yahoo.com.cn[/email]
 * @version 0.1
 */
public class SimpleAnime0 extends Frame {

    private static final long serialVersionUID = 1L;

    Image act1;

    Image act2;

    // 是否令图像移动

    boolean actMoving = false;

    // 初始图像编号

    int actPhase = 1;

    Canvas c = new Canvas() {

        private static final long serialVersionUID = 1L;

        /**
         * 绘制图像,直接调用update方法(顺便说一下,若以paint调用update, 再用update调用paint,会出现很好玩的事。^^)
         */
        public void paint(Graphics g) {
            update(g);
        }

        /**
         * 此方法仅在在发生变更时绘制图形
         */
        public void update(Graphics g) {
            if (actMoving) {
                if (actPhase == 1) {
                    g
                            .drawImage(act1, getWidth() / 2
                                    - act1.getWidth(null) / 2, getHeight() / 2
                                    - act1.getHeight(null) / 2, act1
                                    .getWidth(null), act1.getHeight(null), this);
                } else {
                    g
                            .drawImage(act2, getWidth() / 2
                                    - act2.getWidth(null) / 2, getHeight() / 2
                                    - act2.getHeight(null) / 2, act2
                                    .getWidth(null), act2.getHeight(null), this);
                }
            }
        }
    };

    /**
     * 简单动画的构造
     * 
     */
    public SimpleAnime0(boolean isRun) {
        actMoving = isRun;
        setTitle("图像变换");
        setSize(400, 400);
        // 设定背景为黑色
        setBackground(Color.BLACK);
        //这只是一个图像加载的演示,我们完全可以定义一个Image数组,然后动态加载
        //做成动画播放。
        URL imageUrl = getClass().getResource("/image/act.jpg");
        act1 = Toolkit.getDefaultToolkit().createImage(imageUrl);
        imageUrl = getClass().getResource("/image/act0.jpg");
        act2 = Toolkit.getDefaultToolkit().createImage(imageUrl);
        add(c);

        /**
         * 顺便介绍一下,在Swing下有Timer类,可以设定运算周期循环触发事件。 大体写法如下,不过很多人还是愿意用线程……
         * 
         * class TimerListener implements ActionListener{ public void
         * actionPerformed(ActionEvent e){ if(!actMoving) return; actPhase =
         * (actPhase == 1) ? 2 : 1; canvas.repaint(); } } javax.swing.Timer t =
         * new javax.swing.Timer(200,new TimerListener()); t.start();
         */

        Thread t = new Thread(new Timer());
        t.start();
    }

    /**
     * 事件循环处理线程
     * 
     * @author chenpeng
     */
    class Timer implements Runnable {
        public void run() {
            while (true) {
                if (!actMoving)
                    return;
                actPhase = (actPhase == 1) ? 2 : 1;
                c.repaint();
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {

                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 主函数
     * 
     * @param args
     */
    public static void main(String[] args) {
        // 实例化本类,并触发循环事件
        SimpleAnime0 sa = new SimpleAnime0(true);
        // 显示窗体
        sa.setVisible(true);
    }

}



本文转自 cping 51CTO博客,原文链接:http://blog.51cto.com/cping1982/130224