Programování

Animace v appletech Java

Tento článek popisuje, jak implementovat animaci pomocí API appletu Java. Popisuje běžně používané techniky a poskytuje jednoduchý příklad pro ilustraci každé techniky.

Základní animační techniky

V Javě je možné mnoho forem animace. Všichni mají společné to, že na obrazovce vytvářejí určitý druh pohybu kreslením po sobě jdoucích snímků relativně vysokou rychlostí (obvykle asi 10–20krát za sekundu).

Začneme vytvořením jednoduchého appletu šablony pro vytváření animací a pomalým zpracováním, dokud nedojdeme k poměrně úplnému appletu.

Pomocí vlákna

Chcete-li aktualizovat obrazovku několikrát za sekundu, musíte vytvořit nové vlákno Java, které obsahuje smyčku animace. Smyčka animace je zodpovědná za sledování aktuálního snímku a za vyžádání pravidelných aktualizací obrazovky. Chcete-li implementovat vlákno, musíte buď vytvořit podtřídu Vlákno nebo dodržovat Spustitelný rozhraní.

Častou chybou je vložení smyčky animace do malovat() metoda appletu. To bude mít podivné vedlejší účinky, protože drží hlavní vlákno AWT, které má na starosti veškeré kreslení a zpracování událostí.

Jako příklad jsem napsal malý applet šablony s názvem Example1Applet, který ilustruje obecný obrys animačního appletu. Example1Applet ukazuje, jak vytvořit vlákno a zavolat překreslit () metoda ve stanovených intervalech. Počet snímků za sekundu je určen předáním parametru appletu. Zde je příklad toho, co byste vložili do dokumentu HTML:

Tady je Example1Applet.

Poznámka:

Tento applet ve skutečnosti ještě nic na obrazovku nekreslí. Kreslení na obrazovku je vysvětleno později. Všimněte si také, že applet ničí své vlákno animace, kdykoli uživatel opustí stránku (což má za následek applet stop() volaná metoda). Tím je zajištěno, že applet nebude ztrácet čas CPU, zatímco jeho stránka nebude viditelná.

Udržování konstantní obnovovací frekvence

Ve výše uvedeném příkladu applet jednoduše spí po stanovenou dobu mezi snímky. To má tu nevýhodu, že někdy čekáte příliš dlouho. Chcete-li získat 10 snímků za sekundu, neměli byste mezi snímky čekat 100 milisekund, protože pouhým spuštěním vlákna ztratíte nějaký čas.

Následující applet, Example2Applet, ukazuje, jak si udržet lepší čas. Jednoduše vypočítá správné zpoždění mezi snímky sledováním počátečního času. Vypočítá odhadované požadované zpoždění mezi snímky na základě aktuálního času.

Tady je Example2Applet.

Malování každého rámečku

Zbývá zbarvit každý rám. V předchozích příkladech voláme překreslit () pro každý snímek, což způsobí applet malovat() metoda, která se má volat. Aplikace Example3Applet má a malovat() metoda, která vykreslí číslo aktuálního snímku na obrazovku.

Zde je Example3Applet v akci, následovaný výpisem kódu.

Poznámka:

Pokud určíte rychlost snímků za velmi vysokou (řekněme 100 snímků za sekundu), hodnota běh() metoda zavolá překreslit () 100krát za sekundu. Ne vždy to však bude mít za následek 100 volání na malovat() za sekundu, protože když vydáte požadavek na překreslení příliš rychle, sbalí se do aktualizace na jednu obrazovku. Proto sledujeme aktuální číslo snímku v běh() metoda spíše než v malovat() metoda.

Generování grafiky

Nyní pojďme animovat něco, co je o něco těžší nakreslit. Příklad4Applet kreslí kombinaci sinusových vln. Pro každou souřadnici x nakreslí krátkou svislou čáru. Všechny tyto řádky společně tvoří jednoduchý graf, který se mění pro každý snímek. Bohužel zjistíte, že tento přístup hodně bliká. V následující části vysvětlíme příčinu blikání a několik nápravných opatření.

Zde je Example4Applet v akci, následovaný výpisem kódu.

Vyvarujte se nadměrného blikání

Blikání, které vidíte v Příkladu 4Applet, má dvě příčiny: malování každého rámečku trvá příliš dlouho (kvůli množství výpočtu, které je vyžadováno během překreslení) a celé pozadí je před malovat() je nazýván. Zatímco probíhá výpočet dalšího snímku, uživatel vidí pozadí animace.

Tato krátká doba mezi vyjasněním pozadí a vymalováním sinusové vlny je považována za záblesk. Na některých platformách, jako je PC, je blikání zřetelnější než na X Windows. Důvodem je to, že grafika X Windows je ukládána do vyrovnávací paměti, čímž je blesk o něco kratší.

Blikání můžete výrazně omezit pomocí dvou jednoduchých triků: implementace Aktualizace() metoda a použití dvojitého ukládání do vyrovnávací paměti (někdy známé jako pomocí backbufferu).

