|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Анимация Есть несколько способов создать анимацию. Самый простой из них — записать заранее все необходимые кадры в графические файлы, загрузить их в оперативную память В виде Объектов класса 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).
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||