• Nu S-Au Găsit Rezultate

1.2 Text în jurul unei sfere

N/A
N/A
Protected

Academic year: 2022

Share "1.2 Text în jurul unei sfere "

Copied!
142
0
0

Text complet

(1)
(2)

În această carte am încercat să scriu câteva exemple (tutoriale) care să vă lămurească cam ce aţi putea să faceţi în Flash şi cam cum ar trebui să procedaţi pentru a face unele aplicaţii. Deşi dorinţa mea iniţială a fost ca acest volum de exemple să apară în format tipărit, nu consider că ar mai fi cazul deoarece deja a apărut mult-aşteptatul „Flash9” care are un mod diferit de programare (foarte asemanator cu Java şi incompatibil cu stilul de programare „la gramada” (adica tot codul într-un loc) din AS2).

Această carte nu este „revăzută” din punct de vedere gramatical iar codul nu a fost re-implementat de nimeni (totuşi dat fiind faptul că este copy/paste din aplicaţii care funcţionau corect la momentul scrierii, nu ar trebui să aveţi probleme). Dacă găsiţi erori de natură gramaticală sau de corectitudine a codului, vă rog să îmi scrieţi la adresa [email protected] (respectiv numărul paginii şi ce anume credeţi că este incorect).

Nu uitaţi să vizitaţi siturile:

http://www.infoiasi.ro/~vcosmin – ca sa îmi vedeţi „feţişoara de îngeraş” şi galeria de fotografii, eventual pentru a-mi lăsa un mesaj.

http://www.infoiasi.ro/~flash – aici puteţi discuta cu alţi „interesaţi” de Flash într-un forum dedicat (şi eu sunt membru aşa că vă pot răspunde chiar eu la întrebări); puteţi găsi şi alte tutoriale – pe wiki-ul dedicat Flashului (eventual puteţi scrie şi dumneavoastră un tutorial pe care să mi-l trimiteţi prin e-mail – vezi mai sus – şi să vă fac cont pentru a-l uploada);

nu în ultimul rând, tot pe acest site avem o galerie de exemple – chiar şi unele surse din această carte. La galeria de exemple puteţi să contribuiţi şi dumneavoastră (în cazul în care faceţi un exemplu care să îmi placă :D). --- deci, acest site e un bun punct de start.

Aşa că, în speranţa că acest PDF vă va fi de folos vă urez spor la învăţat Flash.

Cosmin Vârlan

(3)

Capitolul 1

1 Guizmos

Vom începe această carte prin a da câteva exemple de natura grafică, în care codul ActionScript va fi folosit cât de puţin posibil.

Această secţiune este dedicată începătorilor şi deşi efectele sunt uneori banale sau chiar inutilizabile în cadrul paginilor web, vă pot forma o idee despre puterea Flash-ului în crearea animaţiilor.

Nu ezitaţi să rezolvaţi si problemele propuse la sfârşitul fiecărui.

1.1 Caleidoscop

Dificultate: 3

Câţi dintre noi nu s-au jucat în copilărie cu un caleidoscop1... am crescut şi am schimbat jucăriile: ne plac mai mult calculatoarele, ce pot face ele sau ne place să le „convingem” să facă ce vrem noi. Vom începe această primă parte (dealtfel destul de scurtă) dedicată graficii în Flash tocmai prin realizarea unui caleidoscop.

În primul rând pentru realizarea unui caleidoscop avem nevoie de un obiect care să îşi modifice forma în timp – acesta este „motorul”

caleidoscopului care va fi copiat (de fapt oglinzile caleidoscopului dadeau acest efect de copiere) în diverse poziţii – de obicei în formă circulară.

Pentru a copia obiectul în diverse poziţii şi a-l putea roti, vom avea nevoie ca acesta să fie creat ca un MovieClip.

Pentru început vom insera în scenă un nou MovieClip (Insert -> New Symbol...) şi vom selecta opţiunea MovieClip; tot în această fereastră vom bifa opţiunea Export for ActionScript şi în câmpul „Identifier” vom trece

„forma”. Aceste setări au rolul de a crea în librărie un obiect ce va putea fi manipulat prin intermediul identificatorului său (acesta fiind „forma”) . Faptul că „Export in first frame” rămâne bifat va determina Flash-ul să definească obiectul ca făcând parte din primul cadru. Acest lucru este uneori util (atunci când la începutul Flash-ului avem nevoie de acest prim

1 Instrument în formă de tub ce conţine trei oglinzi şi câteva pietre colorate; când ne uitam

(4)

obiect) dar alteori poate dăuna proiectului pe care îl realizăm (de exemplu dacă vreţi să puneţi în primul cadru un obiect construit din foarte mulţi vectori, o imagine de dimensiuni mari sau un MP3, un eventual preloader va eşua în afişarea corectă a procentului de film Flash încărcat2). Pentru acest exemplu vom lăsa bifată această opţiune (Figura 1-1):

Figura 1-1 – Setările noului MovieClip

După apăsarea butonului OK, va apare o fereastră ce are în centru un semn plus. Acest semn este punctul de referinţă al obiectului pe care îl veţi crea. De exemplu, atunci când vom aduce MovieClip-ul din librărie şi-l

2 De obicei un preloader este aşezat în primele 2-3 cadre ale unui film Flash. Dacă în primul cadru este exportat (“Export in First Frame”) un MP3 de 4MB şi filmul are în total 5MB (deşi aceste dimensiuni sunt mai mult decat mari pentru folosirea pe web) un eventual preloader va începe să funcţioneze corect abia după ce se va trece la cadrul al doilea deci când filmul este deja 80% încărcat pe calculatorul clientului.

(5)

vom poziţiona în punctul P(0,0), de fapt acest punct de referniţă (semnul plus) va fi suprapus peste P(0,0) şi conţinutul MovieClip-ului va fi aşezat relativ faţă de el. Cum construiţi o animaţie în MovieClip-ul pe care doriţi să-l creaţi:

Selectaţi primul cadru al liniei temporale şi cu ajutorul instrumentului Text adăugaţi litera „A” scenei astfel încât semnul plus despre care tocmai am discutat să rămână în partea stângă-sus a literei adăugate. Selectaţi apoi cadrul douazeci şi apăsaţi F6 (apăsarea tastei F6 va duce la inserarea unui nou cadru-cheie în această poziţie; operaţia de inserare a unui cadru poate fi efectuată şi apăsând click dreapta pe cadrul douăzeci şi selectarea opţiunii Insert Keyframe sau din meniuri: Insert->Timeline->Keyframe). În poziţia cadrului douăzeci va apare din nou litera „A” pe care o veţi edita cu ajutorul instrumentului Text şi o veţi transforma în litera „D”. Procedaţi identic adăugând în cadrul patruzeci litera „P”, în cadrul şaizeci litera „O”

şi în sfârşit în cadrul optzeci din nou litera „A” (Figura 1-2).

Figura 1-2 – Inserarea literelor la diferite cadre (se continua cu cadrul 60, 80) Toate literele introduse până acum se comportă ca elemente textuale şi noi aveam nevoie de o formă (grafică) care să se modifice în timp. Pentru a schimba tipul literelor (din text în element grafic) selectaţi pe rând cadrele în care aţi adăugat litere, selectaţi litera adăugată şi apăsaţi combinaţia de taste CTRL+B (sau din meniuri Modify->Break Apart) – această operaţie ar trebui efectuată de cinci ori – nu uitaţi cadrul optzeci. În continuare selectaţi pe rând cadrele 0, 20, 40, 60 şi de fiecare dată, din fereastra de proprietăţi (CTRL+F3 sau din meniuri: Window -> Properties) modificaţi opţiunea Tween în Shape.

(6)

Deasupra liniei temporale selectaţi „Scene1” pentru a vă reîntoarce să editaţi documentul îniţial. Din acest moment există (cel puţin) două posibilităţi de a continua:

1. Deschideţi biblioteca de obiecte (prin apasărea tastei F11 sau CTRL+L sau din meniuri: Window -> Library) şi printr-o operaţie drag-and-drop aduceţi în scena principală simbolul nou creat. Selectaţi simbolul din scenă (ar trebui să fie încadrat într-un dreptunghi albastru) şi din fereastra de proprietăţi setaţ-i numele de instanţă „mc0” – MovieClip-ul original după care vom face copiile. Tot în fereastra de proprietăţi selectaţi în dreptului drop-down-ului „Color” opţiunea „Alpha” şi valoarea transparenţei setaţi-o la 25%.

Selectaţi primul cadru al scenei principale şi (deşi credeaţi că aţi scăpat de ActionScript) scrieţi în fereastra Actions-Frame (F9 sau Window -

>Developmenent Panels -> Actions) următorul cod:

for (i=1; i<36; i++) {

_root.mc0.duplicateMovieClip("mc"+i, i);

_root["mc"+i]._rotation = i*10;

}

Codul de mai sus are rolul de a duplica MovieClip-ul existent în scenă de încă treizeci şi cinci de ori şi de a-l roti astfel încât să se formeze o floare (operaţiile se repetă din cauza instrucţiunii „for” de 35 de ori; aceste operaţii sunt duplicare – obţinută prin apelul funcţiei „duplicateMovieClip”

şi rotire – obţinută prin modificarea parametrului „_rotation” caracteristic fiecărui MovieClip). Testaţi rezultatul apăsând combinaţia de taste CTRL+Enter (sau Control -> TestMovie).