Přepsat metodu update ()

Když AWT obdrží žádost o překreslení appletu, zavolá na applet Aktualizace() metoda. Ve výchozím nastavení je Aktualizace() metoda vymaže pozadí appletu a poté zavolá malovat() metoda. Zrušením Aktualizace() metoda pro zahrnutí výkresového kódu, který býval v malovat() metodou, vyhneme se tomu, aby byla při každém překreslení vymazána celá oblast appletu.

Nyní, když pozadí již není automaticky vyčištěno, musíme to udělat sami v Aktualizace() metoda. Nyní můžeme jednotlivě svislou čáru grafu vymazat jednotlivě, než nakreslíme novou čáru, čímž zcela eliminujeme blikání. Tento efekt je uveden v příkladu 5Applet.

Zde je Example5Applet v akci, následovaný výpisem kódu.

Poznámka:

Kdykoli přepíšete Aktualizace() metodu, stále musíte implementovat malovat(). Je to proto, že malovat() Tato metoda je volána přímo systémem kreslení AWT, kdykoli dojde k „poškození“ kreslicí oblasti appletu - například když je z obrazovky odstraněno okno zakrývající část kreslicí oblasti appletu. Vaše malovat() implementace může jednoduše zavolat Aktualizace().

Dvojité ukládání do vyrovnávací paměti

Dalším způsobem, jak omezit blikání mezi snímky, je použití dvojitého ukládání do vyrovnávací paměti. Tato technika se používá v mnoha animačních appletech.

Obecným principem je, že vytvoříte obraz mimo obrazovku, do obrázku nakreslíte rámeček a poté jedním obrázkem plácnete celý obraz na obrazovku drawImage (). Výhodou je, že většina výkresů se provádí mimo obrazovku. Konečné malování obrazu mimo obrazovku na obrazovku je obvykle mnohem efektivnější než malování rámečku přímo na obrazovku.

Aplet sinusových vln s dvojitým ukládáním do vyrovnávací paměti je uveden v příkladu 6Applet. Uvidíte, že animace je docela plynulá a při kreslení rámečku nepotřebujete žádné speciální triky. Jedinou nevýhodou je, že musíte přidělit obraz mimo obrazovku, který je stejně velký jako oblast kreslení. Pokud je kreslicí plocha velmi velká, může to vyžadovat spoustu paměti.

Zde je Example6Applet v akci, následovaný výpisem kódu.

Poznámka:

Pokud používáte dvojité ukládání do vyrovnávací paměti, musíte přepsat Aktualizace() protože nechcete, aby bylo pozadí appletu před malováním rámečku vymazáno. (Pozadí si sami vymažete nakreslením obrázku mimo obrazovku.)

Používání obrázků

Nyní přepíšeme paintFrame () metoda s metodou, která animuje některé obrázky. To přidává problému drobné komplikace. Obrázky jsou poměrně velké a načítají se postupně. Plné vykreslení obrázků může trvat dlouho, zvláště když je načítáte přes pomalé připojení. To je důvod, proč drawImage () metoda přebírá čtvrtý argument, objekt ImageObserver. Pozorovatel obrazu je objekt, který je upozorněn, když dorazí více obrazových dat. K získání obrázků používáme getImage () metoda.

Přesouvání obrazu po obrazovce

Tento první applet pro animaci obrázků, Example7Applet, používá následující dva obrázky:

world.gif: car.gif:

Jako pozadí se použije obraz světa a obrázek vozu se na něj dvakrát nakreslí, čímž se vytvoří animace dvou automobilů závodících po celém světě.

Tady je Example7Applet v akci, následovaný výpisem kódu.

Zobrazení sekvence obrázků

Příklad 8Applet ukazuje, jak vytvořit animaci pomocí samostatných obrázků pro každý snímek. Zde se používá 10 snímků, které se používají:

T1.gif: T2.gif: T3.gif: T4.gif: T5.gif:

T6.gif:

T7.gif:

T8.gif:

T9.gif:

T10.gif:

K odstranění blikání stále používáme dvojité ukládání do vyrovnávací paměti. Důvodem je, že každý obrázek, který vykreslujeme, je částečně průhledný, a proto musíme před nakreslením dalšího vymazat každý snímek. To by způsobilo blikání bez dvojitého ukládání do vyrovnávací paměti.

Tady je Example8Applet v akci, následovaný výpisem kódu.

Poznámka:

Při zobrazování sekvencí obrázků je třeba dbát na správné zarovnání obrázků. Nejjednodušší způsob je zajistit, aby všechny obrázky měly stejnou velikost a mohly být kresleny ve stejné pozici. Pokud tomu tak není, bude váš applet muset nakreslit každý snímek s jiným odsazením.

Pomocí MediaTracker se vyhnete přírůstkovému zobrazení

