マルチメディアコンピューティングU

第6章:アニメーション

6.1 原理

復習:アプレットの処理の流れ

6.2 定石

アニメーションの定石

スレッド:いくつかのプログラムを同時並行的に走らせる仕組み

例題6.2 定石のひな形

import java.applet.*;
import java.awt.*;

public class ani1 extends Applet implements Runnable {
        int x;
        Thread th;

        public void start() {
                th= new Thread(this);
                th.start();
        }

        public void run() {
                for( x=0; x<180; ++x) {
                        repaint();
                        try {
                                Thread.sleep(100);
                        }
                        catch(InterruptedException e) {
                        }
                }
        }

        public void paint(Graphics g) {
                g.drawOval(x,90,19,19);
                g.drawLine(0,110,199,110);
        }
}

6.3 簡単な応用

スレッドの制御

6.4 ダブル・バッファとマルチ・スレッド

シングルバッファ

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class ani2b extends Applet implements Runnable, ActionListener {
        //Image fb;
        Graphics gg;
        int k=0;
        int dt=1000;
        Thread th;
        Button b1=new Button("中断");
        Button b2=new Button("再開");
        Button b3=new Button("速く");
        Button b4=new Button("遅く");

        public void init() {
                //fb=createImage(200,200);
                //gg=fb.getGraphics();
                add(b1);
                add(b2);
                add(b3);
                add(b4);
                b1.addActionListener(this);
                b2.addActionListener(this);
                b3.addActionListener(this);
                b4.addActionListener(this);
        }

        public void start() {
                th= new Thread(this);
                th.start();
        }

        public void run() {
                th.suspend();
                for( int i=0; i<1000000; ++i) {
                        repaint();
                        ++k;
                        try {
                                Thread.sleep(dt);
                        }
                        catch(InterruptedException e) {
                        }
                }
        }

        public void actionPerformed(ActionEvent e) {
                String s;
                s=e.getActionCommand();
                if (s == "中断" )
                        th.suspend();
                else if (s == "再開" )
                        th.resume();
                else if (s == "速く" )
                        dt/=2;
                else if (s == "遅く" )
                        dt*=2;
        }

        public void paint(Graphics g) {
                double ss,cc,t,r=75.0,rr=20.0;
                double u, rrr=70.0;
                double v, rrrr=60.0;
                double da=3.1416/30.0;
                double db=3.1416/6.0;
                int x,y,xx,yy;
                gg = g;

                gg.setColor(Color.white);
                gg.fillOval(20,40,160,160);
                gg.setColor(Color.black);
                gg.drawOval(19,39,162,162);
                gg.drawOval(20,40,160,160);
                gg.drawOval(21,41,158,158);
                gg.drawOval(97,117,6,6);
                t=da*(double)(k%60);
                ss=Math.sin(t);
                cc=Math.cos(t);
                x=100+(int)(r*ss);
                y=120-(int)(r*cc);
                xx=100-(int)(rr*ss);
                yy=120+(int)(rr*cc);
                gg.drawLine(xx,yy,x,y);
                gg.setColor(Color.blue);
                u=da*(double)((k/60)%60);
                ss=Math.sin(u);
                cc=Math.cos(u);
                x=100+(int)(rrr*ss);
                y=120-(int)(rrr*cc);
                gg.drawLine(100,120,x,y);
                gg.setColor(Color.red);
                v=da*(double)k/3600.0;
                ss=Math.sin(v);
                cc=Math.cos(v);
                x=100+(int)(rrrr*ss);
                y=120-(int)(rrrr*cc);
                gg.drawLine(100,120,x,y);
                //g.drawImage(fb,0,0,this);
        }

        public void update(Graphics g) {
                paint(g);
        }
}

