Иллюстрированный самоучитель по Java

       

Анимация


Есть несколько способов создать анимацию. Самый простой из них — записать заранее все необходимые кадры в графические файлы, загрузить их в оперативную память В виде Объектов класса Image или Bufferedlmage и выводить по очереди на экран.

Это сделано в листинге 15.9. Заготовлено десять кадров в файлах runl.gif, run2.gif, , runl0.gif. Они загружаются в массив imgt] и выводятся на экран циклически 100 раз, с задержкой в 0,1 сек.

Листинг 15.9.

Простая анимация 

import java.awt.*; 

import ]ava.awt.event.*;

class SimpleAnim extends Frame{

private Image[] img = new Image[10]; 

private int count; 

SimpleAnim(String s){ super(s);

MediaTracker tr = new MediaTracker(this); 

for (int k = 0; k < 10; k++){



img[k] = getToolkit(}.getlmage("run"+(k+D+".gif"); 

tr.addlmage(img[k], 0); 

try{

tr.waitForAll(); // Ждем загрузки всех изображений 

}catch(InterruptedException e)(} 

setSize(400, 300); 

setvisible(true);

},

public void paint(Graphics g){

g.drawImage(img[count % 10], 0, 0, this);

}

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

public void go(){ while(count < 100){

repaint(); // Выводим следующий кадр 

try{       // Задержка в 0.1 сек

Thread.sleep(100); 

}catch(InterruptedException e){)

count++; 

public static void main(String[] args){

SimpleAnim f = new SimpleAnim(" Простая анимация");

f.go();

f.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent ev){

System.exit(0); }

}); 

}

Обратите внимание на следующее важное обстоятельство. Мы не можем обратиться прямо к методу paint () для перерисовки окна компонента, потому что выполнение этого метода связано с операционной системой — метод paint о выполняется автоматически при каждом изменении содержимого окна, его перемещении и изменении размеров. Для запроса на перерисовку окна в классе component есть метод repaint ().


Метод repaint о ждет, когда представится вшможность перер/иеозать

окне,

и потом обращается к методу update (Graphics gj. При этом нескольку обращений к repaint о могут быть произведены исполняющей системой Java за один раз.

Метод update() сначала обращается к методу g.ciearRectO, заполняющему окно цветом фона, а уж затем к методу paint (g). Полный исходный текст таков:

public void update(Graphics g){

if ((this instanceof java.awt.Canvas) ||

(this instanceof java.awt.Panel)      || 

(this instanceof java.awt.Frame)      || 

(this instanceof java.awt.Dialog)     ||

(this instanceof java.awt.Window)){

g.clearRect(0, 0, width, height); 

}

paint(g); 

}

Если кадры анимации полностью перерисовывают окно, то его очистка методом clearRecto не нужна. Более того, она часто вызывает неприятное мерцание из-за появления на мгновение белого фона. В таком случае надо сделать следующее переопределение:

public void update(Graphics g) { 

paint(g);

В листинге 15.9 это переопределение сделано как комментарий.

Для "легких" компонентов дело обстоит сложнее. Метод repaint () последовательно обращается к методам repaint () объемлющих "легких" контейнеров, пока не встретится "тяжелый" контейнер, чаще всего это экземпляр класса Container. В нем вызывается метод update о, очищающий и перерисовывающий контейнер. После этого идет обращение к методам update о всех "легких" компонентов в контейнере.

Отсюда следует, что для устранения мерцания "легких" компонентов необходимо переопределять метод update о первого объемлющего "тяжелого" контейнера, обращаясь в нем к методам super.update (g) или super.paint(g).

Если кадры покрывают только часть окна, причем каждый раз новую, то очистка окна необходима, иначе старые кадры останутся в окне, появится "хвост". Чтобы устранить мерцание, используют прием, получивший название

"двойная буферизация "

(double buffering).


Содержание раздела