přejít na obsah přejít na navigaci

Linux E X P R E S, Open-source alternativy Adobe Flashe: Jednoduchá flashová střílečka v SWFMILL a MTASC

Open-source alternativy Adobe Flashe: Jednoduchá flashová střílečka v SWFMILL a MTASC

flash.png

Kombinace nástrojů SWFMILL a MTASC vytváří skutečně silný nástroj, se kterým už lze vytvářet náročnější aplikace, jako jsou například flashové hry. Nevadí přitom, že se jedná o otevřené nástroje. Naopak. Náročné projekty totiž vyžadují práci ve skupině - jeden navrhuje grafiku, druhý programuje. A proč by programátor nutně potřeboval kupovat IDE od Adobe, když mu k vytvoření programu stačí obyčejný editor, kód zkompiluje přes MTASC a sadu knihoven si vytvoří v SWFMILL? Pojďme se tedy podívat, jak se taková otevřená flashovka dělá.


V dnešním dílu si pomocí dvou otevřených nástrojů vytvoříme jednoduchou flashovou hru - Vystřílej prales!

SWFMILL

Jedná se o konzolový nástroj, který se používá pro generování swf souborů. Do nich si pomocí swfmill mohu naimportovat obrázky, zvuky, fonty nebo filmy a použít je dále jako zdrojovou knihovnu pro další zpracování pomocí jazyka ActionScript. Nicméně lze s ním vytvořit i jednoduché statické swf bez dalších možností.

Swfmill se pouští pomocí

$ swfmill simple zdrojovysoubor.xml cilovysoubor.swf

Jako zdroj používá swfmill xml soubor s několika danými tagy. Nejzákladnější struktura je následující:

<?xml version="1.0" encoding="utf-8" ?>
<movie width="320" height="240" framerate="12">
<background color="#ffffff"/>
<frame/>
</movie> 

Základem práce v swfmill je vytvoření knihovny objektů pro další práci v ActionScriptu. Ty se umísťují do párového tagu <library>. Nejčastější tagy v sekci <library> jsou:

<clip id="obrazek" import="library/soubor.jpg" />

Pomocí <clip> vytvářím komponenty nové třídy MovieClip. Právě sem importuji externě vytvořené obrázky.

<font id="jmenoFontu" import="library/Arial.ttf" glyphs="0123456789" />

Import fontů - pomocí parametru glyphs mám možnost omezit import na několik znaků. Díky tomu nevytvářím příliš velké soubory. V knihovně mám jen to potřebné.

<sound id="zvuk" import="library/blah.mp3" />

Práce se zvukem není nejpohodlnější. Údajně aby s ním šlo dále pracovat, mělo by být mp3 mono a mít frekvenci 44,1 kHz. Musím si ho upravit pomocí příkazu lame ($ lame --resample 44.1 in.mp3 out.mp3). Já načítám zvuky přímo v ActionScriptu, proto za uvedený postup neručím a uvádím ho zde pro úplnost.

<import file="library.swf" url="library/library.swf" />

Mohu importovat také jiná swf s vlastními knihovnami, která jsem si vytvořil já nebo grafik v Adobe Flashi.

<textfield id="blokTextu" width="200" height="50" size="10" font="jmenoFontu" text="Nazdar lidi!" /> 

Textové pole musí mít nadefinovánu výšku a šířku.

Po vytvoření knihovny si objekty mohu rovnou v swfmill umístit, a to pomocí nepárového tagu <place />

<place id="pozadi"  x="0" y="0" depth="1"/>

id identifikuje umístěný objekt s objektem v knihovně.

Statický flash z pralesa

Mám tři základní obrázky - hrocha, slona a ilustraci z džungle. Vytvořím XML, ve kterém nadefinuji jednotlivé objekty a určím jejich zdroj. Dále si objekt umístím na určité souřadnice. Pozor! Je důležité, aby byl každý objekt ve vlastní vrstvě (depth).

