Иллюстрированный самоучитель по 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).