ダブルバッファ

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class ani2c extends Applet implements Runnable, ActionListener {
        Image fb;
        Graphics gg;
        int k=0;
        int dt=1000;
        Thread th;
        Button b1=new Button("中断");
        Button b2=new Button("再開");
        Button b3=new Button("速く");
        Button b4=new Button("遅く");

        public void init() {
                fb=createImage(200,200);
                gg=fb.getGraphics();
                add(b1);
                add(b2);
                add(b3);
                add(b4);
                b1.addActionListener(this);
                b2.addActionListener(this);
                b3.addActionListener(this);
                b4.addActionListener(this);
        }

        public void start() {
                th= new Thread(this);
                th.start();
        }

        public void run() {
                th.suspend();
                for( int i=0; i<1000000; ++i) {
                        repaint();
                        ++k;
                        try {
                                Thread.sleep(dt);
                        }
                        catch(InterruptedException e) {
                        }
                }
        }

        public void actionPerformed(ActionEvent e) {
                String s;
                s=e.getActionCommand();
                if (s == "中断" )
                        th.suspend();
                else if (s == "再開" )
                        th.resume();
                else if (s == "速く" )
                        dt/=2;
                else if (s == "遅く" )
                        dt*=2;
        }

        public void paint(Graphics g) {
                double ss,cc,t,r=75.0,rr=20.0;
                double u, rrr=70.0;
                double v, rrrr=60.0;
                double da=3.1416/30.0;
                double db=3.1416/6.0;
                int x,y,xx,yy;

                gg.setColor(Color.white);
                gg.fillOval(20,40,160,160);
                gg.setColor(Color.black);
                gg.drawOval(19,39,162,162);
                gg.drawOval(20,40,160,160);
                gg.drawOval(21,41,158,158);
                gg.drawOval(97,117,6,6);
                t=da*(double)(k%60);
                ss=Math.sin(t);
                cc=Math.cos(t);
                x=100+(int)(r*ss);
                y=120-(int)(r*cc);
                xx=100-(int)(rr*ss);
                yy=120+(int)(rr*cc);
                gg.drawLine(xx,yy,x,y);
                gg.setColor(Color.blue);
                u=da*(double)((k/60)%60);
                ss=Math.sin(u);
                cc=Math.cos(u);
                x=100+(int)(rrr*ss);
                y=120-(int)(rrr*cc);
                gg.drawLine(100,120,x,y);
                gg.setColor(Color.red);
                v=da*(double)k/3600.0;
                ss=Math.sin(v);
                cc=Math.cos(v);
                x=100+(int)(rrrr*ss);
                y=120-(int)(rrrr*cc);
                gg.drawLine(100,120,x,y);
                g.drawImage(fb,0,0,this);
        }

        public void update(Graphics g) {
                paint(g);
        }
}

マルチスレッド

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class ani3 extends Applet  {
        Mojiban f1,f2;
        Tokei th1,th2;

        public void init() {
                f1=new Mojiban("時計1");
                f1.setSize(200,240);
                f1.show();
                th1=new Tokei(f1);
                th1.start();
                f2=new Mojiban("時計2");
                f2.setSize(200,240);
                f2.show();
                th2=new Tokei(f2);
                th2.start();
        }
}

class Mojiban extends Frame implements ActionListener {
        double tt=0.0;
        double dt=1.0;
        double dtq=0.0;
        Button b1,b2,b3,b4;

        public Mojiban(String s) {
                super(s);
                setSize(200,240);
                b1=new Button("中断");
                b2=new Button("再開");
                b3=new Button("速く");
                b4=new Button("遅く");
                setLayout(new FlowLayout());
                add(b1);
                add(b2);
                add(b3);
                add(b4);
                b1.addActionListener(this);
                b2.addActionListener(this);
                b3.addActionListener(this);
                b4.addActionListener(this);
        }

        public void actionPerformed(ActionEvent e) {
                String s;
                s=e.getActionCommand();
                if(s == "中断" ) {
                        if(dt!=0.0) {
                                dtq=dt;
                                dt=0.0;
                        };
                }
                else if(s == "再開" )
                        dt=dtq;
                else if(s == "速く" )
                        dt*=2.0;
                else if(s == "遅く" )
                        dt/=2.0;
        }

        public void update(Graphics g) {
                g.setColor(Color.white);
                g.drawRect(0,0,200,200);
                g.setColor(Color.black);
                paint(g);
        }

        public void paint(Graphics g) {
                double ss,cc,t,r=75.0,rr=20.0;
                double u, rrr=70.0;
                double v, rrrr=60.0;
                double da=3.1416/30.0;
                double db=3.1416/6.0;
                int x,y,xx,yy;

                g.setColor(Color.white);
                g.fillOval(20,40,160,160);
                g.setColor(Color.black);
                g.drawOval(19,39,162,162);
                g.drawOval(20,40,160,160);
                g.drawOval(21,41,158,158);
                g.drawOval(97,117,6,6);
                t=da*(double)((int)tt%60);
                ss=Math.sin(t);
                cc=Math.cos(t);
                x=100+(int)(r*ss);
                y=120-(int)(r*cc);
                xx=100-(int)(rr*ss);
                yy=120+(int)(rr*cc);
                g.drawLine(xx,yy,x,y);
                g.setColor(Color.blue);
                u=da*(double)(((int)tt/60)%60);
                ss=Math.sin(u);
                cc=Math.cos(u);
                x=100+(int)(rrr*ss);
                y=120-(int)(rrr*cc);
                g.drawLine(100,120,x,y);
                g.setColor(Color.red);
                v=db*tt/3600.0;
                ss=Math.sin(v);
                cc=Math.cos(v);
                x=100+(int)(rrrr*ss);
                y=120-(int)(rrrr*cc);
                g.drawLine(100,120,x,y);
                tt+=dt;
        }
}