Obrázky, které máme k dispozici

Obrázky, které máme k dispoziciObrázky, které máme k dispozici

<?xml version="1.0" encoding="utf-8" ?>
<movie width="600" height="400" framerate="30">
<background color="#ffffff" />
<frame>
<library>
<clip id="pozadi" import="assets/Jungle.jpg" />
<clip id="slon" import="assets/Slon.png" />
<clip id="hroch" import="assets/Hroch.png" />
</library>
<place id="pozadi"  x="0" y="0" depth="1" />
<place id="slon"  x="140" y="300" depth="2" />
<place id="hroch"  x="430" y="300" depth="3" />
</frame>
</movie>

Soubor uložím například jako classes.xml a zkompiluji:

$ swfmill simple classes.xml build/animace.swf 

Výhody SWFMILL

  • vytváří knihovny pro další zpracování jazykem ActionScript;

  • používá standardní zápis XML, proto je práce s ním přehledná a rychlá;

  • snadná údržba a rychlá kompilace nových knihoven;

  • v novějších verzích už bez větších problémů zvládá importovat SVG grafiku. Ta se importuje ve vektorech, což je výhoda proti bitmapám, které nemůžu zvětšovat a zabírají více místa. Díky tomu lze propojit tvorbu Flashe s Inkscape. 

Obvykle nám ale nestačí statický flash a chceme jej rozpohybovat. Uznejte - statický obrázek hrocha a slona z džungle nikoho nenadchne a flash používáme proto, že chceme, aby se obrázek pohyboval a případně reagoval na ovládání uživatele. To nám umožní ActionScript - jazyk, který dokáže interpretovat plugin flashe v prohlížeči. V praxi to vypadá tak, že vytvořené swf použiji jako zdroj knihoven pro programy MTASC (programuji-li v ActionScript 2) nebo haXe (ActionScript 2 a 3).

MTASC

MTASC (Motion-Twin ActionScript 2 Compiler) je otevřený kompilátor jazyka ActionScript 2. Tento jazyk dovedou v zásadě interpretovat všechny verze Adobe Flashe od verze 6, s podstatným vylepšením od verze 8. Já sám jsem ho chtěl už odpískat a programovat pouze v ActionScriptu 3, ale v poslední době ho pracovně využívám prakticky ve všech nových aplikacích. Důvod? S ActionScriptem2 si dobře poradí Flash Lite pro mobilní zařízení. Ten je totiž postaven na Adobe Flash 8.

MTASC je dobré využít jako kompilátor pro již vytvořené knihovny pomocí swfmill nebo také pro swf vytvořené v Adobe Flashi. Výhody tohoto kompilátoru proti kompilátoru od Adobe jsou publikovány na stránkách MTASC. Za sebe oceňuji rychlost kompilace, která je u MTASC objektivně vyšší.

MTASC se pouští pomocí příkazu:

$ mtasc (naše .as soubory) -swf (swf projekt)

MTASC vezme jako zdrojovou knihovnu swf soubor, který jsme specifikovali pomocí parametru -swf, kompiluje všechny uvedené .as soubory a aktualizuje swf, ve kterém nahradí všechny vložené třídy nově zkompilovanými. Pokud swf neexistuje, vytvoří se nové, můžeme tedy vytvářet flash “z ničeho”. Chceme-li zdrojové a cílové swf odlišit, přidáme parametr -out cilovysoubor.swf

K dalším parametrům patří např:

  • -header 400:100:20:a00000 - rozměry vytvořeného Flashe, snímkování, barva pozadí

  • -main - označení hlavní třídy

  • -cp - cesta ke knihovnám

Existují dva způsoby použití swfmill a MTASC.

První způsob - Skeletal Injection Method

Vytvořím xml soubor, ve kterém popíšu kostru budoucího swf s cestami k importovaným souborům.

Tuto kostru si zkompiluji například pomocí swfmill.

Vytvořím třídu ActionScript 2 se statickou metodou main ().