Když program Java načte obrázek, může jej zobrazit před úplným načtením obrázku. Uživatel vidí obrázek, který se vykresluje, nejprve neúplně a poté postupně a stále více a více po načtení obrázku. Toto přírůstkové zobrazení poskytuje uživateli zpětnou vazbu (zlepšuje vnímaný výkon) a umožňuje programu snadno provádět další úlohy při načítání obrazu.

Pokud jde o animaci, může být přírůstkové zobrazení obrazu užitečné pro obrázky na pozadí, ale při použití pro animované obrázky může být velmi rušivé. Proto je někdy žádoucí počkat, než se načte celá animace, než ji zobrazíte.

Můžete použít Jima Grahama MediaTracker třídy ke sledování stahování obrázků, se zpožděním zobrazení animace, dokud není plně stažena celá sada obrázků. Example9Applet ukazuje, jak používat MediaTracker třídy ke stažení obrázků pro vlnící se Dukeovu animaci.

Tady je Example9Applet v akci, následovaný výpisem kódu.

Přidání zvuku

Přidání zvuku do animace je snadné. Můžete použít getAudioClip () metoda získání objektu AudioClip. Později můžete klip přehrát buď jako souvislou smyčku, nebo jako jediný zvuk. Example10Applet ukazuje, jak přehrávat nepřetržitý zvuk na pozadí i opakující se zvuk během animace.

Zde je Example10Applet v akci, následovaný výpisem kódu.

Poznámka:

Při přehrávání nepřetržitého zvuku musíte pamatovat na jeho zastavení, když uživatel opustí stránku (tj. Udělejte to v appletu) stop() metoda).

Další poznámka:

Nepřetržitý zvuk může být velmi nepříjemný. Je vhodné poskytnout uživateli způsob, jak vypnout zvuk bez opuštění stránky. Můžete zadat tlačítko nebo jednoduše vypnout zvuk, když uživatel klikne na applet.

Tipy pro rychlejší načítání obrázků

Stahování animace, která používá mnoho obrázků, bude trvat dlouho. To je způsobeno hlavně skutečností, že pro každý obrazový soubor je vytvořeno nové připojení HTTP a navázání připojení může trvat několik sekund, i když existuje velká šířka pásma.

V této části si povíme o dvou formátech obrázků, které může váš applet použít k rychlejšímu stahování obrázků.

Použití obrazového pásu

Výkon stahování můžete zlepšit pomocí jediného obrázku obsahujícího několik snímků animace. Pomocí obrázku můžete z obrázku vykreslit jeden snímek clipRect () operátor. Níže je uveden příklad obrazového pásu, který se používá v appletu UnderConstruction.

Applet vytváří efekt vrtání tím, že nevymaže předchozí snímky. Pozadí se čistí jen tak často.

Zde je UnderConstruction v akci s odkazem na jeho zdrojový kód.

Mezisnímková komprese pomocí Flic

Pokud opravdu chcete zlepšit výkon stahování animace skládající se z více snímků, musíte použít nějakou formu komprese mezi snímky.

Animační nástroje

V tuto chvíli (leden 1996) je k dispozici několik nástrojů, které vám pomohou vytvářet animace založené na prostředí Java. Nejlepší nástroj, který jsem mohl najít, je DimensionX's The Easy Animator (TEA) (dříve známý jako JAM). Umožňuje vám interaktivně vytvářet animace. Rádi bychom vyzvali vývojáře, aby psali více nástrojů pro vytváření animací v Javě.

Pokud máte několik připravených obrázků k zobrazení, můžete použít applet Animator. Animator má mnoho parametrů, které vám umožňují specifikovat spojité zvuky, zvuky specifické pro snímek, časování a polohy jednotlivých snímků, úvodní obrázek, pořadí snímků atd.

Měli byste také navštívit stránku Animace Gamelan a najít mnoho appletů, které používají animaci.

Závěr

Doufám, že tento článek pomůže vývojářům appletů psát více a lepší animační applety. Rovněž doufám, že brzy budou k dispozici lepší nástroje.

Arthur van Hoff byl donedávna vedoucím technikem společnosti Sun Microsystems a vývoju jazyka Java se věnuje od roku 1993. Je autorem prvního kompilátoru jazyka Java napsaného výhradně v jazyce Java. Nedávno opustil Sun a založil novou společnost společně se Sami Shaio, Kim Polese a Jonathanem Paynem. Nová společnost se zaměří na budování Java aplikací. Kathy Walrath je technickou spisovatelkou společnosti Sun Microsystems. V týmu Java pracuje od roku 1993. V současné době spolupracuje s Mary Campione na kurzu Java Tutorial: Object-Oriented Programming for the Internet, applet-enhanced tutorial for learn the Java language, applet programming, and Java GUI programování . Kromě toho, že bude k dispozici online, bude Java Tutorial vydán letos v létě jako součást Addison-Wesley Java Series.

Tento příběh „Animace v appletech Java“ původně publikoval JavaWorld.