2. Puteţi ca să adăugaţi direct primului cadru următorul script (care aduce din bibliotecă obiectul cu numele „forma”, îl duplică şi îi setează transparenţa la 25% („attactMovie” are rolul de a aduce din biblioteca un MovieClip, parametrul „_alpha” este de asemenea caracteristic oricărui MovieClip şi semnifică transparenţa):

for (i=0; i<36; i++) {

_root.attachMovie("forma","mc"+i, i);

_root["mc"+i]._rotation = i*10;

_root["mc"+i]._alpha = 25;

}

(7)

Figura 1-3 – Imaginea Caleidoscopului (evident ca în Flash va fi animată) Dezavantajul pe care îl are acest mod de construire a unui caliedoscop este aceala că după un timp (egal cu numărul cadrelor în care a fost construit – 80 împărţit la viteza filmului) animaţia se va repeta. Vom încerca într-un capitol viitor să realizăm un caleidoscop care să nu se repete (în care forma care se modifică în timp este generată aleator).

Întrebare: puteaţi construi caleidoscopul fără a folosi ActionScript deloc ? (încercaţi să răspundeţi singuri înainte de a citi răspunsul).

Răspuns: Caleidoscopul se putea construi şi în întregime manual, aducând pe rând treizeci şi şase de instanţe ale MovieClip-ului din librărie şi rotite cu ajutorul ferestrei Transform (CTRL+T sau din meniuri: Window->

Design Panels -> Transform). Încercaţi singuri să rezolvaţi acest exerciţiu (veţi înţelege – sper – de ce este atât de important ActionScript-ul şi de câtă muncă inutilă vă scuteşte).

1.2 Text în jurul unei sfere

Dificultate: 2

Iarăşi un exemplu care nu demonstrează decât puterea grafică a Flash- ului fără a avea un scop anume (sau poate doar în cazul construirii siglei unei firme deşi puţin probabil). Textul ce se va roti în jurul sferei nu va putea fi modificat în ActionScript, el se va comporta ca o componentă grafică.

Pentru a se roti în jurul unui obiect (ca exemplu va fi folosită o sferă) trebuie ca în prealabil textul să fie aşezat în formă de cerc. Textul pe care îl voi folosi ca exemplu este „BINE ATI VENIT IN LUMEA FLASH-ULUI!”.

Pentru început va trebui să aşezaţi textul ales de dumneavoastră sub forma unui cerc – acest lucru se poate realiza folosind Adobe Photoshop (introduceţi

(8)

jumate de cerc şi identic pentru celaltă jumătate). În final ar trebui să obţineţi o imagine asemănătoare cu aceasta:

Figura 1-4 – Textul scris pe circumferinţa unui cerc

După ce aţi reuşit să realizaţi cercul din text, importaţi imaginea rezultată (JPG) în Flash (CTRL+R sau din Meniu: File->Import->Import to stage). După ce aţi importat imaginea, ea va rămâne în scenă. Selectaţi-o şi din meniuri alegeţi Modify->Bitmap->Trace bitmap pentru a o „vectoriza”

(aici puteţi să schimbaţi opţiunile de convertire a imaginii în vectori după care apăsaţi „OK”). Selectaţi porţiunile albe şi apăsaţi de fiecare dată tasta Delete pentru a rămâne doar cu porţiunea de text. Selectaţi textul convertiţi- l în MovieClip cu punctul de înregistrare în centrul obiectului (apăsaţi click dreapta dupa selecţie şi din meniul apărut alegeţi opţiunea convert to MovieClip – nu uitaţi de punctul de înregistrare). Repetaţi acţiunea (selectare – convertire în MovieClip) şi veţi avea două filme imbricate.

Efectuaţi un click dublu pentru a edita primul MovieClip (cel care mai conţine încă unul în interior). Inseraţi un cadru-cheie în poziţia 60 (vezi exerciţiu precedent) şi în primul cadru, din fereastra de proprietaţi selectaţi opţiunea Tween -> Motion. În aceeaşi fereastra cu proprietăţi setaţi valoarea Rotation la CCW3 şi puneţi valoarea 1 în câmpul ce indică numărul de rotaţii (times) – această operaţi va avea ca efect realizarea unei animaţii de rotire a textului pe parcursul a 60 de cadre; rotirea va fi realizată în sens invers acelor de ceasornic.

Dacă testaţi filmul ar trebui să vedeţi un cerc ce se roteşte. Reveniţi în scena principală şi cu ajutorul instrumentului Free Transform (tasta „Q” sau

3 Counter Clockwise = împotriva acelor de ceasornic

(9)

din bara de instrumente) modelaţi obiectul ca şi cum scrisul ar orbita în jurul unui obiect. Ceea ce mai rămâne de făcut este să construim obiectul central. Adăugaţi un strat nou (Insert->Timeline->Layer) şi desenaţi o sferă ca în imaginea următoare:

Figura 1-5 – Adăugaţi o sferă (cerc) în noul layer chiar dacă acesta se va poziţiona peste întreg textul după care tăiaţi sfera în două semisfere

Jumatea superioară de sferă ar trebui să fie situată deasupra textului iar cea inferioară sub textul ce se roteşte. Pentru a muta jumătatea inferioară sub text, trasaţi o linie oblică care să despartă cele două jumătăţi ca în Figura 1-5. Selectaţi partea inferioară şi din meniul edit alegeţi opţiunea Cut. Adăugaţi un strat nou şi poziţionaţi-l sub straturile existente (printr-o operaţie drag-and-drop) după care având acest nou strat selectat din meniul Edit alegeţi opţiunea Paste in place. Stergeţi linia rămasă după care testaţi filmul realizat. Vă puteţi juca cu gradienţii (imediat dupa desenarea sferei) pentru a desena obiectul central exact ca o sferă:

Figura 1-6 – Sferă pe care a fost aplicat şi un gradient circular

Exerciţiu: Încercaţi să realizaţi acelaşi efect, de această dată fără a „tăia”

sfera, ci prin copierea în întregime a ei şi ascunderea unor porţiuni prin intermediul măştilor. Această nouă metodă este folositoare atunci când intenţionaţi ca în centru să aveţi un MovieClip care la rândul său este animat.

(10)

1.3 Acumularea pixelilor

Dificultate: 2

Atunci cand realizaţi un album fotografic veţi dori de cele mai multe ori ca imaginea să nu fie afişate în scenă într-un mod banal (imaginea să apară brusc), probabil că aţi prefera ca asupra noilor imagini să fie aplicate diverse efecte. Vom sări peste efectele banale aplicate asupra imaginilor (cum ar fi slide – deplasarea noii imagini peste vechea imagine se realizează prin modificarea poziţionarea imaginii noi în exteriorul scenei şi apoi modificarea coordonatelor sale până la suprapunerea peste vechea poza, zoom-in (zoom-out) – mărirea sau micşorarea pozei se realizează prin alterarea parametilor _xscale, _yscale a MovieClip-ului în care a fost încărcată noua poza, fadein/fadeout – efect realizat prin modificarea parametrului _alpha ce indică transparenţa unui MovieClip) şi vom încerca câteva efecte mai complexe.

Imaginea asupra căreia doriţi să aplicaţi efectul este de tip scalar - adică este realizată din puncte – de obicei un JPG, BMP, GIF (acelaşi efect poate fi aplicat şi unei imagini de tip vectorial fără probleme). Efectul pe care îl veţi realiza va presupune alungirea imaginii, folosirea unor măşti pentru a descoperi treptat imaginea cea nouă.

Pentru realizarea efectului folosiţi o imagine de tip JPG pe care redimensionaţi-o astfel încât să încapă în scenă sau în locul în care doriţi să o afişaţi (dimensiunile folosite în acest exemplu vor fi 320-lungimea, 240- înălţimea). După ce aţi importat imaginea în scenă (operaţie pe care aţi realizat-o şi în cazul rotirii textului în jurul sferei) converţiţi-o în MovieClip.

(de această dată setaţi punctul de înregistrare în colţul stânga-sus al noului obiect). Înafara MovieClip-ului obţinut mai aveţi nevoie de încă o copie.

Selectaţi MovieClip-ul, şi apăsaţi combinaţia de taste CTRL+C (sau Edit-

>Copy). Selectaţi imaginea şi în fereastra de proprietăţi modificaţi valoarea W (Width - lăţime) la 2000 (în cazul în care se modifică şi înălţimea imaginii pentru a păstra raportul, apăsaţi lacătul care uneşte lăţimea şi înălţimea).

Creaţi un layer nou deasupra celui existent şi apăsaţi combinaţia de taste CTRL+Shift+V (sau Edit->Paste in place).

În timp ce vom realizarea MovieClip-ului alungit de la stanga spre dreapta, vom anima şi o mască care are rolul de a afişa doar o anumită porţiune a imaginii ce păstrează raportul original (cea de dimensiuni 320x240).

(11)

Adăugaţi un nou layer deasupra celor existente şi în acesta animaţi un dreptunghi (convertit în MovieClip) de dimensiunile imaginii originale (320x240) astfel încât acesta să fie la început lipit în stânga imaginii iar în ultimul cadru (să zicem cadru 100) suprapus peste aceasta. Selectaţi acest layer şi din meniul obţinut prin apăsarea butonului drept al mose-ului selectaţi opţiunea „Mask”.

În cel de-al doilea layer apăsaţi tasta F5 având selectat ultimul cadru al animaţiei de pe stratul superior (în exemplu nostru era 100).

În cel de-al treilea strat ar trebui să aveţi imaginea alungită. Imaginea alungită ar trebui să aibă partea din stânga aliniată cu cea a imaginii iniţiale. Animaţi imaginea alungită astfel încât în cadrul 100 să aibă marginea din dreapta alipită marginii imaginii originale (cu alte cuvinte ar trebui ca poziţia finală a imaginii alungite să fie cu 2000-320=1680 puncte mai în stânga imaginii iniţiale). După realizarea acestei animaţii sunteţi foarte aproape de rezultatul final. Inseraţi un ultim strat deasupra stratului al treilea şi desenaţi în poziţia imaginii originale un dreptunghi de aceleaşi dimensiuni (320x240). Mascaţi stratul ce conţine imaginea alungită (click dreapta şi selectaţi opţiunea mask). De asemenea şi acest strat trebuie să se

„întindă” până la cadrul 100 şi din acest motiv va trebui să apăsaţi tasta F5 când aveţi ultimul cadru selectat.

Figura 1-7 – Imaginea originală şi în timpul realizării efectului Testaţi filmul rezultat.

Exerciţiu: pentru a fi siguri că aţi stăpânit tehnica descrisă mai sus încercaţi realizarea efectului în care imaginea să intre din partea stângă, de sus sau de jos.

(12)

1.4 Efect de lupă

Dificultate: 2

În ce constă acest efect: avem o imagine afişată şi prin intermediul unui instrument vom mări regiuni din poză. Atunci când mărim o imagine de tip raster (adică formată din pixeli) nu vom face altceva decât să mărim dimensiunea pixelului şi deşi imaginea este mărită, calitatea acesteia va rămâne aceeaşi – de exemplu dacă într-o porţiune de imagine avem un scris ce nu poate fi înţeles, mărind imaginea nu facem decât să mărim pixelii, scrisul respectiv va rămâne tot indescifrabil – nu putem extrage informaţii suplimentare dintr-o resursă ce conţine puţine informaţii.

Totuşi putem falsifica această poveste având ca singură poză o poză detaliată care să fie micşorată în timpul rulării. Poza va apărea mică dar când vom duce instrumentul de mărire peste poza (mică) vor fi afişate detalii din poza originală (cea dinaintea mişorării).

Pentru început importaţi în scenă o imagine bogată în detalii cu dimensiuni destul de mari (eu am ales o imagine de 1024x768 pixeli).

Convertiţi imaginea în MovieClip cu punctul de înregistrare în stânga sus şi daţi ca identificator şirul de caractere „imagine”.

În continuare vom construi lupa. Cu ajutorul instrumentul Oval, ţinând tasta Shift apăsată desenaţi un cerc care să aibă ca interior un gradient circular. Puteţi repoziţiona gradientul prin intermediul instrumentului GradientTransform sau cu PaintBucket pentru a avea un rezultat asemănător cu cel din imaginea următoare:

Figura 1-8 – Repoziţionând centrul gradientului veţi obţine o “lupă”

Convertiţi rezultatul în MovieClip cu punctul de înregistrare în centru.

Setaţi un factor de opacitate (alpha din fereastra de proprietăţi) de 20%

pentru obiectul rezultat şi setaţi-i numele de instanţă „lupa” (din fereastra de proprietăţi - stânga) .

(13)

Ţinând apăsată tasta CTRL repoziţionaţi lupa pentru a realiza o copie.

Copiei îi veţi seta numele de instanţă „masca”.

Cum funcţionează lupa: atunci când cursorul mouse-ului este dus deasupra imaginii (cea micşorată) la poziţia lupei (în interiorul său) va fi afişată imaginea originală (pentru a afişa numai o porţiune din imaginea originală ne vom folosi de o mască – copia lupei).

Să trecem la partea interesantă: script-ul ce ne ajută în construirea lupei:

Pentru început vom iniţializa câteva variabile:

factor_marire=4;

mic_x=20;

mic_y=100;

După care vom trece la adăugarea în scenă a MovieClip-ului ce conţine imaginea iniţială şi micşorarea sa (pentru a da impresia ca imaginea este mai mică):

_root.createEmptyMovieClip("imagine_mica",

_root.getNextHighestDepth());

_root.imagine_mica.attachMovie("imagine", "mica", 0);

Vom repoziţiona imaginea mică unde ne convine cel mai mult (poziţie dată de variabilele mic_x, mic_y):

_root.imagine_mica._x=mic_x;

_root.imagine_mica._y=mic_y;

După care vom micşora imaginea pentru a arăta cu adevărat mai mică:

_root.imagine_mica._width =

_root.imagine_mica._width/factor_marire;

_root.imagine_mica._height =

_root.imagine_mica._height/factor_marire;

Pentru a putea arăta în scenă (sub lupă mai exact) şi imaginea mare, trebuie să aducem în scenă şi originalul:

_root.createEmptyMovieClip("imagine_mare",

_root.getNextHighestDepth());

_root.imagine_mare.attachMovie("imagine", "mare", 0);

Să setăm poziţia „lupei” deasupra celorlalte obiecte din film (pentru a fi afişată deasupra tuturor imaginilor):

(14)

_root.lupa.swapDepths(1000);

După care ar trebui să mascăm imaginea mare folosind drept mască duplicatul lupei (care poartă numele de instanţă „mască”):

_root.imagine_mare.setMask(_root.masca);

Vom ascunde cursorul mouse-ului pentru a nu influenţa vizualizarea corectă a imaginii mărite:

Mouse.hide();

Şi în final, de fiecare dată când vom mişca mouse-ul vom repoziţiona lupa şi masca la poziţia cursorului mouse-ului (care acum este invizibil) respectiv vom repoziţiona imaginea mare (ar trebui să deplasăm imaginea mare pentru că dacă pe imaginea mică lupa de deplasează 320 de puncte, trebuie să fie afişate mai multe puncte din imaginea mare – respectiv 320xfactor_marire):

_root.onMouseMove = function() { _root.masca._x = _xmouse;

_root.masca._y = _ymouse;

_root.lupa._x = _xmouse;

_root.lupa._y = _ymouse;

_root.imagine_mare._x = -_xmouse*(factor_marire- 1)+_root.imagine_mica._x*(factor_marire);

_root.imagine_mare._y = -_ymouse*(factor_marire- 1)+_root.imagine_mica._y*(factor_marire);

updateAfterEvent();

};

Rolul funcţiei updateAfterEvent va fi explicat ulterior când vom schimba cursorul mouse-ului într-un film Flash.

Figura 1-9 – Folosirea lupei pentru observarea unui detaliu

(15)

Temă: înţelegeţi din ce motiv este aşezată imaginea mare în acea poziţie şi nu alta; de ce trebuie să scădem o unitate din factorul de mărire la repoziţionarea imaginii mari?

1.5 Schimbarea cursorului mouse-ului

Dificultate: 1

Ne propunem ca în acest exerciţiu să schimbăm cursorul mouse-ului cu unul realizat de noi. Pentru aceasta ar trebui iniţial să desenăm noul cursor.

Realizaţi această operaţie după care convertiţi desenul în MovieClip şi setaţi punctul de înregistrare în aşa fel încât să coincidă cu vârful noului cursor (de exemplu dacă săgeata mouse-ului va fi una îndreptată din dreapta-sus în stânga-jos atunci punctul de înregistrare va fi cel din stânga- jos4):

Figura 1-10 Setaţi punctual de înregistrare a noului cursor astfel încât să coincidă cu vârful intuituiv al cursorului (aici stânga-jos)

Apăsaţi butonul „Advanced” şi după ce aţi bifat opţiunea de exportare pentru ActionScript, setaţi identificatorul noului cursor drept „sageata”.

4 Personal pentru realizarea săgeţii am folosit fontul Windings3 după care am apăsat tasta ‘

(16)

Odată săgeata construită ea va fi memorată în bibliotecă de unde o vom prelua folosind ActionScript. Săgeata rămasă în scenă ne prisoseşte de aceea putem să o ştergem.

Toate acţiunile pe care le vom face pentru a schimba cursorul trebuie să fie realizate odată cu încărcarea în memorie a documentului. De aceea este cel mai bine ca operaţiile de schimbare a cursorului să fie realizate în cadrul funcţiei „onLoad” ataşată obiectului _root, funcţie ce va fi lansată îm momentul în care documentul (_root) este încărcat în întregime în memorie. Funcţia va arăta astfel:

_root.onLoad=function () { Mouse.hide();

_root.attachMovie("sageata","cursor",65000);

_root.cursor.startDrag(true);

};

Codul (destul de intuitiv, de altfel) are rolul de a ascunde cursorul predefinit am mouse-ului (comanda Mouse.hide();) după care este adus din librărie obiectul creat anterior care va fi referit cu numele „cursor” şi va fi poziţionat pe unul din straturile cele mai înalte (pentru a nu intra pe

„sub” obiectele deja existente în scenă) şi în final indicăm Flash-ului să

„tragă” în locul cursorului iniţial (care acum este ascuns) noul cursor (_root.cursor.startDrag(true);); parametrul „true” ajută pentru poziţionarea punctului de control (deci al vârfului săgeţii) exact în vârful săgeţii ascunse.

Dacă testaţi filmul ar părea că acesta funcţionează foarte bine dacă aveţi un număr mare de cadre pe secundă. În cazul în care numărul acestora este unul redus, cursorul va sacada în obiectul Flash şi nu va crea o impresie plăcută.

Pentru a rezolva această problemă trebuie ca noua săgeată să fie redesenată de fiecare dată când poziţia mouse-ului este schimbată.

Evenimentul schimbării poziţiei mouse-ului îl vom capta prin intermediul funcţiei onMouseMove şi tot ceea ce va trebui să realizăm este să reactualizăm documentul. Ataşaţi aşadar scriptului precedent următoarea funcţie:

_root.onMouseMove = function() { updateAfterEvent();

};

Cu aceasta schimbarea cursorului mouse-ului a fost realizată. Problema pe care v-o las dumneavoastră spre rezolvare este de a schimba cursorul cu

(17)

unul animat (trebuie ca MovieClip-ul „sageata” să îşi schimbe forma) după care să adăugaţi două butoane prin intermediul cărora să schimbaţi cursorul în cel iniţial respectiv în cel creat de dumneavoastră.

Observaţie: atunci când folosiţi mouse-ul sau tastatura, încercaţi să utilizaţi evenimentele asociate acestora pentru ca flash-ul să nu depindă de viteza derulării cadrelor.

1.6 Decodificarea textului

Dificultate: 4;

Un efect pe care l-am întâlnit în câteva locuri şi mi s-a părut interesant mai mult pentru ceea ce aţi putea învăţa din el – respectiv manipularea şirurilor de caractere.

Efectul constă în următoarele: vom crea într-un MovieClip un obiect de tip text care va afişa la un moment dat un mesaj. Iniţial mesajul va apare codificat şi decodificarea va începe odată cu apăsarea mesajului. Ca text va fi introdus mesajul decodificat şi codificarea va fi realizată în obiectul Flash.

Codificarea are la bază extragerea codului ascii al fiecărui caracter, incrementarea sa cu 10 şi transformarea din nou în şi de caractere a rezultatului.

Decodificarea textului va trebui să fie realizată în mai mulţi paşi, la fiecare pas decodificându-se câte o literă sau cate o porţiune din literă.

Decodificarea unei litere va înceta atunci când se ajunge la litera corectă. La un pas al decodificării, fiecare literă va fi mai aproape cu un pas de valoarea reală.

Deocamdată să creăm MovieClip-ul şi să-i adăugăm textul ce ar trebui decodat:

_root.createEmptyMovieClip("mc", 0);

_root.mc.createTextField("mesaj", 0, 0, 0, 300, 30);

var tf = new TextFormat("Tahoma", 11, 0x000000, true);

_root.mc.mesaj.selectable = false;

_root.mc.mesaj.setNewTextFormat(tf);

(18)

Obiectul „tf” are rolul de a configura felul în care trebuie să apară textul.

Mesajul nu va putea fi selectat ci doar „clickat”. Valoarea decodificată este cel dat de _root.mc.txtdecod şi poate fi modificată din cod.

Vom construi în continuare o funcţie care arată şirul de caractere la un anumit pas al decodificării:

_root.mc.arata_mesaj = function(k:Number) {

// parametrul k dă pasul decodificării.

//construim un şir cu codurile ascii ale textului:

var coduri_ascii:Array = new Array(this.txtdecod.length);

for (i=0; i<coduri_ascii.length; i++) {

// charCodeAt va furniza codul ascii caraterului de pe // o anumita poziţie din string:

coduri_ascii[i] = this.txtdecod.charCodeAt(i);

}

//şi un şir cu codurile modificate

var coduri_ascii_modificate:Array = new

Array(this.txtdecod.length);

for (i=0; i<coduri_ascii.length; i++) {

coduri_ascii_modificate[i] = coduri_ascii[i]+10;

}

//acesta este mesajul ce va fi afişat ce va fi costruit:

var msg = "";

for (i=0; i<coduri_ascii.length; i++) {

//caracterul este deja decodificat ?

if (coduri_ascii_modificate[i]-k+i>coduri_ascii[i]) {

//nu: îl aducem mai aproape de valoarea reală msg += String.fromCharCode

(coduri_ascii_modificate[i]+k-i);

} else {

//da: atunci afişam caracterul

msg += String.fromCharCode(coduri_ascii[i]);

} }

// mai rămâne să afişăm textul:

this.mesaj.text = msg;

};

(19)

În funcţie de parametrul de intrare „k”, textul va fi decodificat altfel:

prima literă va fi mai aproape cu un număr de 10-k paşi de valoarea reală, a doua mai aproape cu 11-k, a treia cu 12-k etc. Dacă una din litere are deja valoarea reală, ea va rămâne fixată la acea poziţie.

Incrementarea lui k şi afişarea noii stări trebuie să fie făcută în mod continuu, de fiecare dată când filmul va intra într-un nou cadru. Din acest motiv aceste funcţii vor fi scrise în cadrul evenimentuli onEnterFrame asociat MovieClip-ului:

_root.mc.onEnterFrame = function() {

if (decodifica) {

stadiu++;

this.arata_mesaj(stadiu);

} };

Funcţia onEnterFrame este acum parte din MovieClip-ul „mc”. Din acest motiv, pentru a ne referi la o altă funcţie componentă („arată_mesaj”) ne vom folosi de apelativul „this” în loc de _root.mc. Variabila „stadiu” care indică în ce pas al decriptării suntem ar trebui iniţializată odată cu pornirea filmului. La fel variabila booleană „decodifică” trebuie să aibă iniţial valoarea fals şi să devină adevărată atunci când MovieClip-ul este apăsat:

_root.onLoad = function() {

decodifica = false;

stadiu = 10;

_root.mc.arata_mesaj(9);

};

Am stabilit valorile iniţiale, Trebuie doar să pornim animaţia atunci când se va executa click pe text:

_root.mc.onPress = function() {

decodifica = true;

};

Exerciţiu: O problemă interesantă este codificarea unui şir de caractere folosind o parolă: se vor extrage codurile ascii ale parolei şi vor fi adăugate codurilor literelor din textul iniţial. Să presupunem că parola are 10

(20)

caracterelor de pe poziţiile 1,11,21,31.... codul ascii al celei de-a doua litere din parolă va fi adăugat codurilor ascii ale caracterelor de pe poziţiile 2,12,22.... În final veţi obţine un text nou care poate fi decriptat scăzând din codul fiecărui caracter pe cel al caracterelor din parolă. Deşi nu oferă prea multă securitate, încercaţi să realizaţi scriptul propus pentru a învăţa mai bine lucrul cu şiruri de caractere.

(21)

Capitolul 2

2 Jocuri în Flash… nimic mai simplu

Continuam în capitolul al doilea cu realizarea unui joc de puzzle în Flash8. Deşi nu este optimizat pentru a putea „jongla”

cu imagini mari sau cu multe piese ale puzzleului, cred ca prin intermediul acestui exemplu voi raspunde multor persoane care doresc să ştie „cum se face un joc”

2.1 Curbă Bezier cu două puncte de control

Dificultate: 3

Acest exerciţiu va fi unul ce ne va ajuta mai mult la definirea unor concepte ce vor fi folosite ulterior într-un joc de tip puzzle. Curbele Bezier sunt construite pe baza a două puncte de start şi final şi având un anumit număr de puncte de control. Curba Bezier va pleca din primul punct, se va îndrepta spre primul punct de control, spre al doilea şi tot aşa după care va ajunge în punctul final. Două astfel de curbe sunt mai populare: cele cu un singur punct de control şi cele cu două puncte de control (dacă desenaţi în Flash o linie după care o curbaţi cu ajutorul instrumentului „Selection Tool” şi apoi o selectaţi cu „Subselection Tool” punctele din capetele curbei vor fi evidenţiate prin prezenţa unor pătrăţele; selectarea pătrăţelelor va duce la apariţia punctelor de control).

Figura 2-1 – Curba Bezier cu un punct de control şi cu două puncte de control Găsirea locului geometric a punctelor de pe o curbă Bezier este unul destul de simplu atunci când avem la îndemână un calculator. Pentru a găsi punctul din mijlocul curbei trasăm segmentele de dreaptă dintre punctul de start şi primul punct de control după care stabilim mijlocul acesteia.

(22)

dintre al doilea punct de control şi punctul final. Aşadar acum vom avea trei puncte. Trasăm cele două segmente şi stabilim mijloacele lor obţinând de această dată un singur segment aflat între cele două mijloace. Punctul din mijlocului acestui ultim segment coincide cu punctul din mijlocul curbei. Pentru a găsi un punct aflat la un sfert de la începutul curbei procedaţi asemănător selectând de fiecare dată punctul aflat in primul sfert al dreptei (atenţie trebuie să consideraţi o orientare – să nu confundaţi primul sfert al dreptei2 cu ultimul sfert – primul sfert se afla mai aproape de primul punct de start pe prima dreapta, mai aproape de primul punct de control pe dreapta dintre cele doua puncte de control şi mai aproape de punctul al doilea de control pe ultima dreapta).

Primul tip de curbă cel cu un singur punct de control este implementat în Flash prin intermediul funcţiei de desenare curveTo specifică modulului de desenare din cadrul MovieClip-urilor. În continuare vom construi un exemplu ce va desena curba Bezier cubică (adică cea care foloseşte două puncte de control). Pentru aceasta construiţi patru MovieClip-uri care să aibă numele de instanţă: s1,s2 (pentru punctele de start respectiv de sfârşit) şi c1,c2 pentru cele două puncte de control (preferabil să fie cercuri cu punctul de înregistrare în centru). Selectaţi pe rând fiecare dintre aceste MovieClip-uri şi ataşaţi-le scriptul următor (identic pentru fiecare):

on (press) {

Mouse.hide();

this.onMouseMove = function() {

this._x = this._parent._xmouse;

this._y = this._parent._ymouse;

_root.redraw();

updateAfterEvent();

};

}

on (release) {

this.onMouseMove = null;

Mouse.show();

}

Atunci când se va apăsa butonul mouse-ului deasupra unuia dintre MovieClip-uri, se va ascunde cursorul predefinit al mouseului şi se va construi funcţia „onMouseMove” care poziţionează MovieClip-ul la poziţia mouse-ului. Funcţia _root.redraw va avea rolul de a redesena curba şi trebuie să apelăm funcţia de updatare a scenei pentru a o redesena. În momentul în care este eliberat cursorul mouse-ului vom şterge din

(23)

memoria calculatorului funcţia ce tratează evenimentul mişcării mouse- ului şi vom afişa cursorul.

Trebuie să stabilim în câţi paşi vom realiza curba (nu sunt de ajuns doar mijloacele si sferturile curbei – ar trebui mai multe puncte). Numărul de puncte intermediare va fi stabilit de către variabila „maxpasi”. Vom da în continuare scriptul (ce trebuie să fie adăugat scenei principale – în primul cadru) după care vom explica cum funcţionează:

maxpasi = 100; // numărul maxim de paşi

function redraw() { // funcţie de redenare a curbei _root.clear(); // ştergem vechea curbă

// vom seta stilul liniei dintre punctele de start // şi punctele de legătură:

_root.lineStyle(1, 0xff0000, 40);

_root.moveTo(s1._x, s1._y);

_root.lineTo(c1._x, c1._y);

_root.moveTo(s2._x, s2._y);

_root.lineTo(c2._x, c2._y);

//setarea liniei pentru desenarea curbei:

_root.lineStyle(1, 0x000000, 100);

// ne poziţionăm în punctul de start _root.moveTo(s1._x, s1._y);

// vom lua maxpasi puncte pe fiecare dreapta:

for (pas=1; pas<_root.maxpasi; pas++) { //stabilim raport pentru poziţia în

//pasul curent de ex raport=1/2 pt mijlocul curbei:

raport = pas/maxpasi;

//puncte din cadrul primei linii - între punctul //iniţial şi primul punct de control (s1-c1)):

s1c1x = s1._x+(c1._x-s1._x)*raport;

s1c1y = s1._y+(c1._y-s1._y)*raport;

//puncte din linia dintre punctele de control:

c2s2x = c2._x+(s2._x-c2._x)*raport;

c2s2y = c2._y+(s2._y-c2._y)*raport;

//puncte din cadrul ultimei linii

c1c2x = c1._x+(c2._x-c1._x)*raport;

c1c2y = c1._y+(c2._y-c1._y)*raport;

(24)

s1c1c2y=s1c1y+(c1c2y-s1c1y)*raport;

//puncte intermediare pe dreapta a doua c1c2s2x=c1c2x+(c2s2x-c1c2x)*raport;

c1c2s2y=c1c2y+(c2s2y-c1c2y)*raport;

//in final găsim punctul ce aparţine curbei:

finalx=s1c1c2x+(c1c2s2x-s1c1c2x)*raport;

finaly=s1c1c2y+(c1c2s2y-s1c1c2y)*raport;

//_root.moveTo(s1._x, s1._y);

_root.lineTo(finalx, finaly);

} }

// vom face o desenare iniţială prin apelul funcţieide mai // sus:

redraw();

Funcţia redraw în primul rând şterge ecranul (pentru a putea desena o nouă curbă), acest lucru întâmplându-se de fiecare dată când mutăm unul din cele 4 MovieClip-uri aflate (s1,s2,c1,c2). În continuare dorim să trasăm cele două tangente la curba în punctele s1 şi s2 fapt realizat prin comenzile moveTo, lineTo. Pentru desenarea curbei stabilim alt tip de linie şi vom stabili punctul de plecare în desenul liniei (s1). Prin intermediul unei instrucţiuni de ciclare (for) vom calcula cele maxpasi puncte ale curbei şi vom trasa linii între aceste puncte calculate. Observaţi cum de fiecare dată înmulţim cu raportul pentru a stabili la ce distanţă de primul punct al segmentului se află punctul curent calculat.

În final trebuie să desenăm curba (pentru ca ea să apară şi înainte de a muta vreunul din MovieClip-uri) fapt realizat prin apelul direct al funcţiei redraw.

Aşa cum v-aţi obişnuit deja, în finalul fiecărui exemplu veţi găsi un exerciţiu. Exerciţiul pentru acest capitol constă în construirea unei funcţii asemănătoare pentru desenarea curbei Bezier cu un singur punct de control (aşa cum am spus aceasta este implementată şi în flash – curveTo; totuşi este o provocare să o realizaţi dumneavoastră). Funcţia va avea ca parametri de intrare punctul de control şi cel final şi va desena o curbă între ultimul punct desenat şi cel dat ca parametru. Alt exerciţiu l-ar putea constitui desenarea unui obiect ce se deplasează pe o curbă Bezier (ce trece prin fiecare punct de control).

(25)

2.2 Adăugarea unei funcţii clasei MovieClip

Dificultate: 1

Aşa cum probabil vă imaginaţi vom adăuga funcţia de desenare a unei curbe Bezier clasei MovieClip. Pentru a putea importa funcţiile construite de noi în mai multe obiecte flash, vom defini aceste funcţii într-un fişier extern. Pentru a construi fişierul extern folosiţi-va de Flash: selectaţi opţiunea „new” din meniul „File” şi apoi selectaţi ActionScript file. În acest fel veţi beneficia de modulul ce verifică corectitudinea scriptului (apăsaţi butonul albastru din partea de sus în forma simbolului „check”).

Pentru a putea introduce o funcţie nouă ne vom folosi de proprietatea

„prototype”. Vom denumi fişierul „grafix.as” şi deocamdată va conţine doar o funcţie (bezier):

MovieClip.prototype.bezier = function(s_x, s_y, c1_x, c1_y, c2_x, c2_y, f_x, f_y, pasi) {

var maxpasi = pasi;

this.moveTo(s_x, s_y);

for (pas=1; pas<maxpasi; pas++) { raport = pas/maxpasi;

s1c1x = s_x+(c1_x-s_x)*raport;

s1c1y = s_y+(c1_y-s_y)*raport;

c2s2x = c2_x+(f_x-c2_x)*raport;

c2s2y = c2_y+(f_y-c2_y)*raport;

c1c2x = c1_x+(c2_x-c1_x)*raport;

c1c2y = c1_y+(c2_y-c1_y)*raport;

s1c1c2x = s1c1x+(c1c2x-s1c1x)*raport;

s1c1c2y = s1c1y+(c1c2y-s1c1y)*raport;

c1c2s2x = c1c2x+(c2s2x-c1c2x)*raport;

c1c2s2y = c1c2y+(c2s2y-c1c2y)*raport;

finalx = s1c1c2x+(c1c2s2x-s1c1c2x)*raport;

finaly = s1c1c2y+(c1c2s2y-s1c1c2y)*raport;

this.lineTo(finalx, finaly);

}

this.lineTo(f_x,f_y);

};

Modul de desenare a curbei a fost deja explicat, parametrii de intrare sunt startx, starty, pozitiile celor două controale (pe axa x respectiv y), poziţia punctului final şi numărul de paşi folosiţi (cu cât sunt mai mulţi

(26)

Pentru a folosi noua funcţie va trebui să includem fişierul extern după care putem să desenăm curbe Bezier apelând funcţia „bezier” pentru orice MovieClip. De exemplu într-un nou document Flash puteţi scrie codul următor:

#include "grafix.as"

_root.lineStyle(11, 100, 100);

_root.bezier(10, 250, 30, 100, 350, 500, 300, 250, 100);

Atenţie! Directiva include este prefixată de caracterul diez după care urmează un string conţinând calea corectă către fişierul ce trebuie inclus (în exemplul dat fişierul grafix.as se află în acelaşi director cu fişierul fla). În plus trebuie menţionat că după include nu se pune caracterul punct şi virgulă (;). Ceea ce face include este de a copia conţinutul fişierului specificat în ActionScript-ul pe care îl scrieţi.

2.3 Construirea unui puzzle

Dificultate: 7; necesita adăugarea funcţiei precedente clasei MovieClip şi folosirea Flash8.

Am adăugat o funcţie nouă obiectelor de tip MovieClip. De fiecare dată când vom folosi directiva include şi cu parametru numele fişierului în care se găseşte scriptul suplimentar. Ceea ce vom dori să realizăm în continuare este un joc de puzzle. Curba bezier aşa cum a fost dată mai sus va fi utilizată pentru a defini marginile pieselor. Să evidenţiem câteva din problemele cu care ne vom confrunta în încercarea noastră de a realiza un puzzle:

- în primul rând piesele trebuie să fie independente una de cealaltă şi din acest motiv trebuie ca fiecare piesă să fie construită ca un MovieClip separat care să poată fi mutat prin intermediul mouse- ului;

- fiecare dintre piese (deci MovieClip-uri) trebuie să aibă marginile compatibile cu marginile pieselor alăturate. Aceasta se rezolvă copiind marginea şi în piesele alăturate; stânga , dreapta sus, jos. De fapt se poate observa că odată găsită marginea din stânga a piesei din dreapta nu mai avem nevoie să găsim marginea din dreapta a piesei din stânga, aceasta fiind identică. La fel procedăm şi pentru

(27)

marginile sus-jos (marginea superioară a unei piese va fi copiată ca margine inferioară piesei aflate deasupra sa):

Figura 2-2 – Piesa stângă trebuie să aibă în partea dreapta aceeaşi curbură cu piesa din dreapta (în parta stângă)

- piesele trebuie să aibă ca fundal o imagine şi nu doar o porţiune neagră (Figura 2-3);

- atunci când „ridicăm” o piesă ea să fie deasupra celorlalte (ar trebui să ne folosim de umbre şi deoarece piesele vor fi create dinamic – în momentul rulării filmului, şi umbrele trebuie să fie create tot dinamic; pentru aceasta ne vom folosi de facilităţile ultimei versiuni de Flash care permite adăugarea de umbre obiectelor MovieClip. În cazul în care nu aveţi Flash 8, puteţi simula umbra printr-o copiere a piesei, înnegrire – pentru a da impresia de umbră, setarea parametrului alpha – umbra trebuie să fie oarecum transparentă şi în final poziţionarea umbrei sub piesa ce va fi mutată);

- poziţionarea unei piese în locaţia corectă trebuie să nu mai permită utilizatorului să o mai ridice şi totodată această poziţionare ar trebui să permită un grad de inexactitate: utilizatorul ar putea aşeza piesa în apropierea locului în care trebuie să se afle şi aceasta să se alipească corect (nu trebuie să forţam jucătorul să poziţioneze piesa în poziţia exactă ci într-o vecinătate a poziţiei corecte)

(28)

Figura 2-3 – Piesa trebuie să fie o porţiune dintr-o imagine

- piesele poziţionate corect să fie contorizate şi în momentul în care toate au fost afişate corect să fie afişat un mesaj ce-l felicită pe jucător;

- să avem o funcţie de amestecare a pieselor care să nu permită pieselor să iasă din scenă.

Deoarece îl vom face cat mai simplist, acest joc nu va conţine un modul de încărcare a imaginilor sau de setare a opţiunilor, imaginea va fi încărcată o singură dată la început (în bibliotecă) şi va fi folosită pe parcurs fiind preluată de acolo. Pentru acest exemplu setaţi scena la 640x480 pixeli şi alegeţi o imagine cu o rezoluţie de 320x240 pixeli.

Imaginea va fi importată în scenă (File->Import->Import to Stage) după care va fi convertită în MovieClip căruia îi veţi atribui ca identificator

„img”.

Liniile de cod ale scriptului vor fi comentate (chiar dacă codul se va întinde pe o suprafaţă mai mare va fi mai uşor de înţeles; atunci când copiaţi scriptul nu copiaţi şi comentariile – cele marcate cu // la începutul liniei):

// în primul rând va trebui să importăm funcţia // ce ne permite desenarea curbei bezier:

#include "grafix.as"

// disponibilă numai in Flash 8, clasa filters ne va // permite să adăugăm umbră pieselor noastre:

(29)

import flash.filters.DropShadowFilter;

// construim umbra: parametrii daţi reprezintă în ordine:

// distanţa, unghiul, culoarea, transparenţa, factorul // blur pe X respectiv pe Y, accentuarea, calitatea, // umbra interioara, eliminarea obiectului şi a umbrei de // dedesubtul său, eliminarea obiectului dar nu şi a // umbrei:

var filter:DropShadowFilter = new DropShadowFilter(5, 45, 0, .8, 5, 5, 1, 3, false, false, false);

// vom construi un şi cu aceşti parametri:

var umbra:Array = new Array();

// şi vom defini un tip de umbra pentru o piesă:

umbra.push(filter);

// definim similar umbra pentru piesă atunci cand este // ridicată in vederea repoziţionării:

var filter2:DropShadowFilter = new DropShadowFilter(2, 45, 0, .8, 3, 3, 1, 3, false, false, false);

var umbra2:Array = new Array();

umbra2.push(filter2);

// iniţializăm cu 0 numărul pieselor poziţionate corect:

pozitionate_corect = 0;

// definim o funcţie de construcţie a pieselor:

function construieste_piese() { //dimensiunea pozei:

l_img = 320;

h_img = 240;

// dimensiunea unei piese a puzzle-ului;

// piesele vor fi pătrate şi deci lungimea=lăţimea:

marime = 40;

// numărăm câte piese sunt pe verticala/orizontală:

nr_l = Math.ceil(l_img/marime);

nr_h = Math.ceil(h_img/marime);

// construim un fundal ce va ajuta jucatorul // să aşeze piesele în poziţiile corecte.

// de observat este că nivelul este unul inferior // (-10000) pentru a nu se suprapune nici unei piese:

_root.createEmptyMovieClip("harta", -10000);

_root.harta.attachMovie("img", "fundal", -10001);

// aducem pe fundal imaginea din bibliotecă:

_root.harta.fundal._alpha = 20;

(30)

(1, 1, 20);

_root.harta.lineStyle

// cum poziţiona imaginea ajutătoare în centru:

// următoarel;e linii ajută la corectarea imaginii

);

);

pe verticala

ce va simboliza piesa

iecărei piese noi o funcţie ce

i mare te:

scenă:

_root.harta._x = 160;

_root.harta._y = 120;

// ajutătoare atunci când dimensiunea piesei nu // divide exact înalţimea/lăţimea pozei:

999);

_root.createEmptyMovieClip("corector", -9 _root.corector._x = 160;

_root.corector._y = 120;

_root.corector.lineStyle(1

_root.corector.beginFill(100, 100 _root.corector.moveTo(0, 0);

_root.corector.lineTo(0, h_img);

_root.corector.lineTo(l_img, h_img);

_root.corector.lineTo(l_img, 0);

_root.corector.lineTo(0, 0);

r);

_root.harta.setMask(_root.corecto // să trecem la construcţia pieselor:

// i este variabila contor pt. piesele // j pentru piesele pe orizontală

for (i=0; i<nr_l; i++) { for (j=0; j<nr_h; j++) { // construim un MovieClip

_root.createEmptyMovieClip("piesa_"+i+"_"+j, i*nr_h+j);

// atribuim f

// tratează evenimentul apăsării sale:

on() { _root["piesa_"+i+"_"+j].onPress = functi

// vom „agăţa” piesa de mouse:

this.startDrag(false);

cel ma // o vom pune pe nivelul

// pentru a fi afişat deasupra celorlal this.swapDepths(10000);

a este ridicată:

// umbra va arăta ca pies

this.filters = _root.umbra;

// atunci când mouseul se va mişca this.onMouseMove = function() {

în // vom redesena poziţia piesei

updateAfterEvent();

};

};

(31)

ibuim şi evenimentul eliberării butonului:

// atr

_root["piesa_"+i+"_"+j].onRelease = function() {

orectă (vom vedea ă)atunci:

esa:

_x;

piesă:

nr_l) {

false;

ui, e:

onţien forma piesei:

",

i e:

// ştergem evenimentul mutării mouseului:

this.onMouseMove = null;

// setăm alta umbră

a2;

this.filters = _root.umbr cea c // dacă poziţia este

// ulterior ce înseamnă poziţie corect

if ((Math.abs(this._x-_root.harta._x)<5) &&

(Math.abs(this._y-_root.harta._y)<5)) { //setează stratul cel mai mic:

this.swapDepths(0);

// nu-i mai permite mutarea:

this.onPress = null;

this.onRelease = null;

// elimină umbrele:

this.filters = null;

t pi // poziţionează exac this._x = _root.harta.

this._y = _root.harta._y;

t o // am mai poziţionat corec _root.pozitionate_corect++;

}

iesele:

// dacă am poziţionat corect toate p (_root.pozitionate_corect == nr_h*

if

// afişam un mesaj de felicitare;

// acest mesaj va las pe d-voastră să-l i după // completaţi pentru a fi vizibil ş

// faza de testare…………

trace("ai castigat");

utătoare:

// vom ascunde harta aj

_root.harta._visible = }

// în orice caz, la eliberarea mouse-ul vom înceta să mişcăm piesa după mous //

this.stopDrag();

};

în cadrul fiecărei piese // în continuare vom crea

un MC gol ce va c // câte

_root["piesa_"+i+"_"+j].createEmptyMovieClip("masca 1000+i*nr_h+j);

// setăm, tipul linei cu care vom desena masca:

+j].masca.lineStyle(1);

_root["piesa_"+i+"_"

// şi tipul umplerii (negru, opac):

00);

_root["piesa_"+i+"_"+j].masca.beginFill(0, 1 rei p // vom desena un pătrat în poziţia fiecă es

(32)

_root["piesa_"+i+"_"+j].masca.moveTo(i*marime, j*marime);

arime, _root["piesa_"+i+"_"+j].masca.lineTo(i*marime+m

j*marime);

"_"+j].masca.lineTo(i*marime+mar

_root["piesa_"+i+ ime,

,

buie să realizăm o curbură Figura 2-2:

(i=0; i<nr_l; i++) {

(marime/2))+5;

, 1);

erioare vor fi desenate

e vorba de prima piesă

rime-c2,

mar c2,

er(i*marime,

e:

marime-c2, j*marime+marime);

"_"+j].masca.moveTo(i*marime, _root["piesa_"+i+

j*marime);

masca.lineTo(i*marime, _root["piesa_"+i+"_"+j].

j*marime+marime);

"_"+j].masca.lineTo(i*marime+marime _root["piesa_"+i+

j*marime+marime);

} }

fiecare piesă tre // pentru

ca în //

for

for (j=0; j<nr_h; j++) {

ă curburi (c1,c2 sunt puncte de // stabilim dou

// control):

c1 = random(Math.round if (random(2) == 1) { c1 *= -1;

}

(marime/2))+5;

c2 = random(Math.round ) == 1) { if (random(2

c2 *= -1;

}

asca.lineStyle(1 _root["piesa_"+i+"_"+j].m

rioare/inf // curbele supe

ca nu // doar da

if (j>0) {

// orizontal sus pentru o piesă

*marime, _root["piesa_"+i+"_"+j].masca.bezier(i

*mar me+Math.round(marime/2), j*ma j ime, i*mari

i* ime+Math.round(marime/2), j*marime+

i*marime+marime, j*marime, 30);

// aceeasi orizontală va fi jos pentru piesa // aflată deasupra ei:

_root["piesa_"+i+"_"+(j-1)].masca.bezi

*mar

j ime, i*marime+Math.round(marime/2), j*marime-c2, j*marime+c2,

i*marime+Math.round(marime/2), i*marime+marime, j*marime, 30);

// curba va fi desenată şi pe imaginea-ajutatoar _root.harta.bezier(i*marime, j*marime,

i*marime+Math.round(marime/2), j*

(33)

marime+Math.round(marime/2), j*marime+c2,

ale

a.bezier(i*marime, 2), me,

e,

me,

olosim de masca

ţiune din poză:

{ for (j=0; j<nr_h; j++) {

esă:

are piesă vom seta masca

nt uie să avem o funcţie de amestecare oziţionează aleatoriu piesele puzzle-ului:

nction amesteca() { i*

i*marime+marime, j*marime, 30);

}

// procedăm identic pentru curbele vertic if (i>0) {

// marginea din stanga:

piesa_"+i+"_"+j].masc _root["

j*marime, i*marime-c1, j*marime+Math.round(marime/

arime+Math.round(marime/2), i*mari i*marime+c1, j*m

j*marime+marime, 30);

// marginea din dreapta a piesei precedente:

_root["piesa_"+(i-1)+"_"+(j)].masca.bezier(i*marim j*marime, i*marime-c1, j*marime+Math.round(marime/2), i*marime+c1, j*marime+Math.round(marime/2), i*marime, j*marime+marime, 30);

// şi desenarea şi în cadrul imaginii ajutatătoare:

_root.harta.bezier(i*marime, j*marime, i*marime-c1, j*marime+Math.round(marime/2), i*marime+c1,

j*marime+Math.round(marime/2), i*marime, j*marime+mari 30);

} //sfârşitul condiţiei } // terminat piese „for j”

} // terminat „for i”

// să adăugăm poza şi să ne f

afişa doar o por // construită pentru a

for (i=0; i<nr_l; i++)

// ataşarea imaginii se face pentru fiecare pi

_root["piesa_"+i+"_"+j].attachMovie("img", "poza", - 2000+i*nr_h+j);

/

/ de asemenea pentru fiec

// adică forma construită anterior:

_root["piesa_"+i+"_"+j].poza.setMask(_root["piesa_"+i +"_"+j].masca);

// fiecărei piese îi setăm o umbră:

oot.umbra2;

_root["piesa_"+i+"_"+j].filters = _r

}

} }

treb // şi evide

care rep //

fu

(34)

_root["piesa_"+i+"_"+j]._y = random(240);

_root["piesa_"+i+"_"+j]._x = random(320);

le:

amestecăm:

.amesteca();

} }

}