Konečně příkazem mtasc “vstříknu” (inject) třídy do již existujícího swf s kostrou.

$ swfmill simple kostra.xml kostra.swf
$ mtasc -swf kostra.swf -keep -main skript.as -out kostraSeSkriptem.swf

Pro tuto metodu je charakteristická přítomnost statické metody main(), která musí být v hlavní třídě aplikace specifikované parametrem -main . Jedná se o vstupní bod (Entry Point), kterým se začne vykonávat kód. Přístup do swf je tedy pouze přes tuto main().

Tento způsob velmi podrobně a názorně popsal Adam Sádovský ve výborném článku Animované flash bannery pomocí open-source nástrojů. Ten článek doporučuji všem začátečníkům s MTASC. Já se o ní nebudu nyní zmiňovat, protože ji s MTASC nepoužívám a protože si ji ještě vyzkoušíme v dalším dílu věnovanému spolupráci swfmill a haXe.

Druhý způsob - Natural Entry Point Method

Postup u této metody je obrácený - nejdříve si vytvořím třídy, zkompiluji je pomocí MTASC a swfmill mi teprve potom vnutí tyto třídy jednotlivým objektům. Tato metoda byla popsána v článku The Natural Entry Point Method (Tutorial & Source Files) – Introducing A New Way to Create Flash Applications Using Swfmill and MTASC od Arala Balkana.

Výhodou tohoto způsobu je, že nepoužívá statickou metodu main(). Nevýhodou je větší počet swf souborů, se kterým musím pracovat.

Postup je následující:

  1. Vytvořím swf s hlavní aplikací (pomocí MTASC).
  2. Vytvořím swf s objekty, které si volají již vytvořené třídy.

Já tento způsob používám proto, že mi připadá názornější a více objektově orientovaný. Vytvářím si jednotlivé soubory s třídami a metodami. Ty až v posledním bodě aplikuji na určité objekty. K jednotlivým objektům tedy přistupuji zvlášť a nemusím přes hlavní soubor. Mám sice více samostatných souborů, ale výhodou takového programování je, že jednotlivé vytvořené soubory - třídy, pak používám v jiných aplikacích. Tento postup mi prostě sedne.

Střílečka Vystřílej prales

Vraťme se do pralesa. Nejdříve jsme vytvořili statický obrázek pralesa s hrochem a slonem. Nyní chci vytvořit jednoduchou střílečku, všechno rozpohybovat a trochu si zahrát. Ostatně proto Flash používám, nebo ne?

V první řadě si obohatíme scénu o další objekty. V editoru si nakreslíme potřebné objekty - startovací tlačítko a zaměřovač (já jsem v tomto případě použil Inkscape, soubory najdete přiložené k článku).

Další podklady

Další podkladyStartovací tlačítko a zaměřovač

Dále upravím XML pro swfmill. Vždy s ním začínám, protože při rozvrhu XML si udělám představu o vytvořené scéně, zároveň všem objektům připíšu nový parametr - class, kterým určím názvy tříd.

<?xml version="1.0" encoding="utf-8" ?>
<movie width="600" height="400" framerate="20">
<clip import="classes.swf" />
<frame>
<library>
<clip id="Aplikace" class="Aplikace" />
<clip id="Pozadi" class="Pozadi" import="assets/Jungle.jpg" />
<clip id="StartButton" class="StartButton" import="assets/NewGame.png" />
<font id="badaboom" import="assets/BadaBoomCE.otf" glyphs="VYSTŘÍLEJ PRALES!" />
<clip id="Slon" class="Objekt" import="assets/Slon.png" />
<clip id="Hroch" class="Objekt" import="assets/Hroch.png" />
<clip id="Pointer" class="Pointer" import="assets/Pointer.png" />
</library>
<place id="Aplikace" name="app" x="0" y="0" depth="1000" />
<place id="Pozadi"  x="0" y="0" depth="1" />
</frame>
</movie>