class Tokei extends Thread {
        Mojiban mojiban;

        Tokei(Mojiban fr) {
                mojiban=fr;
        }

        public void run() {
                for( int i=0; i<10000; ++i) {
                        try {
                                sleep(100);
                        }
                        catch(InterruptedException e) {
                        }
                        mojiban.repaint();
                }
        }
}

6.5 画像を用いるアニメーション

スライド・ショー

import java.applet.*;
import java.awt.*;
import java.net.*;

public class im1 extends Applet implements Runnable {
        Image im;
        String fn[]={"1-front.jpg","3-chapel.jpg","5-main2.jpg","9-seikyo.jpg","a-library.jpg","b-sst.jpg"};
        String gn[]={"KSC","チャペル","総政","生協","図書館","理工学部"};
        String ms;
        Thread th;

        public void start() {
                th = new Thread(this);
                th.start();
        }


        public void paint(Graphics g) {
                g.drawString(ms,10,15);
                g.drawImage(im,0,20,this);
        }

        public void run() {
                for( int i=0; i<6; ++i) {
                        ms=gn[i];
                        repaint();
                        im=getImage(getDocumentBase(),fn[i]);
                        repaint();
                        try {
                                Thread.sleep(10000);
                        }
                        catch(InterruptedException e) {
                        }
                }
        }
}

付録1.スレッド制御推奨版

import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class ani2d extends Applet implements Runnable, ActionListener {
        Image fb;
        Graphics gg;
        int k=0;
        int dt=1000;
        Thread th;
        Button b1=new Button("中断");
        Button b2=new Button("再開");
        Button b3=new Button("速く");
        Button b4=new Button("遅く");

        public void init() {
                fb=createImage(200,200);
                gg=fb.getGraphics();
                add(b1);
                add(b2);
                add(b3);
                add(b4);
                b1.addActionListener(this);
                b2.addActionListener(this);
                b3.addActionListener(this);
                b4.addActionListener(this);
        }

        public void start() {
                stop();
        }

        public void stop() {
                th = null;
        }

        public void run() {
                while( th != null ) {
                        repaint();
                        ++k;
                        try {
                                Thread.sleep(dt);
                        }
                        catch(InterruptedException e) {
                        }
                }
        }

        public void actionPerformed(ActionEvent e) {
                String s;
                s=e.getActionCommand();
                if (s == "中断" ) {
                        stop();
                }
                else if (s == "再開" ) {
                        if(th == null) {
                                th = new Thread(this);
                                th.start();
                        }
                }
                else if (s == "速く" )
                        dt/=2;
                else if (s == "遅く" )
                        dt*=2;
        }

        public void paint(Graphics g) {
                double ss,cc,t,r=75.0,rr=20.0;
                double u, rrr=70.0;
                double v, rrrr=60.0;
                double da=3.1416/30.0;
                double db=3.1416/6.0;
                int x,y,xx,yy;

                gg.setColor(Color.white);
                gg.fillOval(20,40,160,160);
                gg.setColor(Color.black);
                gg.drawOval(19,39,162,162);
                gg.drawOval(20,40,160,160);
                gg.drawOval(21,41,158,158);
                gg.drawOval(97,117,6,6);
                t=da*(double)(k%60);
                ss=Math.sin(t);
                cc=Math.cos(t);
                x=100+(int)(r*ss);
                y=120-(int)(r*cc);
                xx=100-(int)(rr*ss);
                yy=120+(int)(rr*cc);
                gg.drawLine(xx,yy,x,y);
                gg.setColor(Color.blue);
                u=da*(double)((k/60)%60);
                ss=Math.sin(u);
                cc=Math.cos(u);
                x=100+(int)(rrr*ss);
                y=120-(int)(rrr*cc);
                gg.drawLine(100,120,x,y);
                gg.setColor(Color.red);
                v=da*(double)k/3600.0;
                ss=Math.sin(v);
                cc=Math.cos(v);
                x=100+(int)(rrrr*ss);
                y=120-(int)(rrrr*cc);
                gg.drawLine(100,120,x,y);
                g.drawImage(fb,0,0,this);
        }

        public void update(Graphics g) {
                paint(g);
        }
}

2003.12.9