// în final nu ne rămâne decât să construim piese ruieste_piese();

_root.const i sa le // ş

oot _r

S lui:

- l flash să fie aşezat în acelaşi director ca şi ce adaugă obiectului de tip MovieClip funcţia ce

-

- itulat „img”.

m vedea în cele ce urmează că ă vedem câteva aspecte care nu au putut fi explicate în liniile codu

trebuie neapărat ca

„grafix.as” – fişierulfişieru

desenează o curbă Bezier folosind două puncte de control. În cazul în care nu doriţi să aşezaţi în acelaşi director cele două fişiere, directiva

„include” de la începutul script-ului ar trebui să aibă ca parametru pe lângă numele fişierului şi calea corectă către acesta;

dimensiunea piesei poate fi schimbată ducând la mărirea sau micşorarea pieselor puzzle-ului;

se observă folosirea obiectului din bibliotecă int

Imaginea este ataşată iniţial scenei pentru a constitui un indiciu pentru rezolvarea puzzle-ului. Vo

aceasta nu este folosită doar ca indiciu ci şi pentru a verifica corectitudinea poziţionării unei piese: fiecare piesă are o anumită formă şi la început sunt desenate doar măştile ce vor defini forma fiecărei piese. Se observă că desenarea măştii nu începe niciodată din punctul 0,0 al MovieClip-ului „mască”; de fapt, ca să fim mai expliciţi putem spune că desenarea măştii porneşte din punctul