Poprvé zde importuji také fonty, s jejichž pomocí vytvořím úvodní nápis. Všimněte si, jak jsem omezil počet písem na nejnutnější znaky.

Nyní si vytvoříme jednotlivé třídy. Začneme od nejjednodušší pro zaměřovač.

Pointer.as

Nadefinujeme si pozici zaměřovače, ta bude hlídat x a y souřadnice myši ve hře.

class Pointer extends MovieClip {
function Pointer(){
}
function onEnterFrame ()
{
_x = _parent._xmouse;
_y = _parent._ymouse;
}
}
Objekt.as

Tahle třída nám bude definovat chování zvířat na obrazovce. Chování této třídy je složitější, ale v podstatě jde jen o matematický výpočet polohy objektu na obrazovce. Při inicializaci se Objekt náhodně umístí na obrazovce. Při každém novém snímku se objekt přesune úhlopříčným pohybem danou rychlostí a směrem.

Pokud se někdo chopí příležitosti, může právě v tomto bodě hru hodně vylepšit. Například lze zvyšovat rychlost pohybu při ubývání zvířat. Tím se hra stane zajímavější.

class Objekt extends MovieClip
{
var vX:Number = null;
var vY:Number = null;
function Objekt ()
{
_x = _width + Math.random() * ( Stage.width - _width );
//Následující podmínka kontroluje, zda nám objekt nevypadl z obrazovky
if ( _x > Stage.width - _width ) _x =  Stage.width - _width ; 
_y = _height + Math.random() * ( Stage.height - _height );
//Následující podmínka kontroluje, zda nám objekt nevypadl z obrazovky
if ( _y > Stage.height - _height ) _y =  Stage.height - _height ;
vX = 5;
vY = 5;
}
function onEnterFrame ()
{
_x += vX;
_y += vY;
if ( _x < 0 || _x > ( Stage.width - _width ) )
{
vX *= -1;
_x += 2 * vX;
}
if ( _y < 0 || _y > ( Stage.height - _height ) )
{
vY *= -1;	
_y += 2 * vY;
}
}
}
StartButton.as

Třída pro úvodní - startovací tlačítko. Definujeme zde jen chování při přejetí myší.

class StartButton extends MovieClip {
function StartButton(){
}
// Nadefinuji chování při přejetí myši 
function onRollOver () {
this._xscale = _yscale = 95;
//Posouvám objekt, protože změna velikosti probíhá z levého horního okraje. Existují i jiné způsoby, jak tuto vlastnost obelstít, tento je nejprimitivnější
this._x = this._x + 5 ;
}
function onRollOut () {
this._xscale = _yscale = 100;
this._x = this._x - 5 ;
}
}
JungleGame.as

V hlavní třídě aplikace začínám úvodní obrazovkou. Při stisku startovacího tlačítka, smažu úvodní obrazovku a pomocí smyčky vytvořím nové instance “slonů” a “hrochů”. Dále schovám myš a zobrazím zaměřovač. Kontroluji, zda dojde ke stisknutí myši - potom si kontroluji, zda mám zaměřovač překrytý s objektem. Pokud ano - trefa, vymažu ho. Pokud počet zvířat klesne na nulu, začínám od začátku.

Pro hlavní třídu jsem si potřeboval naimportovat třídu Delegate, pomocí které volám funkce při událostech. Třída Delegate je součástí tříd v prostředí Adobe Flashe od verze 8. Protože nepředpokládám, že byste utráceli za balík od Adobe, můžete si stáhnout její volnou verzi ze stránek autora Steva Webstera Delegate.as. Je to velmi užitečná pomůcka, protože bez ní je volání funkcí v ActionScriptu 2 mnohem pracnější. Třídu si nainstalujte do složky com/dynamicflash/utils ve složce, kde máte knihovny.

import com.dynamicflash.utils.Delegate;
//importuji třídu pro vytváření událostí 
class JungleGame extends MovieClip
{
var _numAnimals: Number; 
function JungleGame ()
{
init ();
}
function init ()
{
//ukážeme kursor myši
Mouse.show();
//umístíme startovací tlačítko
this.attachMovie ("StartButton", "_startButton", this.getNextHighestDepth()  );
this["_startButton"]._x= 200;
this["_startButton"]._y= 300;
//Vytvoříme titulku 
this.createTextField("_title",this.getNextHighestDepth(),0,0,Stage.width,200);
var tf = new TextFormat();
tf.font = "badaboom";
tf.size = 80;
tf.color = "0xffcc00";
this["_title"].text =  "VYSTŘÍLEJ PRALES!" ;
this["_title"].embedFonts = true;
this["_title"].selectable = false;
this["_title"].setTextFormat ( tf );
this["_title"]._x = 50;
this["_title"]._y = 100;
//Volám funkci při stisknutí tlačítka
var myGame = this["_startButton"].onRelease = Delegate.create(this, startGame);
myGame._numElephants = 6;
myGame._numHippo = 6;
}     
private function startGame () : Void
{
//Hra začíná - smažu původní obrazovku
this["_startButton"].removeMovieClip();
this["_title"].removeTextField();
//Načtu hodnoty pro počet objektů na obrazovce 
var _numElephants = arguments.caller._numElephants;
var _numHippo = arguments.caller._numHippo;
_numAnimals = _numElephants + _numHippo;
//Vytvořím slony
for ( var i = 0; i < _numElephants; i++ )
{
this.attachMovie ("Slon", "_slon" + i,this.getNextHighestDepth() );
}
//Vytvořím hrochy   
for ( var i = 0; i < _numHippo; i++ )
{
this.attachMovie ("Hroch", "_hroch" + i, this.getNextHighestDepth()  );
}
//Schovám myš a zobrazím zaměřovač 
Mouse.hide();
this.attachMovie ("Pointer", "_pointer", this.getNextHighestDepth() );
}
function onMouseDown () {
//Při stisku myši zkontroluji, zda se mi zaměřovač nepřekrývá s nějakým objektem
//Zároveň počítám
for(var i in this ){
if (this[i] instanceof Objekt ) {
if (this["_pointer"].hitTest(this[i])) {
this[i].removeMovieClip();
_numAnimals = _numAnimals - 1;
//Jestliže už nezbývá žádné zvíře 
if (_numAnimals == 0 ) {
this["_pointer"].removeMovieClip();
init ();  
}
}
}
}
}
}

Nyní si musím vše zkompilovat.  Nejdříve třídy pomocí MTASC do jednoho swf souboru. Ten pak teprve použiji v swfmill, kde ho umístím mezi ostatní nadefinované objekty. 

$ mtasc -header 1:1:20 -swf classes.swf JungleGame.as Objekt.as Pointer.as StartButton.as
$ swfmill simple classes.xml build/jungle-game.swf

Upozorňuji, že prvním příkazem jsem vytvořil swf velké 1px na 1px. To vůbec nevadí, protože se jedná jen o zkompilované třídy - konečný rozměr je nadefinován v XML swfmill. Také jsem musel vyjmenovat všechny použité třídy. Tenhle krok není nutný, pokud je volám z kódu jiné uvedené třídy.

V praxi kompilace probíhá tak, že tyto dva příklady mám umístěné ve spustitelném skriptu ./make.sh. Ušetří mi to čas, protože nemusím pořád dokola psát dva příkazy.

Ještě jeden tip pro budoucí programátory

Pro spouštění funkcí při události jsme použili otevřenou třídu Delegate. Podobně užitečná je třída GDispatcher pro hlídání událostí. Ta nahrazuje komponentu EventDispatcher z balíku Adobe. Lze si ji stáhnout z gskinner.com.

Nainstaluje se do adresáře com/gskinner/events ve vaší knihovně.