„P(i*marime, j*marime)” unde i,j variază în funcţie de poziţia piesei.

Aşadar, piesa este desenată la o anumită poziţie de punctul de înregistrare. Poziţionând imaginea cu colţul stânga-sus în punctul de înregistrare, masca se va afla exact deasupra zonei pe care vrem sa o reprezinte piesa puzzle-ului. Atunci când vom masca poza folosind masca construită vom avea exact piesa dorită. Aşadar punctul de control al fiecărei piese se află în colţul în care este aşezată imaginea (stânga-sus); este suficient să testăm dacă punctul acesta este în apropierea imaginii ajutătoare (hartă) pentru a valida poziţia piesei ce este mutată – fapt realizat în cadrul funcţiei onRelease asociat fiecărei piese.

(35)

-

e fiecare dată când se va apela comanda moveTo (care un alt aspect ar fi cel al modului în care facem umplerea măşii:

începerea umplerii începe odată cu comanda beginFill dar umplerea se va efectua d

se lansează în momentul construirii fiecărei curbe. Desenând şi pătratul central se va realiza un „xor” între cele două culori (adică acolo unde pătratul se va suprapune peste curbură – evident curbura interioară locul nu va mai fi desenat, va fi lăsat gol) – ar fi existat şi alte metode dar mai complicate.

Figura 2-4 – Imaginea puzzleului înainte de a fi rezolvat

Ce am încercat să realizăm aici este un puzzle cât mai simplu – nu am ut să încarc exemplul cu mai mult cod ActionScript decât era necesar (şi vr

aşa codul est otuşi pentru

ce

e destul de mare şi destul de dificil de înţeles). T

i care doriţi să continuaţi dezvoltarea exemplului v-aş putea da câteva sugestii (cu titlul de exerciţii):

- realizaţi o funcţie de auto-rezolvare a puzzle-ului (care va prelua pe rând fiecare piesă şi o va duce în poziţia corectă);

(36)

urbe Bezier cu un

-

e dinamic/aleatoriu dintr-un director ce conţine mai

-

l realizat de dumneavoastră pe un server (sau local – - să se realizeze şi alte tipuri de margini pentru piese şi nu numai

curbe Bezier (de exemplu folosiţi triunghiuri, c

singur punct de control, alte forme eventual definite manual de către dumneavoastră – aveţi grijă ca marginile unei aceleiaşi piese să nu se suprapună). O implementare cu adevărat interesantă ar fi aceea de a construi piesele puzzle-ului sub forme oarecare şi nu bazate pe pătrate;

încercaţi să realizaţi un astfel de puzzle în care imaginile să poată să fie încărcat

multe imagini;

puteţi încerca (pentru cei mai avansaţi dintre dumneavoastră) să salvaţi progresu

prin intermediul obiectelor „shared”). Puteţi de asemenea să folosiţi un server orientat-conexiune pentru a comunica în timp real cu alţi utilizatori şi a rezolva puzzle-ul în comun.

(37)

Capitolul 3

3 XML – metoda ideală pentru structurarea datelor

eXtended Markup Language ... şi Flash a putut comunica...

3.1 Construirea unei agende folosind XML

Dificultate: 4;

Să abordăm un subiect de care se tem cei mai mulţi programatori Flash (sau mă rog... dacă ajungi să programezi cu adevărat în Flash îţi dai seama cât de indispensabil este XMLul).

Nu voi încerca să vă explic istoria care stă în spatele XML-ului, cert este că la un moment dat a apărut acest format care poate fi folosit cu succes de majoritatea aplicaţiilor (fie ele disopnibile pe WEB sau nu). Formatul este unu destul de simplu şi este foarte bine înţeles şi de către partea umană. Să vedem cum arată un fişier XML ce conţine date privitoare la câteva persoane (pe care îl vom salva cu numele „agenda.xml”):

<?xml version="1.0" encoding="UTF-8"?>

<agenda>

<persoana>

<nume>Varlan.Cosmin</nume>

<telefon>0722123456</telefon>

</persoana>

<persoana>

<nume>Alboaie.Lenuta</nume>

<telefon>0723123456</telefon>

</persoana>

<persoana>

<nume>Croitoru.Marilena</nume>

<telefon>0742123456</telefon>

</persoana>

</agenda>

Din ce este alcătuit un fişier XML?

(38)

În primul rând avem pe prima linie un antet care furnizează ce versiune de XML folosim. În exemplul nostru am folosit versiunea 1.0. Tot în antet vom găsi şi encodingul caracterelor din fişierul XML. În acest XML se observă că am folosit ca encoding setul de caractere UTF-8.

Am întâlnit cazuri în care am avut nevoie să încarc în Flash fişiere XML care să conţină diacritice şi deoarece această problemă a iscat o discuţie destul de interesantă pe forumul www.actionscript.org vă voi oferi şi soluţia destul de simplă: Encodingul de care povesteam (UTF-8) conţine toate caracterele (inclusiv diacriticile). Pentru a scrie un fişier care să conţină caracterele speciale din limba română nu este suficient să specificaţi în antetul fişierului tipul encodingului ci trebuie să salvaţi fişierul ca atare.

Astfel dacă folosiţi notepad (alte editoare de texte au probabil opţiuni similare), apăsaţi opţiunea „Save as…” din meniul file. În fereastra de dialog obţinută veţi putea selecta un nou nume al fişierului, tipul fişierului şi formatarea acestuia. În saecţiunea de selectare a foamatării alegeţi opţiunea UTF-8:

Figura 3-1 – Selectarea tipului formatării pentru un fişier XML editat cu Notepad (secţiune din dialogul obţiunt prin apăsarea “Save as…”)

Fişierul XML poate fi reprezentat sub formă arborescentă şi formatul (deşi doar text) este înţeles ca atare de către aplicaţiile ce-l folosesc. Aşadar rădăcina arborelui construit în XML-ul de mai sus este nodul „agenda” şi are trei copii (de fapt trei persoane). Fiecare nod-persoană are asociat câte un nume şi un număr de telefon (fictiv evident).

Arborele XML-ului nostru ar putea fi reprezentat astfel:

(39)

Figura 3-2 – Arborea asociat XMLului “agenda.xml”

Fişierul XML este – după cum aţi observat – format din câteva marcaje şi informaţiile utile cuprinse între unele din marcaje. Fiecare nod va începe cu un marcaj de tipul <marcaj> şi se va termina cu unul de tip </marcaj>.

Cuvântul care defineşte începutul sau sfârşitul unui nod nu este special, putând fi scris în orice limbă, singura cerinţă este ca marcajul cu care a început un nod să fie similar cu cel cu care se termină.

În interiorul marcajelor (unui nod) puteţi defini alte marcaje (de fapt alte noduri şi deci şi sub-arbori), numărul de marcaje (noduri) imbricate fiind nelimitat. În exemplul nostru putem observa cum marcajul <agenda> este cel care deschide fişierul şi marcajul-pereche </agenda> este cel care îl termină. Acest nod care se extinde peste tot documentul se numeşte şi rădăcină. Relativ la rădăcină, nodurile de tip „persoană” se numesc noduri copii. Dacă privim din punctul de vedere al unui nod-persoană atunci nodul „agendă” este un nod-părinte.

O altă observaţie pe care trebuie să o facem este că un marcaj-A deschis în interiorul altui marcaj-B trebuie închis tot în interiorul marcajului-B.

Aşadar nu se permit marcaje imbricate.

Deschiderea fişierului XML cu ajutorul unui browser WEB(Internet Explorer, Firefox etc.) vă permite vizualizarea arborescentă a acestuia şi totodată verificarea corectitudinii acestuia:

(40)

Figura 3-3 – Afişarea XML-ului în cadrul unui Browser

Fiecare nod al unui fişier XML poate avea asociat un număr oarecare de atribute. De exemplu (reluând o porţiune din XML-ul de mai sus), putem considera la fel de bine:

<persoana>

<nume>Croitoru.Marilena</nume>

<telefon retea="Orange">0742123456</telefon>

</persoana>

XML-ul este în continuare corect. Despre atribute trebuie să reţinem că sunt folosite asemănător unor constante: au un nume şi o valoare. Valoarea este întotdeauna încadrată de ghilimele. De fapt, aceleaşi informaţii care exprimate prin XML-ul iniţial pot fi redate prin intermediul atributelor (fişierul „agenda2.xml”):

<agenda>

<persoana nume="Varlan.Cosmin" telefon="0722123456" />

<persoana nume="Alboaie.Lenuta" telefon="0723123456" />

<persoana nume="Croitoru.Marilena" telefon="07123456" />

</agenda>

Nu putem spune că prima metodă este corectă sau a doua. Important este ca aplicaţia care se foloseşte de fişierul XML să înţeleagă corect conţinutul acestuia.

Observaţi că acestui XML îi lipseşte cu desăvârşire antetul. Acesta este cu caracter opţional şi doar furnizează informaţii despre XML. Flash-ul ignoră

(41)

linia-antet şi trece direct la parcurgerea informaţiilor din interiorul XML- ului (numai după ce a verifica, bineînţeles, dacă XMLul este unul valid – toate marcajele deschise sunt şi închise respectiv nu există marcaje imbricate).

O a doua observaţie pe care o putem face este că marcajele sunt închise fără a fi scrise de două ori, prin apariţia caracterului „/” la sfârşitul marcajului. Aşadar un marcaj de tipul <marcaj /> nu are nevoie de un marcaj-pereche.

În Flash, pentru a putea parcurge arborele XML trebuie ca acesta să fie încărcat complet în memorie (parsare DOM).

Felul în care vă definiţi XML-ul (ca în primul caz sau ca în al doilea) este la latitudinea dumneavoastră. Ar fi bine totuşi ca marcajele să exprime corect informaţiile din interiorul lor (de exemplu marcajul telefon chiar să conţină numărul de telefon şi nu adresa de mail).

De ce se foloseşte Flashul de XML ? Ei bine, obiectul Flash este un obiect compilat şi din acest motiv nu prea avem cum să modificăm informaţiile existente în cadrul său. Să zicem că am avea o agendă făcută în Flash, fără a utiliza XML. Acest lucru ar însemna că avem toate informaţiile (numele persoanelor, telefoanele) scrise direct în codul sursă (probabil ca variabile sau ca tablouri). Ce se întâmplă atunci când vrem să adăugăm o nouă persoană ? Vom căuta sursa Flash-ului (şi ne vom bucura dacă o mai găsim), vom adăuga nouă variabilă, va trebui să recompilăm obiectul Flash (asta evident dacă avem Flash-ul instalat) după care să-l punem din nou pe serverul pe care se afla iniţial.

Fişierul XML poate fi modificat cu un simplu editor şi acest lucru se poate realiza şi direct pe server. Obiectul Flash care se foloseşte de XML va trebui apoi doar să reîncarce XML-ul updatat şi să-l afişeze ca atare.

Să construim obiectul Flash care folosindu-se de XML-ul „agenda.xml”

afişează într-un mod plăcut conţinutul agendei dumneavoastră.

Pentru început vom seta scena la 640x480 şi din fereastra cu componente vom aduce în scenă un obiect de tipul DataGrid (printr-o operaţie drag &

drop). Din fereastra de proprietăţi vom schimba dimensiunile componentei la 600 (lungime) respectiv 400 (înălţime) şi-i vom asocia numele de instanţă

„dg”.

Referințe

DOCUMENTE SIMILARE

În contextul dat, vom încerca să demonstrăm faptul că realismul isteric este inclus în maximalism și, ca atare, tema acestei teze este de a scoate în eviden ță

BABOŞA este înregistrat de Tomici, Andronache la 5 persoane (în formele: 1- Babosa, 4-Baboşa) şi considerat derivat de la n.. În DFNFR

Tipologic, formal şi funcţional, la Gurile Dunării ceramica romană cunoaşte o varietate de tipuri şi, pentru a facilita discuţia, vom porni de la aspectul

 În final aceste diferenţe sunt normalizate şi utilizate la construirea histogramei, bazându-ne pe faptul că deschiderea corespunzătoare unei anumite dimensiuni

Astfel, la început, în grup erau doar câțiva foşti colegi de-ai lui din „C“ – Matei, Alberto şi Ena –, Țache, care reuşise să intre în cercul lor şi pentru că erau

Soluţia părea excelentă şi pentru unii, şi pentru alţii; avea acel aer de provizorat care convenea tuturor, într-o situaţie mai mult decât fluidă.. Eu vedeam doar fericita

Fie A şi B două inele în care (pentru a simplifica scrierea) operaţiile sunt notate pentru ambele prin „+” şi „·”. Dacă A şi B sunt inele unitare, vom spune că

Vom admite existenţa mulţimii vide şi ea se poate caracteriza astfel: ∀x( x∉∅) este o proprietate adevărată. Relaţia de incluziune este un predicat binar şi de multe ori se