MTASC doporučuji pro:

  • tvorbu swf souborů pro co nejširší okruh klientů (bannery, hry pro web i mobilní zařízení);

  • nenáročné flashové aplikace;

  • výhodou je dobrá spolupráce s swfmill;

  • kompatibilita s ActionScriptem 2. Přestože se jedná o starý jazyk, lze ho použít prakticky na všech osobních počítačích a mobilních zařízení (s výjimkou iPadu). Chcete-li mít 100% jistotu, že váš flash uvidí opravdu všichni, potom sáhněte po MTASC;

  • díky kompatibilitě s ActionScriptem 2 máte přístup k ohromnému množství různých tutoriálů a knih. Za dobu existence ActionScriptem 2 už jich je na webu a v antikvariátech pěkná řádka.

V příštím díle se budeme věnovat jazyku haXe. Ukážeme si, jak propojit swfmill s haXe a vytvoříme si MP3 přehrávač s externím playlistem.

Všechny materiály z tohoto dílu si můžete stáhnout v archivech swfmill.zip a mtasc.zip.

Nahoru

Odkazy

Příspěvky

Open-source alternativy Adobe Flashe: Jednoduchá flashová střílečka v SWFMILL a MTASC
e.xitu.s 24. 08. 2010, 10:29:57
Odpovědět  Odkaz 
Místo flashe bych už raději propagovat html5 a css3, většina prohlížečů to už podporuje. A k tomu je to svobodná alternativa k flashi, takže co řešit.
Luděk Janda Re:Open-source alternativy Adobe Flashe: Jednoduchá flashová střílečka v SWFMILL a MTASC
Luděk Janda 29. 08. 2010, 21:48:55
Odpovědět  Odkaz 
No, smyslem tohoto seriálu není něco propagovat. Já prostě vytvářím aplikace ve flashi, který vyžaduje drtivá většina zákazníků, a dělám ho čistě bez balíku od Adobe (a v linuxu). Protože to považuji za zajímavé, tak jsem se rozhodl s ostatními podělit. Jestli tedy něco propaguji, pak je to zásada: "Proč používat profi nástroje, když si vše můžu udělat na koleně!" :-)
Open-source alternativy Adobe Flashe: Jednoduchá flashová střílečka v SWFMILL a MTASC
Roman Mátyus 24. 08. 2010, 22:18:37
Odpovědět  Odkaz 
Ja naopak veľmi vítam tento článok (seriál). Flash má veľmi dobrú dostupnosť a široké použitie. Pre mnoho vecí je dobre použiteľný. Sám som do prechodu na linux s ním pracoval. Možno to znovu nejak prekopem :)
JGqIYYQJgb
djhonfcqil 30. 10. 2011, 21:12:44
Odpovědět  Odkaz 
kjZzdG wxxvupwcnujb, [url=http://rjrkfynliokb.com/]rjrkfynliokb[/url], [link=http://lasjfmfdljjp.com/]lasjfmfdljjp[/link], http://hiurghsbsxym.com/
JGqIYYQJgb
djhonfcqil 30. 10. 2011, 21:13:28
Odpovědět  Odkaz 
kjZzdG wxxvupwcnujb, [url=http://rjrkfynliokb.com/]rjrkfynliokb[/url], [link=http://lasjfmfdljjp.com/]lasjfmfdljjp[/link], http://hiurghsbsxym.com/
JGqIYYQJgb
djhonfcqil 30. 10. 2011, 21:14:44
Odpovědět  Odkaz 
kjZzdG wxxvupwcnujb, [url=http://rjrkfynliokb.com/]rjrkfynliokb[/url], [link=http://lasjfmfdljjp.com/]lasjfmfdljjp[/link], http://hiurghsbsxym.com/

Přidat názor

Nejsou podporovány žádné značky, komentáře jsou jen čistě textové. Více o diskuzích a pravidlech najdete v nápovědě.
Diskuzi můžete sledovat pomocí RSS kanálu rss



 
 

Top články z OpenOffice.cz