+ All Categories
Home > Documents > Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf ·...

Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf ·...

Date post: 19-Jan-2020
Category:
Upload: others
View: 3 times
Download: 0 times
Share this document with a friend
142
Transcript
Page 1: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop
Page 2: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Introducere

Î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

Page 3: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

1

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 printr-un orificiu aflat în capătul opus celor în care se află pietrele, reflecţia lor în cele trei oglinzi dă impresia unei flori – de fapt o iluzie de copiere a originalului.

Page 4: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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

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.

Page 5: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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.

3

Page 6: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

4

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; }

Page 7: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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 jumate din text şi apoi folosiţi opţiunea Create warped text - arc pentru a crea

5

Page 8: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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

63 Counter Clockwise = împotriva acelor de ceasornic

Page 9: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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.

7

Page 10: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

8

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).

Page 11: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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.

9

Page 12: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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) .

10

Page 13: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

11

Ţ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):

Page 14: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

_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

12

Page 15: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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”.

13

4 Personal pentru realizarea săgeţii am folosit fontul Windings3 după care am apăsat tasta ‘ (apostrof). Caracterul poate fi convertit în element graphic apăsând de două ori combinaţia de taste CTRL+B.

Page 16: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

14

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

Page 17: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

15

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); _root.mc.txtdecod = "Acest text va fi decriptat.";

Page 18: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

16

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; };

Page 19: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

17

Î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 caractere. Atunci veţi adăuga codul ascii al primei litere din parolă

Page 20: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

18

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.

Page 21: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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. Procedăm asemănător cu segmentele dintre cele două puncte de control şi

19

Page 22: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

20

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

Page 23: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

21

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; // puncte intermediare pentru prima dreapta s1c1c2x=s1c1x+(c1c2x-s1c1x)*raport;

Page 24: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

22

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).

Page 25: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

23

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 paşi cu atât curba va avea o precizie mai mare.

Page 26: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

24

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

Page 27: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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)

25

Page 28: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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:

26

Page 29: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

27

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; // şi setăm un tip de linie pentru desenarea unor //curbe ajutătoare:

Page 30: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

28

(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(); }; };

Page 31: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

29

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:

ca

// ş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, 1rei p // vom desena un pătrat în poziţia fiecă es

// pătratul va fi plin şi dacă va fi definit exact // aici, vom putea crea corect fiecare piesă:

Page 32: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

30

_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 // pentruca î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].mrioare/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*maj ime, i*marii* 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*marj 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*

Page 33: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

31

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() { for (i=0; i<nr_l; i++) {

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*marii*marime+c1, j*mj*marime+marime, 30); // marginea din dreapta a piesei precedente: _root["piesa_"+(i-1)+"_"+(j)].masca.bezier(i*marimj*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+mari30); } //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 evidecare rep//

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

Page 34: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

32

_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.consti 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şierul

fişieru

desenează o curbă Bezier folosind două puncte de control. În cazul încare 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ă intImaginea este ataşată iniţial scenei pentru a constitui un indiciu pentru rezolvarea puzzle-ului. Voaceasta 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.

Page 35: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

33

-

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 dse 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). Ti 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ă);

Page 36: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

34

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, csingur 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ărcatmulte imagini;

puteţi încerca (pentru cei mai avansaţi dintre dumneavoastră) să salvaţi progresuprin 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.

Page 37: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

35

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?

Page 38: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

Î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:

36

Page 39: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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:

37

Page 40: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

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ă 38

Page 41: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

39

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”.

Page 42: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

40

Să trecem la încărcarea XMLului din exterior. Pentru început vom defini obiectul XML şi îl vom încărca din exterior. Pentru a ne convinge că XMLul a fost încărcat vom executa comanda trace având ca parametru chiar obiectul XML. Aşadar, în primul cadru al Flash-ului (aveţi grijă să nu scrieţi codul decât dacă aveţi selectat cadrul şi nu componenta „dg”):

var arbore_xml = new XML(); arbore_xml.load("agenda.xml"); trace(arbore_xml);

Executând Flash-ul probabil că vă veţi aştepta ca în fereastra Flash să fie afişat conţinutul XML-ului. Ei bine, acest lucru nu se va întâmpla. Să vedem de ce... şi aici este de fapt explicaţia pentru care atâtor de multe persoane XML-ul li se pare extraordinar de greu de utilizat cu Flash-ul.

Aşa cum am zis puţin mai devreme, pentru a fi utilizat de Flash XMLul trebuie să fie complet încărcat în memorie. Operaţiile din ActionScript sunt executate destul de rapid şi între comanda de încărcare a XMLului şi cea de afişare a lui nu va trece decât câteva milisecunde (şi motivul este evident: obiectul Flash trebuie să treaca rapid la următorul cadru al animaţiei şi nu are timp să stea după XML să se încarce de pe Internet poate în câteva secunde bune).

Totuşi ce face Flash-ul pentru a prelucra cum trebuie XML-urile ? Ei bine, înainte de a se începe încărcarea XML-ului, se încarcă în memorie o funcţie care se va executa numai în momentul în care XMLul s-a încărcat în întregime. Să refacem codul de mai sus pentru a funcţiona corect:

var arbore_xml = new XML(); arbore_xml.onLoad = function() { trace(arbore_xml); }; arbore_xml.load("agenda.xml");

Înlocuind scriptul cu noul script, la compilarea Flash-ului veţi obţine într-o fereastră conţinutul XMLului.

Imediat după definirea obiectului (respectiv înaintea funcţiei onLoad) vom adăuga următorul cod:

arbore_xml.ignoreWhite = true; _root.dg.addColumn("Nume"); _root.dg.addColumn("Telefon"); dg.setSize(600, 400);

Page 43: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

41

dg.getColumnAt(0).width = 400; dg.getColumnAt(1).width = 180;

Prin intermediul acestui cod vom ignora spaţiile albe din interiorul XMLului (Flash-ul nu ştie să trateze caracterele spaţiu, enter sau tab aflate în faţa marcatorilor sau între ei şi din acest motiv acestea trebuie eliminate prin execuţia comenzii ignoreWhite. Comenzile următoare au rolul de a adăuga componentei DataGrid două coloane intitulate „Nume” şi „Telefon” şi de a le redimensiona astfel încât numele să încapă în întregime în coloana asociată lui.

Revenim la funcţia onLoad în care ştim că XMLul este disponibil şi putem să extragem din el datele:

arbore_xml.onLoad = function() { for (i=0;i<this.firstChild.childNodes.length;i++){ nume = this.firstChild.childNodes[i]. firstChild.firstChild.nodeValue; telefon = this.firstChild.childNodes[i]. lastChild.firstChild.nodeValue; dg.addItem({Nume:nume, Telefon:telefon}); } };

Să vedem câţi paşi face instrucţiunea „for”. Să presupunem că avem n persoane, copii ale nodului „agenda”. În cadrul funcţiei onLoad, prin „this” se identifică obiectul arbore_xml. For-ul principal merge de la 0 până la valoarea mai mică decât this.firstChild.childNodes.length. Prin firstChild se identifică nodul-rădăcină (agenda) apoi prin childNodes se găseşte un şir de elemente, fiecare element având asociat subarborele unei anumite persoane. Pentru a identifica câte elemente sunt în acest şir, interogăm proprietatea length specifică array-urilor.

Pentru a prelua numele din obiectul XML navigăm spre primul nod (agenda) apoi construim array-ul prin intermediul childNodes şi selectăm elementul de pe poziţia [i] (respectiv 0,1,2... depinde de al câtelea nod-persoană este procesat) apoi din nodul-persoană selectat preluăm primul nod (respectiv nodul nume) şi din nou primul nod pentru a ajunge la nodul de tip text ce reprezintă numele propriu-zis. Pentru a extrage valoarea apelăm nodeValue.

Iniţial în XMLul nostru aveam trei persoane şi din acest motiv for-ul va merge de la 0 până la 2 (0, 1, 2) identificând pe rând cele trei persoane din

Page 44: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

XML. Odată cu adăugarea unui nou nod-persoană, for-ul va funcţiona de la 0 până la 3 (0, 1, 2, 3) şi va prelua pe rând informaţiile despre toate persoanele existente in XML.

În cazul în care se optează pentru cel de-al doilea tip de XML (cel în care numele şi telefonul sunt date ca atribute), singurele linii ce trebuiesc schimbate sunt cele privitoare la preluarea informaţiilor din XML (respectiv liniile în care se dau valori numelui şi telefonului). Acestea vor deveni:

nume = this.firstChild.childNodes[i].attributes.nume; telefon= this.firstChild.childNodes[i].attributes.telefon;

Ca exerciţiu, construiţi un nou XML în care să se deosebească clar numele, prenumele, telefonul şi adresa de e-mail la care poate fi contactată o persoană, ca în imaginea de mai jos (în imagine, din motive tipografice nu a fost reprodusă întreaga scenă de 640x480 pixeli):

Figura 3-4 – Agenda

În unul din următoarele exerciţii vom învăţa cum să modificăm un fişier XML folosind serverul PHP şi atunci nu va mai trebui nici măcar să edităm fişierul XML pentru adăugarea unei noi persoane, toate acestea fiind posibile de realizat dintr-o interfaţă WEB.

3.2 Realizarea unei cărţi de oaspeţi (GuestBook)

Dificultate: 9; Necesită instalarea unui program auxiliar...

Când ne vom construi situl vom dori să permitem utilizatorilor să ne lase diverse mesaje. De asemenea această mini-aplicaţie poate fi privită şi ca un jurnal online (blog).

Unde va fi situată cartea de oaspeţi ?

42

Page 45: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

43

Un răspuns evident pentru această întrebare este că pe un server web. Serverul web este o aplicaţie ce rulează pe un calculator5 care are rolul de a răspunde cererilor diverselor persoane care vor să viziteze o anumită pagină. Astfel, în momentul în care dumneavoastră tastaţi în browserul pe care îl folosiţi o anumită adresă (de exemplu http://www.actionscript.org) nu faceţi decât să cereţi unei astfel de aplicaţii anumite informaţii (în acest caz prima pagină a sitului actionscript.org). Browserul dumneavoastră se numeşte client pentru că se comportă ca unul – el cere nişte informaţii, iar o anumită aplicaţie care îi furnizează aceste informaţii se numeşte server. Serverul poate rula sub diverse sisteme de operare. Deoarece Flash-ul este distribuit doar pentru Windows şi MacOS (pentru Linux există doar player) şi deoarece majoritatea persoanelor care citesc această carte (din România) au instalat Windows, vom folosi un server care să ruleze sub acest sistem de operare. Un astfel de server web este Apache şi versiunea de windows se numeşte Apache2Triad. Situl de unde puteţi descărca (gratuit) acest server este: http://sourceforge.net/projects/apache2triad/.

După instalarea serverului (lucru pe care nu-l explic aici deoarece consta în apăsarea repetată a unor butoane de tip „next”) veţi găsi în rădăcina partiţiei C de pe calculatorul dumneavoastră un director „apache2triad” sau asemănător (asta în cazul în care nu aţi schimbat calea în timpul instalării; dacă acest director nu este vizibil va trebui să permiteţi vizualizarea fişierelor ascunse). În Directorul „c:\apache2triad” căutaţi directorul htdocs: aici vor fi păstrate toate documentele care vor fi servite de către server clientului şi în acest director creaţi un director propriu de exemplu „guestbook”.

Deschideţi browserul pe care îl utilizaţi şi tastaţi ca adresă următorul şir de caractere: http://localhost/guestbook/ , aceasta fiind calea către directorul creat. De fapt browserul va face o cerere serverului (care se află tot pe calculatorul dumneavoastră – de aici „localhost” care îi va furniza o pagină web ce momentan nu conţine nimic şi furnizează informatii despre directorul guestbook.

Documentele ce pot fi trimise către dumneavoastră de către server sunt de cele mai variate: imagini, filme, MP3-uri, documente word, pdf. Browserul, totuşi, pentru a înţelege şi a formata corect informaţiile pe care vreţi să le puneţi în pagina de web are nevoie de un format anume de document şi anume (x)html. Toate documentele enumerate mai sus

5 De multe ori chiar calculatorul ce rulează aplicaţia este numit (oarecum impropriu) server.

Page 46: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

44

(inclusiv cele html) sunt de obicei documente statice – adică nu sunt generate de fiecare dată. Într-un guest-book avem nevoie ca pagina furnizată de server să se modifice de fiecare dată când cineva introduce un mesaj. Din acest motiv pe lângă apache (serverul web) apache2triad a mai instalat un interpretor de scripturi şi anume PHP6-ul.

Vom crea un fişier de test „index.php” care va conţine următorul script:

<?PHP phpinfo(); ?>

Fişierul va fi copiat în directorul guestbook după care încercaţi să accesaţi din nou adresa. Dacă aţi putut vizualiza mesajul atunci totul a decurs corect – puteţi şterge fişierul „index.php”.

Dacă vizitatorii vor dori să semneze în cartea dumneavoastră de oaspeţi atunci va trebui ca mesajele ce sunt trimise de către ei să fie „memorate” undeva. Flash-ul nu poate scrie pe maşina clientului fişiere7 (de fapt nu are voie să modifice nici un fel de parametru de pe maşina client care ar putea periclita buna-funcţionare a acesteia) şi chiar dacă ar găsi o metodă de a memora aceste informaţii pe calculatorul local, nimeni nu va putea accesa această informaţie. Din acest motiv informaţiile trimise de un vizitator trebuie sa fie păstrate pe calculatorul pe care rulează serverul şi de fiecare dată când cineva intră, serverul trebuie să ştie să construiască o pagină care să conţină toate mesajele.

Flash-ul ştie să preia de pe server informaţii în diverse formate: txt, xml, jpg, swf, flv etc. Se pot folosi foarte bine fişiere în format txt dar pentru a structura datele transmise între client şi server ne vom folosi de un fişier în format XML. Pentru acest exemplu informaţiile din XML vor conţine numele persoanei ce a introdus mesajul, mesajul propriu-zis, data la care a fost introdus mesajul respectiv adresa IP a calculatorului de la care a fost transmis mesajul (eventual o adresa de mail si una de web). Cu excepţia ultimei informaţii, datele vor fi transmise de către Flash-ul ce rulează pe maşina clientului (am fi putut obţine data de pe server prin anumite

6 Nu vom intra aici în detalii în ceea ce priveşte PHP-ul, cititorul fiind invitat pentru a aprofunda subiectul să consulte situl http://www.php.net/ sau cele două cărţi despre acest subiect ce au ca autor pe domnul Traian Anghel şi sunt disponibile la editura Polirom. 7 Singurele informaţii care pot fi scrise pe maşina clientului pot fi aşa-numitele cookie-uri prin intermediul cărora pot fi păstrate diverse setări preferate de client – limba, culoarea fondului etc.

Page 47: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

45

comenzi PHP dar scopul nostru este de a exemplifica utilităţile Flash-ului şi nu a PHP-ului).

Pentru acest exemplu vom folosi modulul domxml care vine deja instalat în cadrul Apache2Triad. Totuşi în unele cazuri acesta nu este activat. Pentru a verifica dacă acest modul este instalat deja, studiaţi conţinutul documentului rezultat în urma executării comenzii phpinfo (exemplul precedent). În cazul in care modulul domxml nu este activat, cautaţi fişierul php.inf pe partiţia C (cel mai probabil în directorul windowsului dar uneori în windows\system şi în interiorul acestuia decomentaţi linia:

extension=php_domxml.dll

copiaţi în continuare fişierul php_domxml.dll şi iconv.dll în directorul system32 din directorul în care este instalat windowsul (ambele fişiere le veţi găsi dând search în directorul în care a fost instalat apache-ul).

Ne vom abate puţin de la Flash pentru a vedea cum construim un documewnt XML în PHP, cum adăugăm în acest document o nouă înregistrare şi cum putem citi o anumită înregistrare (sau mai multe cu aceeaşi caracteristică) din acest document. Toate fişierele din acest exemplu vor fi puse în directorul c:\apache2\htdocs\guestbook. Documentul XML va avea un format simplu, conceput pentru a reţine mesajele introduse de un vizitator (nu trebuie să tastaţi acest document, el este doar pentru a exemlifica formatul):

<?xml version=”1.0” ?> <mesaje> <mesaj> <nume>Marian Târpescu</nume> <msg>Imi place acest guestbook</msg> <data>09:19:47 [02.07.2006]</data> <identificare> <ip>193.226.24.84</ip> <mail>[email protected]</mail> <web>http://www.marian.xhost.ro</web> </identificare> </mesaj> <mesaj> <nume>Amarie Alex</nume> <msg>Deoarece nu am macromedia Flash player instalat pe calculator a trebuit sa astept putin pentru incarcarea sitului. Nu se poate elimina acest inconvenient ?</msg> <data>16:23:51 [03.07.2006]</data>

Page 48: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

46

<identificare> <ip>191.122.43.6</ip> <mail>[email protected]</mail> <web>http://www.alexx.ro</web> </identificare> </mesaj> ....................... </mesaje>

Acest XML va trebui să fie construit din datele transmise de către Flash. Vom omite pentru început modul de transmitere a datelor din flash şi vom încerca să adăugăm un nod nou obiectului XML aflat în formatul de mai sus. Nodul nou ce va fi adaugat va fi de fapt un nou continut de tip <mesaj> .... </mesaj> adică exact ce este transmis de catre o persoană.

Pentru a deschide orice script PHP vom pune tag-ul de inceput <?PHP dupa care vom iniţializa variabilele care teoretic ar trebui să fie transmise de către Flash (vom vedea ulterior cum sunt transmise aceste variabile):

<?PHP $nume = "Marian"; $msg = "Mesaj de adaugat guestbookului"; $mail = "[email protected]"; $web = "http://www.marian.ro"; $ip = getenv("REMOTE_ADDR"); // prea adresa IP a //calculatorului vizitatorului $data = date("H:i:s [d.m.Y]"); // data postării mesajului

În continuare trebuie să verificăm dacă fişierul în care stocăm mesajele (care se va numi „mesaje.xml”) există deja pe hard-disk şi în caz contrar să creăm acest fişier în format XML:

if (!file_exists("mesaje.xml")){ $doc = new_xmldoc('1.0'); $root = $doc->add_root('mesaje'); $filename="mesaje.xml"; $fp = @fopen($filename,'w'); if(!$fp) { die(mesaj_eroare=Nu pot crea fisierul XML'); } fwrite($fp,$doc->dumpmem()); fclose($fp); }

După acest pas fişerul va fi găsit şi va putea fi deschis (fie din cauză ca tocmai a fost creat fie din cauză că deja exista).

Page 49: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

47

Pentru a deschide fişierul trebuie să ne folosim de comanda domxml_open_file care din păcate necesită calea completă către fişier. Din acest motiv avem nevoie să definim valoarea PATH ca mai jos. În cazul în care calea unde aţi stocat dumneavoastră „mesaje.xml” nu corespunde cu cea dată mai jos, modificaţi-o pentru a pointa spre locul unde este stocat fişierul dumneavoastră:

define ("PATH", 'c:\\apache2\\htdocs\\guestbook\\'); if (!$doc = domxml_open_file(PATH . "mesaje.xml")) { echo " mesaj_eroare=Eroare la deschidere XML"; exit; }

Acum vom adăuga o variabilă care să pointeze spre rădăcina documentului, variabilă prin intermediul căreia vom putea adăuga noile valori:

$root = $doc->document_element(); //acum $root va pointa // spre „mesaje”

Ne vom folosi în continuare de „new_child” pentru a adăuga un nod nou (respectiv un nod cu numele „mesaj” dar a cărui conţinut va fi format din alte noduri pe care le vom adăuga de asemenea folosind „new_child”:

$mesaj_nou = $root->new_child('mesaj',''); // în continuare adăugăm nodul “nume” nodului “mesaj”: $nume_ = $mesaj_nou->new_child('nume',$nume); // adăugăm nodul “msg” nodului mesaj: $mesaj_ = $mesaj_nou->new_child('msg',$msg); // memorăm ora transmiterii mesajului: $data_=$mesaj_nou->new_child('data',$data); // adăugăm nodul “identificare” nodului “mesaj”: $identificare_= $mesaj_nou->new_child ('identificare',''); // adăugăm nodul “IP” nodului “identificare”: $ip_ = $identificare_->new_child('ip',$ip); $mail_ = $identificare_->new_child('mail',$mail); $web_ = $identificare_->new_child('web',$web);

Acum, în variabila $doc vor fi reţinute tot arborele XML. Pentru a-l putea vizualiza sau scrie pe HardDisk ne vom folosi de funcţia dumpmem(). Modul de scriere a fişierului pe HDD este clasic si nu insistăm asupra funcţiilor implicate, în final vom închide scriptul PHP prin utilizarea marcajului final „?>”:

$filename="mesaje.xml";

Page 50: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

48

$fp = @fopen($filename,'w'); if(!$fp) { die(' mesaj_eroare=Nu pot crea fisierul XML'); } fwrite($fp,$doc->dumpmem()); fclose($fp); echo "mesaj_eroare=OK"; ?>

Salvaţi scriptul de mai sus cu numele „adauga.php” şi copiaţi-l în directorul în guestbook din htdocs. Executaţi acest PHP de mai multe ori, scriind in browser: http://localhost/guestbook/adauga.php şi apăsând repetat „refresh”. În acest mod veţi crea un XML ce va conţine mai multe norudi.

După fiecare execuţie ar trebui să obţineţi o pagină care să conţină „mesaj=OK” şi să găsiţi în directorul guestbook un fişier XML „mesaje.xml” care să conţină variabilele definite la începutul PHP-ului (eventual de mai multe ori).

Scriptul PHP va rula pe server dar avem nevoie de o aplicaţie de tip client care să comunice datele (numele, mesajl, etc.). Aplicaţia de pe client poate fi un formular HTML (caz în care aplicaţie este mult spus) sau poate fi un obiect Flash.

Obiectul Flash va fi construit în trei părţi (nu vom adăuga un preloader la acest flash deorece este destul de mic şi mesajele nu sunt – în general – foarte multe). Prima parte este cea care va afişa toate mesajele şi este cea care va apare atunci când Flash-ul va fi deschis în browser. Partea a doua este constituită dintr-un formular care are rolul de a transmite datele către PHP-ul construit mai devreme iar cea de-a treia parte va afişa un mesaj de confirmare (sau de eroare).

Vom construi guest-book-ul încercând să folosind atât script cât şi construcţii grafice.

Drept constructii grafice veţi realiza trei imagini reprezentând un plic, un glob pământesc respectiv un cursor pentru scroll. Primele două imagini vor reprezenta legături către e-mailul respectiv pagina web a celui ce a postat mesajul (daca au fost introduse). După ce au fost redimensionate la 12x12 pixeli, imaginile vor fi transformate în MovieClip (indiferent ca sunt imagini scalare - importate în Flash sau imagini vectoriale) şi li se vor da ca

Page 51: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

49

nume de legătură valorile „pictograma_mail”, „pictograma_web” respectiv „cursor_scroll”.

Pentru început vom încărca fişierul XML (cel ce conţine mesajele) şi-l vom afişa. Următorul cod este cel mai banal atunci când vrem să încărcăm un obiect XML dintr-un fişier extern (nu vom încerca să interpretăm încă datele ci doar să afişăm conţinutul. Flashul pe care îl veţi crea va fi salvat în acelaşi director în care este şi fişierul XML şi se va numi „guestbook.fla”. Iniţial vom defini doar obiectul XML şi vom afişa conţinutul său.

Fişierul XML nu se va încărca instant de pe server; orice persoană care a utilizat vreodata internetul ştie că în anumite momente datele se încarcă mai repede, alte dăţi mai încet. După ce am dat comandă către server să ne trimită fişierul ce conţine mesajele nu ne putem aştepta ca la instrucţiunea imediat următoare informaţiile să fie deja la client. Din acest motiv ne vom folosi de evenimente – cum ar fi eventimentul încărcării XML-ului în memorie. Codul (care va fi pus in primul cadru al unui nou document Flash) este următorul:

var mesaje = new XML(); mesaje.ignoreWhite = true; mesaje.onLoad = function() { trace (mesaje.toString()); }; mesaje.load("mesaje.xml");

În prima linie de cod se alocă memorie pentru obiectul XML, se ignoră spaţiile albe din cadrul XMLului (unui om ii este mai uşor să înţeleagă conţinutul unui fişier XML dacă este structurat aşa cum este structurat mai sus... calculatorul nu are nevoie ca datele să fie aliniate, mai mult spaţiile albe precum tab-ul sau spaţiul dăunează interpretării corecte a obiectului XML – acest lucru este valabil în Flash). În momentul încărcării complete a XMLului în memorie se va executa (automat) funcţia „onLoad” care va afişa conţinutul obiectului XML. În finalul codului mai trebuie să dăm comandă serverului să ne trimită fişierul XML: mesaje.load(„mesaje.xml”);

Ceea ce vrem noi sa facem este mai mult decât doar să afişăm XMLul. Trebuie să formatăm informaţia să apară cum ne place nouă. Ştergeţi codul iniţial (el a fost pus doar pentru a testa dacă fişierul XML se încarcă corect) şi să încercăm să scriem codul pentru adevăratul guestbook. Pentru început vom face câteva iniţializări:

_root._lockroot = true;

Page 52: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

50

//dimensiunea scenei: _root.maxx = Stage.width-1; _root.maxy = Stage.height-1; // tipurile de text cu care vom scrie in guestbook: var textformat = new TextFormat("tahoma", 11, 0, false); textformat.color = 0x003366; var textformat_nume = new TextFormat("tahoma", 11, 0, true); textformat_nume.color = 0x003333; var textformat_data = new TextFormat("tahoma", 11, 0, false); textformat_data.color = 0x003333; //un obiect XML si o functie asociata incarcarii: var mesaje = new XML(); mesaje.ignoreWhite = true;

În această porţiune din cod am setat proprietatea lockroot a scenei ca fiind adevărată. Această proprietate este necesară pentru ca player-ul Flash să ştie unde trebuite să încarce datele. Dacă Flash-ul pe care tocmai îl construiţi va fi ulterior ataşat (prin intermediul comenzii loadMovie) altui obiect Flash există pericolul ca cele două „root-uri” (al Flash-ului ce încarcă respectiv din cel încărcat) să se confunde. Prin blocarea rădăcinii8 obiectului Flash se evită această problemă.

Preluăm dimensiunile scenei pentru ca guestbook-ul să poată fi afişat corect indiferent de dimensiunea scenei (deci ulterior veţi putea altera dimensiunea scenei fără a strica guestbook-ul) – pentru ca guestbookul să fie totuşi conform standardului deja folosit în exemplele anterioare, puteţi seta dimensiunile scenei de pe acum la 640x480. Porţiunea desenabilă va fi aşadar de la 0 la maxx pe axa X şi de la 0 la maxy pe axa Y. În continuare setăm trei tipuri de formatări ale textului: modul în care va fi afişat mesajul, numele respectiv data. Ultimele două comenzi le recunoaşteţi din codul anterior. În continuare vom construi funcţia de afişare (de fapt afişarea se va produce în momentul încărcării XMLului în memorie deci este normal ca aici să postăm toate comenzile care vor formata mesajele.

Vom construi această funcţie în câţiva paşi: primul pas este cel al construirii unui MovieClip în care vom afişa guestbook-ul:

mesaje.onLoad = function() {

8 Blocarea rădăcinii este necesară când Obiectul Flash creat va fi încărcat în alt document şi când este nevoie ca în el să fie încărcate alte date – de exemplu XML sau JPG.

Page 53: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

51

//construim un background de culoare deschisă _root.createEmptyMovieClip("guestbook", 0); _root.guestbook.lineStyle(1, 0x000000, 50); _root.guestbook.beginFill(0xffffff, 80); _root.guestbook.moveTo(0, 0); _root.guestbook.lineTo(maxx, 0); _root.guestbook.lineTo(maxx, maxy); _root.guestbook.lineTo(0, maxy); _root.guestbook.lineTo(0, 0); // atenţie ! codurile ce vor urma se vor pune în // continuare ca făcând parte din aceeaşi funcţie……

Guestbook-ul va conţine două părţi: cea în care vor fi afişate mesajele şi cea în care se introduce un mesaj nou. Deocamdată construim prima parte – MovieClip-ul „guestbook” are rolul de a afişa mesajele. Atunci când vom introduce datele acesta va fi în întregime ascuns. Construcţia backgroundului foloseşte funcţii deja folosite (în exemplul cu puzzle-ul) şi din acest motiv nu le vom mai explica.

Mesajele vor depăşi la un moment dat dimensiunea scenei. Din acest motiv vom construi un MovieClip care să conţină toate mesajele dar care va putea fi deplasat pe axa Y în cadul MovieClip-ului „guestbook” (ulterior acest MovieClip va fi mascat pentru a nu strica aspectul GuestBook-ului).

// construim un tabel ce se va putea deplasa sus-jos: // in acest tabel vor fi "aninate" posturile // si acest tabel va fi mascat de o masca _root.guestbook.createEmptyMovieClip("tabel", 0); //pozitia afisarii unui mesaj poz_curent = 30; //un sir continand toate inregistrarile: var vector = this.firstChild.childNodes;

variabila „poz_curent” indica locul de unde se va începe afişarea mesajelor în cadrul MovieClip-ului „tabel”. În şirul „vector” vom regăsi pe rând nodurile XMLului ce conţin mesajele, numele, datele etc. Va trebui ca pentru fiecare element din acest şir să construim o metodă „frumoasă” de afişare. Vom folosi o structură repetitivă pentru afişarea consecutivă a mesajelor şi preluăm datele din XML (nume, mesaj, data, mailul, adresa web):

for (i=vector.length-1; i>-1; i--) { //preluam textul din nodul "nume" nume_din_xml=vector[i].childNodes[0].firstChild.nodeValue; //preluam textul din nodul "msg"

Page 54: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

52

mesaj_din_xml=vector[i].childNodes[1].firstChild. nodeValue; data_din_xml=vector[i].childNodes[2].firstChild.nodeValue; mail_din_xml=vector[i].childNodes[3].childNodes[1]. firstChild.nodeValue; web_din_xml=vector[i].childNodes[3].childNodes[2]. firstChild.nodeValue;

Calculăm spaţiul ce va fi ocupat de fiecare mesaj:

var metrics:Object = textformat.getTextExtent (mesaj_din_xml, _root.maxx-80);

Parametrii funcţiei getTextExtent sunt mesajul respectiv spaţiul pe care vrem să-l ocupe pe axa X (pe o linie vrem să avem text care să ocupe maxim _root.maxx-80 pixeli). De înălţimea pe axa Y returnată de getTextExtent ne vom ocupa ulterior. Deocamdată fiecărui mesaj îi vom desena o bară ce va conţine numele celui ce a introdus mesajul, data şi eventual două legături către adresa de mail şi pagina web a celui ce a postat (în caz că acestea au fost introduse):

_root.guestbook.tabel.lineStyle(1, 0x999999, 10); _root.guestbook.tabel.beginFill(0xffffff, 30); _root.guestbook.tabel.moveTo(25, poz_curent+20); _rot.guestbook.tabel.lineTo(_root.maxx-50, poz_curent+20); _root.guestbook.tabel.lineTo(_root.maxx-50, poz_curent); _root.guestbook.tabel.lineTo(25, poz_curent); _root.guestbook.tabel.lineTo(25, poz_curent+20); _root.guestbook.tabel.endFill();

După care vom desena încă un dreptunghi ce va constitui un fundal pentru mesaj dreptunghi a cărui înălţime va varia de la mesaj la mesaj.

_root.guestbook.tabel.lineStyle(1, 0x333355, 10); _root.guestbook.tabel.beginFill(0xffffff, 40); _root.guestbook.tabel.moveTo(25, poz_curent); _root.guestbook.tabel.lineTo(_root.maxx-50, poz_curent); _root.guestbook.tabel.lineTo(_root.maxx-50, poz_curent+metrics.textFieldHeight+25); _root.guestbook.tabel.lineTo(25, poz_curent+metrics.textFieldHeight+25); _root.guestbook.tabel.lineTo(25, poz_curent); _root.guestbook.tabel.endFill();

De remarcat este modul în care am calculat înălţimea mesajului folosind obiectul metrics: metrics.textFieldHeight+25.

Page 55: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

53

În continuare vom construi (şi acest lucru are loc pentru fiecare mesaj – încă suntem în structura repetitivă „for”) un textField în care vom afişa mesajul:

_root.guestbook.tabel.createTextField("txt"+i, i+10, 30, poz_curent+20, _root.maxx-80, metrics.textFieldHeight); _root.guestbook.tabel["txt"+i].multiline = true; _root.guestbook.tabel["txt"+i].wordWrap = true; _root.guestbook.tabel["txt"+i].html = true; _root.guestbook.tabel["txt"+i].selectable = false; _root.guestbook.tabel["txt"+i].htmlText = mesaj_din_xml; _root.guestbook.tabel["txt"+i].setTextFormat(textformat);

Proprietatea multiline indică faptul că câmpul textual este capabil să afişeze mai multe linii, wordWrap permite obiectului de tip textField să treacă textul pe următorul rând atunci când nu mai încape pe rândul curent, proprietatea html va permite textField-ului să „proceseze” puţinele formatări HTML disponibile pentru acest obiect. De asemenea nu vom permite selectarea textului, vom atribui textField-ului textul preluat din XML (care a fost anterior copiat în variabila „mesaj_din_xml”), iar în final vom formata textul conform regulilor stabilite la începutul documentului.

Într-un mod aproape similar vom adăuga (pe bara construită pentru fiecare mesaj) numele celui ce a introdus mesajul şi data la care a fost introdus:

_root.guestbook.tabel.createTextField("txt_nume"+i, i+10010, 30, poz_curent+1, 300, 25); _root.guestbook.tabel.createTextField("txt_data"+i, i+20010, 30, poz_curent+1, 300, 25); _root.guestbook.tabel["txt_data"+i]._x = _root.maxx-90- textformat_data.getTextExtent(data_din_xml). textFieldWidth; _root.guestbook.tabel["txt_data"+i].text = data_din_xml; _root.guestbook.tabel["txt_data"+i]. setTextFormat(textformat_data); _root.guestbook.tabel["txt_data"+i].selectable = false; _root.guestbook.tabel["txt_nume"+i].selectable = false; _root.guestbook.tabel["txt_nume"+i].text = nume_din_xml; _root.guestbook.tabel["txt_nume"+i]. setTextFormat(textformat_nume);

În cazul în care adresa de mail şi cea pentru pagina web sunt introduse vom adăuga fiecărui mesaj câte o pictogramă reprezentând legătura ătre acestea:

Page 56: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

54

if ((mail_din_xml.length>5)&&(mail_din_xml.indexOf("@">0))) { _root.guestbook.tabel.attachMovie("pictograma_mail", "plic"+i, i+30010); _root.guestbook.tabel["plic"+i]._y = poz_curent+4; _root.guestbook.tabel["plic"+i]._x = _root.maxx-85; _root.guestbook.tabel["plic"+i].mail = mail_din_xml; _root.guestbook.tabel["plic"+i].onPress = function() { getURL("mailto:"+mail_din_xml); }; } if (web_din_xml.length>10) { _root.guestbook.tabel.attachMovie("pictograma_web", "webpage"+i, i+40010); _root.guestbook.tabel["webpage"+i]._y = poz_curent+4; _root.guestbook.tabel["webpage"+i]._x = _root.maxx-65; _root.guestbook.tabel["webpage"+i].web = web_din_xml; _root.guestbook.tabel["webpage"+i].onPress = function() { getURL(web_din_xml, "_blank"); }; }

În această porţiune de cod ne folosim de obiectele din bibliotecă cu numele de legătură (linkage) pictograma_mail respectiv pictograma_web. Acestea au fost construite la începutul exerciţiului. În cazul în care poziţionarea pictogramelor nu este corectă (ar trebui să apară în partea dreaptă a barei pe care este afişat numele respectiv data) atunci puteţi modifica paramterii _x, _y (adăugând sau scăzând o constantă) pentru a le deplasa în poziţia dorită.

În finalul buclei nu vom uita să incrementăm valoarea poziţiei curente – altfel toate mesajele vor apărea suprapuse:

poz_curent += metrics.textFieldHeight+30; } // această paranteză termină “for”-ul

Am construit MovieClip-ul tabel. El are rolul de a afişa mesajele şi precum am zis, în cazul în care acestea sunt mai multe decât încăpea în ecran va trebui să avem posibilitatea de a deplasa în sus sau jos acest tabel. Pentru aceasta avem nevoie – evident – de o bară de scroll. Bara de scroll va fi construită atunci când vom apela următoarea funcţie (care apare încă în interiorul eventimentului onLoad asociat încărcării XMLului):

Page 57: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

55

function create_scroll_bar(lungime_tabel) { _root.guestbook.createEmptyMovieClip("cursor", 1); _root.guestbook.cursor._x = _root.maxx-30; _root.guestbook.cursor._y = 30; _root.guestbook.cursor.attachMovie("cursor_scroll", "cursor_scroll", 2); _root.guestbook.cursor.onPress = function() { _root.onMouseMove = function() { _root.guestbook.tabel._y = -(_root.guestbook.cursor._y-30)*(lungime_tabel- _root.maxy+50)/(_root.maxy-60); updateAfterEvent(); }; this.startDrag(false, _root.maxx-30, 30, _root.maxx-30, _root.maxy-30); }; _root.guestbook.cursor.onRelease = function() { this.onMouseMove = null; this.stopDrag(); }; _root.guestbook.cursor.onRollOut = function() { this.onMouseMove = null; this.stopDrag(); }; _root.guestbook.cursor.onReleaseOutside = function(){ this.onMouseMove = null; this.stopDrag(); }; }

Funcţia de mai sus are ca parametru de intrare dimensiunea MovieClip-ului „tabel” (de fapt atributul _height al acestui MovieClip). După crearea unui MovieClip intitulat „cursor” – de care vom „apuca” cu mouseul atunci când vrem să deplasăm tabelul respectiv poziţionarea lui în partea dreaptă a guestbook-ului, îi ataşăm imaginea din bibliotecă care are ca linkage id-ul „cursor_scroll” (element grafic construit sau adăugat odată cu pictogramele pentru mail şi web). În continuare vom construi permite acestui cursor sa fie „apucat” şi mutat – lucru destul de facil care seamănă cu metoda de ataşare a unui pointer nou mouse-ului (tutorial precedent). În acelaşi timp cu repoziţionarea cursorului de scroll, de fiecare dată se recalculează poziţia pe axa y a MovieClip-ului „tabel” folosind regula de trei simpla.

Duncţia de mai sus va fi apelată doar dacă dimensiunea tabelului depăşeşte dimensiunea scenei:

Page 58: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

56

if (_root.guestbook.tabel._height>_root.maxy-50) { create_scroll_bar(_root.guestbook.tabel._height); }

În finalul funcţiei ce tratează eventimentul „onLoad” pentru XML trebuie să construim o mască (pentru ca Movie-Clip-ul „tabel” să nu atingă marginile superioară/inferioară a scenei):

_root.guestbook.createEmptyMovieClip("masca", -100); _root.guestbook.masca.lineStyle(1); _root.guestbook.masca.beginFill(1, 100); _root.guestbook.masca.moveTo(25, 30); _root.guestbook.masca.lineTo(_root.maxx-50, 30); _root.guestbook.masca.lineTo(_root.maxx-50, _root.maxy-20); _root.guestbook.masca.lineTo(25, _root.maxy-20); _root.guestbook.masca.lineTo(25, 30); _root.guestbook.tabel.setMask(_root.guestbook.masca); }; // finalul funcţiei “onLoad” _root.mesaje.load("mesaje.xml?NoCache="+(new Date().getTime())");

Ultima linie trimite o cerere către server pentru a descărca obiectul XML conţinut în „mesaje.xml”. Ceea ce urmaează după numele fişierului nu este altceva decât o metodă de a convinge browserul să nu furnizeze fişierul „mesaje.xml” din memoria chache ci să ceară din nou serverului acest fişier.

Credeaţi că dacă aţi afişat mesajele aţi scăpat ? Nici vorbă ! Mai trebuie să construiţi un modul prin intermediul căruia să adăugaţi un mesaj nou. Acest lucru deşi nu este foarte complicat este important pentru că aici „se observă” cel mai bine modul în care comunică Flash-ul cu PHP-ul. Vom construi pentru început (din script) un buton care va avea rolul de a ascunde MovieClip-ul „guestbook” – adică toate mesajele şi va afişa altul „mesaj_nou” care va conţine câteva câmpuri: nume, mesaj, adresa de e-mail respectiv adresa web. Să construim butonul:

_root.createEmptyMovieClip("buton_introdu_date", 1); _root.buton_introdu_date.onRelease = function() { _root.buton_introdu_date._visible = false; _root.guestbook._visible = false; _root.mesaj_nou._visible = true; }; with (_root.buton_introdu_date) { lineStyle(1,0xffffff,50);

Page 59: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

57

beginFill(0xffffff, 40); moveTo(0, 0); lineTo(85, 0); lineTo(85, 15); lineTo(0, 15); lineTo(0, 0);

t _x=_root.maxx-_wid h-50;

_text",0,0,0,100,18);

_y=10; ield createTextF

createTextField("btn btn_text.text="Adaugă mesaj"

mat_nume); btn_text.setTextFormat(textfor}

Am adăugat un nouMovieClip în rădăcină („buton_introdu_date”) şi i-am

aceasta şi di

ataşat funcţia onRelease (ce va fi executată îm momentul apăsării butonului). În această funcţie vom ascunde butonul, guestbook-ul şi vom afişa MovieClip-ul „mesaj_nou”. Desenarea efectivă a butonului nu ridică o problemă, gruparea „with” indică faptul că următoarele comenzi sunt asociate MovieClip-ului _root.buton_introdu_date.

Afişarea conţinutului XMLului este partea cea mai anevoioasa,n cauză că fiecare mesaj are o dimensiune proprie şi backgroundul

pentru fiecare dintre mesaje se intainde sub tot mesajul. Partea de introducere a datelor, însă, este statică şi va conţine mereu aceleaşi câmpuri (care trebuie să fie completate de utilizator). Din acest motiv vom crea această porţiune din guestbook folosindu-ne doar de instrumentele (Tools – bara din dreapta a Flash-ului) disponibile în Flash. Iniţial creaţi un dreptunghi destul de mare în care să încapă cele patru câmpuri textuale şi convertiţi-l în MovieClip. Daţi noului MovieClip numele de instanţă „mesaj_nou”. El va fi afişat în momentul în care veţi apăsa butonul de introducere a detalor. În acest MovieClip construiţi patru câmpuri textuale statice – ele vor reprezenta etichetele: „Nume:”, „Mail:”, „Web:”, „Mesaj:”. Creaţi încă patru câmpuri dar de această dată de tip input, setaţi-le afişarea border-ului (din fereastra de proprietăţi) şi numele de variabilă ce identifică fiecare câmp. Mai rămâne să creaţi trei butoane cu etichetele „Trimite”, „Anulează” şi „Resetează”. În final, MovieClip-ul ar trebui să semene cu cel din imaginea următoare:

Page 60: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

Figura 3-5 – Formularul de trimitere a datelor; în partea dreapta sunt variabilele

asociate câmpurilor de tip input

Mai rămâne să ataşaţi fiecărui buton câte un script (acest lucru il realizaţi efectuând click pe buton şi completând în fereastra „Actions”).

Butonului „Trimite” îi veţi ataşa un script care trimite variabilele din câmpurile textuale către server:

on (release) { loadVariables ("adauga.php",this,"POST"); }

Comanda loadVariables are un rol dublu: pe de o parte transmite toate variabilele din MovieClip-ul curent – cel în care este situat butonul – către fişierul PHP şi în acelaşi timp încarcă variabila „mesaj_eroare” generată de către scriptul PHP. Multe persoane trec cu vederea această comandă şi nu îşi dau seama că aceasta este de fapt baza comunicării între Flash şi PHP (şi dacă ţinem cont că în ziua de azi nu putem fără să comunicăm într-un fel cu serverul vă veţi da seama de importanţa acestei comenzi). Aşadar variabilele care sunt transmise fac parte din MovieClip-ul identificat prin „this” – adică MovieCLip-ul curent, datele sunt trimise la „adauga.php” şi metoda de transmitere este „POST” – orice formular web are nevoie de o metodă de transmitere (GET este cealaltă metodă dar care este folosită de obicei pentru a cere ceva de la server nu pentru a modifica starea serverului – noi vrem să completăm un XML deci vom folosi POST).

58

Page 61: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

59

Butonului „Anulează” îi veţi ataşa un script care vă va returna la mesajele guestbook-ului:

on (release) { this._visible = false; _root.guestbook._visible = true; _root.buton_introdu_date._visible = true; }

Butonul „Resetează” are rolul de a şterge toate câmpurile formularului pentru a fi re-completate:

on (release) { this.nume = ""; this.mail = ""; this.web = ""; this.mesaj = ""; }

În plus, revenind la scena principală, veţi ataşa MovieClip-ului „mesaj_nou” următorul cod (ataşarea codului se face identic – selectare şi scrierea codului în fereastra „Actions”):

onClipEvent (data) { if (this.mesaj_eroare == "OK") { this._visible = false; _root.guestbook._visible = true; _root.buton_introdu_date._visible = true; _root.mesaje.load("mesaje.xml?NoCache="+(new Date().getTime())); } } onClipEvent (load) { this._visible = false; }

La începutul acestui exemplu am convenit ca în cadrul PHP-ului să fixăm numele, mailul, pagina web şi mesajul transmis. Pnetru ca informaţiile să fie primite corect de la Flash ar trebui să înlocuim următoarele linii din codul PHP:

$nume = "Marian"; $msg = "Mesaj de adaugat guestbookului"; $mail = "[email protected]"; $web = "http://www.marian.ro";

După modificare, liniile vor arăta astfel:

Page 62: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

60

$nume=$_POST['nume']; $msg=$_POST['mesaj']; $mail=$_POST['mail']; $web=$_POST['web'];

Adică valorile variabilelor nu sunt fixate ci sunt primite prin metoda POST.

Atenţie! În cazul în care datele ajung pe server (acesta salvează datele) dar guestbook-ul nu se întoarce la pagina principală de afişare a mesajelor (după ce aţi apăsat butonul „Trimite”) eroarea cea mai des întâlnită este lăsarea câtorva spaţii albe după scriptul PHP din fişierul „adauga.php”. (De exemplu dacă după terminarea php-ului mai aveţi două spaţii mesajul de eroare nu va fi „OK” ci „OK ” şi condiţia de returnare la pagina ce afişează mesajele nu va fi satisfăcută). Deşi există şi alte mesaje de eroare acestea nu au fost tratate – vom lăsa această parte ca exerciţiu pentru dumneavoastră (nu aveţi decât de completat ramura „else” a condiţiei „if (this.mesaj_eroare == "OK") ”.

3.3 Album foto – foto SlideShow

Dificultate: 6;

Vom încerca să construim două tipuri de albume fotografice.

În primul exemplu, imaginile vor fi de dimensiuni diferite, vor fi încadrate de un chenar care se va redimensiona la încărcarea fiecărei noi imagini. Imaginile vor fi numerotate (0.jpg, 1.jpg …) pentru o încărcare consecutivă (în exemplul următor imaginile nu trebuie să fie neapărat cu aceste denumiri). După încărcarea în întregime a unei imagini, se vor găsi dimensiunile fotografiei, se va şterge vechea imagine, se va redimensiona chenarul după care va fi afişată noua fotografie.

Vom schimba proprietăţile documentului pentru a avea dimensiunile 800x500 şi o viteză de afişare de 30 de cadre pe secundă (în cazul în care imaginea este mai mare de 800x500 puteţi să realizaţi şi o scalare a acesteia).

Page 63: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

61

În timpul încărcării unei imagini, imaginea precedentă trebuie să fie afişată. Din acest motiv nu trebuie să încărcăm imaginea nouă în acelaşi MovieClip ca şi precedenta – ne vom folosi de două clipuri „m0” şi „m1”.

Chenarul va fi simulat de un dreptunghi ce va fi desenat folosind instrumentele Flash-ului şi care apoi va fi convertit într-un MovieClip cu numele de instanţă „cadru” şi cu punctul de înregistrare în centru. Când construiţi dreptunghiul (a cărui dimensiuni iniţiale nu contează) aveţi grijă ca marginea (conturul) desenului să fie setată ca „hairline” (opţiune disponibilă din fereastra de proprietăţi imediat după selectarea instrumentului recangle). Cu ajutorul ferestrei „Align” (CTRL+K) poziţionaţi dreptunghiul în centrul scenei: apăsaţi butonul „To stage” din dreapta după care apăsaţi al doilea buton de pe primele două rânduri (evident obiectul în formă de dreptunghi trebuie să fie selectat).

La încărcarea unei imagini ne vom folosi de un preloader pentru a comunica vizitatorului cât mai are de aşteptat până la încărcarea următoarei imagini. Din acest motiv vom importa în scriptul nostru clasa grafix.as care are o funcţie ce desenează o bară de progres. Vom face pentru început câteva setări cum ar fi dimensiunile fictive ale unei imagini, numărul imaginii curent afişate precum şi în ce MovieClip (m0 sau m1) este afişată (iniţial nu avem nici o imagine încărcată dar vom face aceste setări – oarecum artificiale – pentru a avea o continuitate în încărcările imaginilor).

#include "grafix.as" lung = 0; inalt = 0; img_nr = 1; nr_mc = 1; contor = 0;

Cu funcţiile ce vor afişa bara de progres deja v-aţi obişnuit din excerciţiul cu preloaderul ce putea găsi apariţia unei erori:

var un_obiect:Object = new Object(); un_obiect.onLoadStart = function():Void { _root.createEmptyMovieClip("bara_progres", 10000); }; un_obiect.onLoadProgress = function(destinatie:MovieClip, bytesLoaded:Number, bytesTotal:Number):Void {

Page 64: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

62

_root.bara_progres.desenaza_bara_progres(200, 490, 400, 7, bytesLoaded, bytesTotal); }; un_obiect.onLoadComplete = function():Void { _root.bara_progres.unloadMovie(); };

De această dată vom mai adăuga (sau completa funcţiile explicate acolo) cu următoarele:

un_obiect.onLoadInit = function(destinatie:MovieClip):Void { _root.contor = 0; _root.lung = destinatie._width; _root.inalt = destinatie._height; _root.m1._alpha = 0; _root.m0._alpha = 0; _root["m"+nr_mc]._x = (800-lung)/2; _root["m"+nr_mc]._y = (500-inalt)/2; }; un_obiect.onLoadError = function(destinatie:MovieClip, httpStatus:Number):Void { _root.img_nr++; _root.img_nr %= 7; _root.monitor.loadClip(_root.img_nr+".jpg", "_root.m"+_root.nr_mc); _root.contor = -1; _root.bara_progres.unloadMovie(); };

Prima funcţie se va executa imediat după încărcarea completă, mai exact atunci când clip-ul va fi iniţializat (adică imaginea va fi efectiv încărcată în MovieClip-ul în care s-a dat comanda de încărcare). În această funcţie vom reiniţializa un contor care are rolul de a cronometra timpul pentru care imaginea a stat în scenă – după un timp vom încărca următoarea imagine, vom reface variabilele ce reprezintă lungimea şi înălţimea imaginii încărcate pentru a putea redimensiona dreptunghiul care joacă rol de chenar; ambele MovieClip-uri vor avea factorul de opacitate setat la 0 (complet transparente) şi va fi repoziţionată imaginea nou încărcată pentru a fi în centrul scenei (deşi invizibilă).

În cazul întâlnirii unei erori (eveniment captat prin intermediul funcţiei onLoadError), vom încerca să încărcăm următoarea imagine. Împărţirea modulo 7 efectuată imediat după încrementarea numărului imaginii are

Page 65: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

63

rolul de a cicla cele 7 imagini de tip jpg numerotate de la 0 la 6. În momentul iniţializării unei noi încărcări, contorul este setat la o valoare foarte mică pentru a împiedica încărcarea altei imagini (am văzut că atunci când imaginea este încărcată complet, contorul este resetat la 0; de fapt de fiecare dată când acest contor va depăşi valoarea 200 se va începe încărcarea unei noi imagini; nu vrem să începem încărcarea unei imagini în timpul încărcării precedentei şi din acest motiv iniţializăm contorul cu un număr negativ şi-l vom incrementa doar dacă este 0 sau mai mare).

În continuare vom crea cele două MovieClip-uri şi vom începe încărcarea primei imagini (din ce motiv construim un obiect de tip MovieClipLoader şi cum îl folosim nu mai explicăm deoarece acest subiect a fost deja atins la un exerciţiu anterior):

var monitor:MovieClipLoader = new MovieClipLoader(); monitor.addListener(un_obiect); _root.createEmptyMovieClip("m0", 0); _root.createEmptyMovieClip("m1", 1); monitor.loadClip("1.jpg", "m1");

Pentru redimensionarea chenarului sau pentru afişarea progresivă (transparent spre opac) a imaginilor, trebuie să avem o funcţie care să se repete încontinuu. _root.onEnterFrame este exact ceea ce avem nevoie:

_root.onEnterFrame = function() { if (_root.contor>=0) { _root.contor++; } if (_root.contor>200) { _root.img_nr++; _root.img_nr %= 7; _root.nr_mc++; _root.nr_mc %= 2; _root.monitor.loadClip(_root.img_nr+".jpg", "_root.m"+_root.nr_mc); _root.contor = -1; } _root.cadru._height = _root.cadru._height- (_root.cadru._height-_root.inalt-5)/9; _root.cadru._width = _root.cadru._width- (_root.cadru._width-_root.lung-5)/9; if (Math.abs(_root.cadru._width-_root.lung)<10) { _root["m"+nr_mc]._alpha += 4; } };

Page 66: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

64

Aşa cum am promis vom incrementa contorul doar dacă acesta este pozitiv, dacă depăşeşte valoarea 200 vom trece la următoarea imagine, vom schimba MovieClip-ul în care încărcăm imaginea, vom porni încărcarea imaginii noi, vom seta contorul la -1 (din acelaşi motiv ca şi prima dată).

În continuare în mod continuu (deşi nu neapărat necesar) vom modifica dimensiunea chenarului pentru a fi cu două unităţi mai mare decât imaginea încărcată (valoarea -5 lasă două unităţi în stânga şi două în dreapta). Dacă dimensiunea chenarului este aproape de cea dorită începem să creştem gradul de opacitate al MovieClip-ului pentru a face vizibilă imaginea.

Testaţi exemplul apăsând de două ori CTRL+Enter (pentru a observa şi preloaderul). Acest exemplu a fost realizat pentru 7 imagini: de la 0.jpg până la 6.jpg. Ce se întâmplă dacă una din cele 7 imagini lipseşte ? Va mai funcţiona corect exemplul ? (încercaţi să răspundeţi înainte de a şterge una din imagini). Din ce motiv atunci când expiră contorul schimbăm şi MovieClip-ul în care încărcăm următoarea imagine dar nu facem acest lucru şi atunci când se produce o eroare (atunci schimbam doar imaginea ce trebuie încărcată) ?

Ca exerciţiu încercaţi să realizaţi acelaşi exemplu fără a desena chenarul folosind instrumentele Flash-ului, adică creaţi acest chenar (împreună cu animaţia sa) numai folosind ActionScript.

Cel de-al doilea album fotografic va încărca o fotografie numai când se va face cererea de încărcare. Iniţial vizitatorului paginii i se va afişa o listă cu imaginile disponibile (în format thumb-nail9), încărcarea efectuându-se numai atunci când acesta va apăsa pe imaginea dorită. Fiecare imagine mică din listă se va încărca folosind un preloader dar nu pentru a afişa cât mai avem de aşteptat până la final ci pentru a şti momentul în care încărcarea este completă. Pentru a forma o listă vom ataşa fiecare imagine încărcată unui MovieClip pe care-l vom putea muta sub o mască. In acest fel vom afişa doar o porţiune din el. Lista va fi afişată deasupra locului în care se va încărca imaginea şi din acest motiv pozele din listă vor fi afişate pe orizontală.

9 Thumb-nail înseamnă de dimensiunea unei unghii – dimensiunea mică a imaginii va ermite încărcarea fiecărei imagini din listă foarte rapid.

Page 67: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

65

Pentru fiecare imagine folosită trebuie să avem stocate (pe server) două imagini: una mică (imaginea ce se va încărca iniţial în listă) şi un a mare (imaginea care se va încărca atunci când imaginea mică va fi apăsată).

Numele fişierelor nu vor mai fi sub formă de numere (de fapt prima metodă era una destul de artificială), ele vor fi încărcate dintr-un fişier XML ce conţine numele tuturor imaginilor.

Fişierul XML conţine doar date structurate. Un fişier în format XML care va indica Flash-ului că are de afişat 3 imagini în format JPG va avea următoarea structură (imagini.xml):

<?xml version="1.0" ?> <imagini> <img fisier="gradina.jpg" descriere="Gradina din spatele casei" data="10.02.2006" /> <img fisier="apa_curgatoare.jpg" descriere="Bistrita iarna" data="01.02.2006" /> <img fisier="pisica.jpg" descriere="Persana" data="15.07.2004" /> </imagini>

Fiecare imagine este identificată printr-un nouă intrare de tip img. Singura informaţie disponibilă (pentru început) pentru fiecare imagine este numele fişierului ce va fi încărcat.

Scrieţi un fişier XML cu un conţinut asemănător cu cel dat mai sus particularizat pentru imaginile pe care doriţi să le folosiţi. Denumiti acest fişier „imagini.xml”. În directorul în care este situat acest fişier veţi salva şi proiectul flash. În plus, în acelaşi director, veţi adăuga un director „foto” în care veţi pune toate imaginile ce au fost trecute în XMLul construit.

Acest exemplu va fi folosit în crearea paginii personale de web în care toate filmele Flash ce vor fi încărcate la un moment dat ar fi bine să aibă o aceeaşi dimensiune. Deoarece dimensiunea scenei pentru majoritatea aplicaţiilor realizate era de 640x480 şi pentru că vom dori să includem şi această aplicaţie în pagina noastră, dimensiunea scenei va fi setată tot la această rezoluţie. Pozele care se vor încărca nu trebuie să fie de dimensiuni foarte mari, personal în pagina web nu pun imagini cu rezoluţie mai mare de 320x240. Pentru fiecare imagine cu rezoluţia 320x240 veţi avea nevoie de incă una cu dimensiunea 96x72 (poza redimensionată). Numele imaginii mici va fi acelaşi cu numele imaginii mari dar va avea prefixul „mic_” (De exemplu, imaginea mică pentru „gradina.jpg” se va numi

Page 68: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

66

„mic_gradina.jpg”). Imaginile mici vor fi puse în acelaşi director cu cele mari.

Scriptul va fi aşezat în totalitate în primul cadrul al al timeline-ului. Pentru început va trebui să definim un obicet XML şi să încărcăm lista imaginilor.

Deocamdata vom vedea o eventuală problemă şi cum ar putea fi evitată: după ce vom termina de încărcat fişierul XML în Flash, îl vom procesa şi vom începe încărcarea fişierelor (mici) de pe server pentru a construi lista cu fişierele disponibile. Pentru fiecare imagine mică vom avea nevoie de câte un MovieClip nou şi pentru fiecare MovieClip nou va trebui să executăm comanda loadMovie pentru a încărca imaginea externă. Dacă sunt puţine imagini, nu există nici o problemă dar în cazul în care avem un număr mare de imagini, acestea îşi vor începe încărcarea aproape toate simultan şi se vor „îngreuna” una pe celaltă (de fapt probabil cu toţii aţi observat că atunci când încercaţi sa copiaţi mai multe fişiere de pe o partiţie pe alta este mai avantajos să le copiaţi pe rând decât simultan). Pentru început vom scrie scriptul care va încărca toate imaginile (mici) simultan (desi gresit, el are o anumită importanţă în observarea funcţionării şi poate fi completat cu uşurinţă pentru a fi schimbat în versiunea corectă):

var imagini = new XML(); imagini.ignoreWhite = true; imagini.onLoad = function() { _root.nr_max_img = _root.imagini.firstChild.childNodes.length; trace("numarul de poze:"+_root.nr_max_img); _root.createEmptyMovieClip("lista_imagini", 0); for (i=0; i<_root.nr_max_img; i++) { _root.lista_imagini.createEmptyMovieClip("img"+i, i); _root.lista_imagini["img"+i].loadMovie ("foto/mic_"+_root.imagini.firstChild. childNodes[i].attributes.fisier); } }; imagini.load("imagini.xml");

Scriptul funcţionează în felul următor: crează un obiect XML, ignoră spaţiile albe (am amintit într-un capitol anterior că acestea împiedică buna procesare a documentului XML), este creată funcţia ce se va executa în momentul încărcării XMLului (onLoad) şi se porneşte încărcarea XML-ului „imagini.xml” ce conţine lista fişierelor. Câteva comentarii asupra funcţiei onLoad: după încărcarea XML-ului memorăm numărul de poze în variabila

Page 69: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

_root.nr_max_img şi afişăm acest număr de poze prin intermediul comenzii trace (aceasta este mai mult o verificare că XMLul s-a încărcat corect). În continuare vom crea un MovieClip cu numele de instanţă „lista_imagini” în care se vor încărca pe rând imaginile desemnate de XML, fiecare în propriul MovieClip. Astfel, pentru fiecare imagine (for-ul de fapt merge de la valoarea 0 până la numărul maxim de imagini deci vom putea prelua pe rând imaginile) vom crea câte un MovieClip nu numele de instanţă „img”+i (de fapt vom avea img0, img1, img2,....) şi fiecărei instanţe îi vom permite încărcarea prin intermediul loadMovie a imaginii asociate.

Problema care apare cu scenariul acesta este încărcarea simultană a mai multor fişiere (acest fapt este rezultatul executării foarte rapide a buclei „for”). În final, dacă în faza de test veţi selecta „Bandwith Profiler” din meniul „View” şi veţi apăsa de două ori CTRL+Enter (reamintesc că acest lucru simulează încărcarea pentru un anumit tip de bandă) veţi avea un rezultat ca în imaginea alăturată.

Aşa cum am zis, încărcarea de acest tip constituie o problemă atunci când numărul fişierelor este mare. În acest caz, pentru a evita „aglomerarea” ar trebui să nu permitem Flash-ului să încarce altă imagine decât dacă cea anterioară a fost încărcată cu succes (sau dacă imaginea nu se găseşte pe server.

Pentru a determina momentul încărcării complete a unei imagini vom apela la un „listener” asemănător cu cel făcut în cadrul preloaderelor dar de această dată nu va avea nevoie de desenarea unei bare de progres ci doar de tratarea evenimentelor onLoadComplete şi eventual a lui onLoadError (pentru a putea trece la următoarea imagine ce trebuie încărcată dacă cea curentă nu a fost găsită pe server).

67

Page 70: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

68

În scriptul ce va încarca imaginile prin intermediul listenerului trebuie să avem grijă ca dacă imaginea nu este găsită pe server (sau apare o eroare de încărcare) să nu creăm un nou MovieClip pentru încărcarea imaginii următoare (de fapt o altă soluţie ar putea fi ca în tratarea evenimentului onLoadError să distrugem MovieClip-up ce a cauzat eroarea). Din acest motiv vom folosi două contoare, unul pentru a reţine la al câtelea MovieClip am ajuns (variabila i) şi al doilea pentru a şi care este imaginea ce va fi încărcată (variabila j).

Un alt aspect este modul în care încărcăm imaginile. În cadrul funcţiei _root.OnEnterFrame vom testa în mod continuu dacă putem încărca o următoare imagine (prin testarea unei variabile care va avea valoarea false pe durata încărcării unei imagini) şi numai în cazul în care aceasta este adevărată (se va face true doar la apariţia evenimentului onLoadComplete) înseamnă că momentan nu se încarcă nimic şi vom putea încărca următoarea imagine.

Scriptul este următorul:

var imagini = new XML(); imagini.ignoreWhite = true; imagini.onLoad = function() { // cream un listener: var un_obiect:Object = new Object(); un_obiect.onLoadComplete = function():Void { _root.lista_imagini["img"+mc_curent].nr_imagine = img_curent; _root.poti_incarca_urmatoarea = true; }; un_obiect.onLoadError = function(destinatie:MovieClip, httpStatus:Number):Void { _root.poti_incarca_urmatoarea = true; _root.eroare_de_incarcare = true; }; var monitor:MovieClipLoader = new MovieClipLoader(); monitor.addListener(un_obiect); // am terminat de creat listenerul _root.nr_max_img = _root.imagini.firstChild.childNodes.length; trace("numarul de poze:"+_root.nr_max_img); _root.createEmptyMovieClip("lista_imagini", 0); _root.poti_incarca_urmatoarea = true; _root.eroare_de_incarcare = false; i = 0; j = 0;

Page 71: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

69

_root.onEnterFrame = function() { if ((_root.poti_incarca_urmatoarea) && (j<_root.nr_max_img)) { _root.poti_incarca_urmatoarea = false; if (!_root.eroare_de_incarcare) { _root.lista_imagini.createEmptyMovieClip ("img"+i, i); } else { i--; _root.eroare_de_incarcare = false; } _root.lista_imagini["img"+i]._x = i*100; _root.mc_curent = i; _root.img_curent = j; monitor.loadClip("foto/mic_"+_root.imagini. firstChild.childNodes[j].attributes.fisier, _root.lista_imagini["img"+i]); i++; j++; } if((j==_root.nr_max_img)&& (_root.poti_incarca_urmatoarea)){ nr_total_mc = i; for (i=0; i<nr_total_mc; i++) { _root.lista_imagini["img"+i].onPress = function() { incarca_imagine_mare("foto/"+_root.imagini. firstChild.childNodes[this.nr_imagine]. attributes.fisier); }; } _root.onEnterFrame = null; } }; }; imagini.load("imagini.xml");

Page 72: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

Diferenţele sunt esenţiale faţa de primul script şi adăugarea listenerului împreună cu variabila ce blochează încărcarea urămtoarei imagini fac ca încărcarea să fie una secvenţială. La un moment dat din timpul încărcării, dacă vom vizualiza Bandwidth Profiler-ul aşa cum am procedat la primul script vom vedea că în acel moment se încărcă o singură imagine (vezi imaginea alăturată).

În acest cod am adăugat crearea listenerului în care tratăm încărcarea completă a imaginii şi evenimentul apariţiei unei erori. De ambele dăţi am dat variabilei _root.poti_incarca_urmatoarea valoarea de de adevăr adevărat. În plus în cazul apariţiei unei erori este setată o variabilă care indică acest lucru. În cazul funcţiei onLoadComplete vom memora imaginea în fiecare MovieClip numărul imaginii care s-a încărcat cu succes (fiecare MovieClip va conţine imaginea dată de nr_imagine – necesar pentru a „şti” ce să încărcăm când acel MovieClip va fi apăsat).

Funcţia _root.onEnterFrame verifică în mod continuu dacă mai putem încărca o nouă imagine (prin testarea variabilelor poti incarca urmatoarea respectiv a variabilei j. În cazul în care este merisă o nouă încărcare, variabila poti_incarca_urmatoarea este setată ca falsă (pentru a nu se realiza încă o încărcare simultană cu cea curentă), vom testa dacă este cazul creării unui nou MovieClip sau dacă îl vom folosi pe vechiul MovieClip creat dar a cărui poză nu a putut fi încărcată ( fapt realizat prin condiţia if(!_root.eroare_de_incarcare)). Vom seta poziţia în care va fi aşezat noulMovieClip, vom seta câteva variabile globale necesare la asocierea MovieClip-imagine iar în final pornim încărcarea noii imagini şi incrementăm cele două contoare pentru a ne pregăti de o nouă încărcare. Ultima construcţie de tip if are rolul de a asocia fiecărui MovieClip evenimentul apăsării sale (de fapt apelul funcţiei incarca_imagine_mare ce are ca parametru calea spre imaginea mare şi va definită în continuare) şi de a elimina din memorie funcţiea _root.onEnterFrame.

Încărcarea imaginii mari poate fi realizată (ţinând cont că are dimensiunea mai mare decât cea a thumbnail) prin intermediul unui obiect de tip MovieClipLoader care să asocieze şi o bară de progres imaginii ce se

70

Page 73: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

71

încarcă. Toate liniile următoare vor fi scrise la finalul scriptului (imediat după comanda de încărcare a XMLului). Deoarece am facut un preloader într-un exerciţiu anterior, vom folosi acelaşi script:

#include "grafix.as" var un_obiect:Object = new Object(); un_obiect.onLoadStart = function():Void { _root.createEmptyMovieClip("bara_progres", 10000); }; un_obiect.onLoadProgress = function(destinatie:MovieClip, bytesLoaded:Number, bytesTotal:Number):Void { _root.bara_progres.desenaza_bara_progres(50, 440, 540, 7, bytesLoaded, bytesTotal); }; un_obiect.onLoadComplete = function():Void { _root.bara_progres.unloadMovie(); }; un_obiect.onLoadError = function(destinatie:MovieClip, httpStatus:Number):Void { trace("Eroare: "+httpStatus); _root.bara_progres.unloadMovie(); }; var monitor:MovieClipLoader = new MovieClipLoader(); monitor.addListener(un_obiect); _root.createEmptyMovieClip("sevalet",1); _root.sevalet._x=160; //customizat pentru imagini 320x240 _root.sevalet._y=120; //customizat pentru imagini 320x240

În cadrul acestui script am folosit funcţia deseneaza_bara_progres care ar trebui să fie definită în cadrul fişierului „grafix.as”, motiv pentru care şi acesta a fost inclus. Sevalet este locul în care vom încărca imaginea mare. Realizăm această încărcare prin intermediul funcţiei incarca_imagine_mare plasată la finalul scriptului:

function incarca_imagine_mare(cale) { monitor.loadClip(cale,_root.sevalet); }

Apăsaţi de două ori CTRL+Enter pentru a vizualiza modul de încărcare pentru o bandă redusă.

Deşi este aproape complet, exemplul nu este încă „folosibil” pentru un număr mare de imagini deoarece nu putem vizualiza toate imaginile mici în acelaşi timp. Ar trebui să „inventăm” o metodă de a muta toate imaginile mici mai în dreapta sau mai în stânga. Vom muta MovieClip-ul „lista_imagini” în care se află de fapt toate imaginile mici (de fapt aici se

Page 74: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

72

vede scopul acestui MovieClip – nu va trebui să mutăm individual fiecare MovieClip ce conţine câte o imagine mică ci le vom muta pe toate simultan). Mutarea lui „lista_imagini” va fi realizată în funcţie de poziţia mouseului. Dacă acesta se va afla în dreapta scenei vom muta lista_imagini înspre stânga cu o viteză direct proporţională cu distanţa dintre cursor şi centrul scenei.

_root.createEmptyMovieClip("misca_lista", -1); _root.misca_lista.onEnterFrame = function() { _root.lista_imagini._x -= (_root._xmouse-320)/40; if (_root.lista_imagini._x>0) { _root.lista_imagini._x = 0; } if (_root.lista_imagini._x+ _root.lista_imagini._width<640) { _root.lista_imagini._x=640-_root.lista_imagini._width; } };

Partea cea mai grea a fost realizată. Puteţi singuri ca din interiorul XMLului să preluaţi comentariile şi data (care deşi au fost trecute, nu au fost folosite) şi să le afişaţi într-un mod plăcut odată cu încărcarea pozei mari ? Puteţi să generalizaţi acest flash pentru orice dimensiune a scenei şi orice dimensiune a imaginii ?

Încă o îmbunătăţire putem face pentru acest album fotografic: putem ca din PHP să generăm automat XMLul ce conţine numele fişierelor. Acest lucru se realizează pritr-un script destul de simplu (fisierul „imagini.php”):

<?PHP $d = dir("./foto"); while($entry=$d->read()) { $fisiere[]=$entry; } $d->close(); $nr=count($fisiere); echo "<?xml version=\"1.0\"?>\n"; echo "<imagini>\n"; for ($f=0;$f<$nr;$f++){ $lungimea_extensiei=strlen($fisiere[$f])- strpos($fisiere[$f],"."); $extensie=substr($fisiere[$f], -$lungimea_extensiei); if((($extensie==".JPG")||($extensie==".JPEG")) &&(file_exists("foto/mic_".$fisiere[$f]))){ echo " <img fisier=\"".$fisiere[$f]."\"

Page 75: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

73

descriere=\"".$fisiere[$f]."\" data=\""."none"."\" />\n"; } } echo "</imagini>"; ?>

Singura instrucţiune care trebuie modificată în Flash este locul de încărcare a XMLului: linia imagini.load("files.xml"); se va transforma în:

imagini.load("files.php");

Scriptul PHP are rolul de a prelua numele tuturor fişierelor din interiorul directorului foto, filtrează aceste fişiere – ne sunt necesare doar fişierele în format JPG care au şi o imaginie mică asociată şi pe baza acestora construieşte un XML. Astfel dacă veţi încerca să lansaţi direct imagini.php (evident rulând sub apache+php) veţi obţine o pagină cu un XML asemănător cu „imagini.xml”.

Persoanele care cunosc PHP sunt invitate să redimensioneze automat poza (să nu fie necesare pe server atât poza mare cât şi cea mică, poza mică fiind creată prin redimensionarea celei mari în momentul cererii.

3.4 Managementul fişierelor aflate pe server

Dificultate: 7

Din categoria noutăţilor aduse de Macromedia Flash 8 face parte şi o clasă nouă ce permite lucrul cu fişiere: FileReference. Această clasă dă posibilitatea obiectului Flash rulând pe maşina locală să deschidă o fereastră de tip Open sau Save în vederea selectării unui fişier sau pentru a fi salvat (sau preluat) pe server.

Partea mai uşoară este cea în care descărcăm un fişier (nu avem nevoie de un script ajutator pe serevr). Pentru a testa vom utiliza totuşi serverul apache (instalat în secţiunea în care am construit un guestbook).

În Directorul c:/apache/htdocs creaţi un director „manager” şi în acesta construiţi încă unul „fişiere”. În directorul fişiere copiaţi câteva fişiere în format jpg. (Pentru acest test eu am copiat fişierul „rasarit.jpg” în acest director.)

Page 76: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

74

Creaţi un nou document Flash şi plasaţi-l în directorul manager. În acest document adăugaţi un buton căruia ataşaţi-i scriptul :

on (release) { import flash.net.FileReference; var listener:Object = new Object(); listener.onComplete = function(file:FileReference) { trace("Am descarcat:"+file.name); }; var url:String = "http://localhost/manager/fisiere/rasarit.jpg"; var fileRef:FileReference = new FileReference(); fileRef.addListener(listener); fileRef.download(url, "soare_dimineata.jpg"); }

Acesta este scriptul cel mai simplu pentru descărcarea unui fişier (care este situat la locaţia http://localhost/manager/fisiere/rasarit.jpg. Când vom apăsa butonul descarcă, se va deschide o fereastră prin intermediul căreia putem selecta locul în care vrem să salvăm fişierul (pe calculatorul local), fişierul salvându-se (opţional) cu un nume nou soare_dimineata.jpg (în cazul în care vreţi să rămână cu numele de pe server, puteţi apela comanda download având ca parametru doar url-ul la care se află fişierul).

Vom construi un flash asemănător pentru a uploada un fişier pe server după care vom purcede la construirea unui utilitar ce realizează managementul fişierelor aflate pe un server.

Pentru a putea uploada un fişier, trebuie să „convingem” serverul să salveze fişierul trimis, deci trebuie să recurgem la un script PHP. Scriptul PHP îl veţi salva în directorul „manager” cu numele „upload.php”:

<?php move_uploaded_file($_FILES['Filedata']['tmp_name'], "./fisiere/".$_FILES['Filedata']['name']); chmod("./fisiere/".$_FILES['Filedata']['name'], 0777); ?>

Funcţia de mai sus are rolul de a scrie în directorul „fisiere” noul fişier adăugat de noi şi de a selecta drepturile pentru acest fişier (în cazul în care serverul este unul care funcţionează în linux sunt necesare aceste dretpuri pentru a-l putea utiliza în continuare).

Unui buton „încarcă” aflat într-un nou document Flash ataşaţi-i scriptul :

Page 77: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

75

on (release) { import flash.net.FileReference; var listener:Object = new Object(); listener.onSelect = function(fisier:FileReference):Void { fisier.upload("upload.php"); }; var fileRef:FileReference = new FileReference(); fileRef.addListener(listener); fileRef.browse(); }

Acest script are rolul de a crea obiectul de tip fileRef (la fel ca şi precedentul), de a-i adăuga obiectul de tip listener căruia i-am adăugat funcţia onSelect (funcţie ce va fi executată odată cu selectarea fişierului de pe calculatorul local şi care are apelează scriptul php scris mai sus pentru obiectul fişier de tip fileReference). Ultima linie a codului are rolul de a deschide fereastra necesară selectării fişierului de pe calculatorul local.

Observaţie: În versiunile de Flash 7 şi mai mici această clasă (FileReference) prin care putem referi un fişier de pe calculkatorul local nu exista. Pentru a putea face upload la un fişier trebuia să recurgem la JavaScript pentru a deschide fereastra de selectare a a fişierului şi un cod PHP puţin mai complicat decât cel oferit ca soluţie în acest subcaptiol.

În continuare vom încerca să realizăm un manager de fişiere prin intermediul căruia vom putea adăuga fişiere pe server, descărca fişiere existente, şterge fişiere de pe server, vom crea directoare respectiv vom avea posibilitatea de a le şterge. Pentru ca Flashul de la client să funcţioneze cât mai rapid, atunci când este vorba despre adăugarea unui fişier pe server, uploadarea sa nu va fi imediată – toate fişierele vor fi uploadate pe server în momentul în care va fi apăsat un buton „apply”.

Ce vom vrea să facem în continuare este să trimitem către server mai mult decât un singur fişier. Pentru aceasta va trebui să avem posibilitatea de a ţine minte mai multe obiecte de tip FileReference. Pentru aceasta ne vom folosi de obiectul FileReferenceList care pe lângă posibilitatea de reţinere a informaţiilor privitoare la mai multe fişiere, ne oferă şi o manieră elegantă de a selecta mai multe fişiere simultan (în primul exemplu puteam selecta doar câte un fişier). Uploadarea propriu-zisă va fi tot una de tipul de mai sus – fişierele vor fi uploadate secvenţial în cadrul unei structuri de tip for. De fiecare dată când facem cerere de uploadare a unui fişier pe serer trebuie să reţinem (într-un alt Array) directorul pe care îl vizualizăm în

Page 78: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

76

momentul creării cererii. Atunci când vom accesa PHPul ce mută conţinutul fişierului la o anumită locaţie, vom transmite şi locaţia folosind metoda GET (apelul va fi unul de tip upload.php?dir=nume_director).

Scriptul PHP ce va lista conţinutul unui anumit director este foarte asemănător cu cel din cadrul albumului foto (cel care ne lista imaginile disponibile în directorul imagini). Acest script va fi scris în „fisiere.php” şi va fi poziţionat în directorul „manager”:

<?PHP $dir=$_GET["dir"]; $d = dir("./fisiere/$dir/"); while($entry=$d->read()) { $fisiere[]=$entry; } $d->close(); $nr=count($fisiere); echo "<?xml version=\"1.0\"?>\n"; echo "<fisiere>\n"; for ($f=0;$f<$nr;$f++){ if (is_dir("./fisiere/".$dir."/".$fisiere[$f])) { echo " <fisier nume=\"".$fisiere[$f]."\" tip=\"dir\" />\n"; } else { echo " <fisier nume=\"".$fisiere[$f]."\" tip=\"fisier\" />\n"; } } echo "</fisiere>"; ?>

În primă fază scriptul preaia fişierele (şi directoarele) din directorul cu numele „dir” (variabilă trimsă prin metoda get). Se observă aici că neapărat primul director este „fisiere” – managerul nostru de fişiere va funcţiona numai în spatele acestui director (nu vrem să lăsăm clientul să scrie fişiere oriunde pe server). În faza a doua scriptul identifică care dintre elementele preluate simbloizează un director şi care sunt fişiere (obiectul flash va trebui să afişeze diferit directoarele de fişiere: în directoare vom putea „intra” pe când operaţiile cu fişiere pot fi descărcarea sau ştergerea). XMLul rezultat va avea următorul format:

Page 79: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

77

<?xml version="1.0"?> <fisiere> <fisier nume="." tip="dir" /> <fisier nume=".." tip="dir" /> <fisier nume="director1" tip="dir" /> <fisier nume="director2" tip="dir" /> ……………………………… <fisier nume="directorN" tip="dir" /> <fisier nume="fisier1.ext" tip="fisier" /> <fisier nume="fisier2.ext" tip="fisier" /> ………………………………… <fisier nume="fisierN.ext" tip="fisier" /> </fisiere>

După cum se observă sunt listate şi directoarele „ . ” – reprezentând directorul curent precum şi „ .. ” – reprezentând directorul părinte al directorului curent.

Construcţia Flashului (a cărei scenă va fi de 640x480 şi care va fi salvat cu numele de „manager.fla”) va începe cu adăugarea a două componente de tip „list”: din meniul Window selectaţi „Components (CTRL+F7)”. În fereastra cu compoenente, din categoria „User Interface” aduceţi în scenă două componente de tip list şi redimensionaţi-le la 250x400 (din fereastra de proprietăţi). Aranjaţi cele două componente şi daţi-le numele de instanţă „list_dir” pentru cea din stânga respectiv „list_fis” pentru componenta aflată în dreapta. Sub cele două componente adăugaţi un textfield de tip dinamic cu variabila asociată „txt”. Vom lăsa deocamdata un spaţiu liber în partea dreaptă, loc în care vom plasa ulterior câteva butoane. În primul cadru al Flash-ului vom scrie următorul script care are rolul de a procesa XMLul generat de „fisiere.php”. În timpul parsării vom adăuga în prima compoentă de tip list directoarele din directorul curent (exceptând directorul „ . ” care nu are sens să fie trecut fiind chiar directorul curent) şi în cea de-a doua componentă (list_fis) fişierele din directorul curent. Atunci când ne aflăm in directorul „fisiere” – de fapt acesta va fi rădăcina proiectului – vom omite şi afişarea directorului „ .. ” pentru a nu permite utilizatorului să navigheze pe întreg discul serverului.

Scriptul, destul de simplu, va fi adăugat primului cadru al scenei:

// directorul curent dir = ""; // obiectul de tip XML: var fisiere = new XML(); fisiere.ignoreWhite = true;

Page 80: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

78

fisiere.onLoad = function() { // pentru a uşura scrierea,vom construi // un Array cu toate elementele fis_si_dir=fisiere.firstChild.childNodes; for (i=0; i<fis_si_dir.length; i++) { // daca nu e „..” din radacina: if (!((_root.dir == "") && (fis_si_dir[i].attributes.nume == ".."))) { //nu e nici director de tip . (dir normal sau ..) if (fis_si_dir[i].attributes.tip == "dir") { if (fis_si_dir[i].attributes.nume != ".") { list_dir.addItem(fis_si_dir[i].attributes.nume); } } else { // nu e director, e fisier: adaugam in lsit_fis: list_fis.addItem(fis_si_dir[i].attributes.nume); } } } };

Aceasta este baza pentru afişarea conţinutului unui director – lucru ce se va întâmpla la încărcarea unui nou XML. Cum XMLul va fi rezultatul generării PHPului anterior şi deoarece PHPul generează mereu conţinutul directorului a carui nume este primit prin metoda GET, tot ce mai rămâne de făcut este să încărcăm primul fişier şi să găsim o metodă de a genera căile de acces spre directoarele disponibile pe server.

Calea curentă este mereu ţinută în variabila „dir”, variabilă ce este iniţializată momentan cu şirul vid indicând că ne aflăm în directorul rădăcină. Putem aşadar încărca conţintul directorului rădăcina (în cazul nostru ./manager/fisiere) prin apelul comenzii:

//comandă ce va scrisă în continuarea scriptului precedent fisiere.load("fisiere.php?dir="+dir);

Cu serverul Apache pornit deja puteţi vizualiza rezultatul muncii de până acum (apelul se realizează prin intermediul apache-ului deci va trebui să scrieţi (în browser) adresa: http://localhost/manager/manager.swf adresă ce va fi disponibilă după salvarea şi compilarea Flash-ului).

Metoda de generare a căii de acces spre un nou director este prin adăugarea la şirul de caractere „dir” a elementului selectat din lista de directoare. Trebuie să avem totuşi grijă ca în cazul selectării directorului „..” să nu adăugăm în şirul ce identifică directorul stringul „..” ci să

Page 81: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

79

eliminăm ultimul director ce se află în calea de acces. Încă un aspect ce nu trebuie neglijat este felul în care introducem caracterul „/” între două directoare. Metoda aleasă în acest exemplu este adăugarea la sfârşit a caracterului „/” şi după obţinerea căii complete eliminarea ultimului caracter. Metoda split are rolul de a pune într-un array toate directoarele din stringul dir (numai când vrem să eliminăm ultimul director). Scriptul se va scrie în continuarea celor deja existente:

// un listener: var listDirListener:Object = new Object(); // în cazul în care se dă click pe un director: listDirListener.change = function(obiect_apasat:Object) { // directorul apăsat este: apasat = obiect_apasat.target.value; // dacă nu este „..” doar adăugam la sfarsit: if (apasat != "..") { _root.dir = _root.dir+"/"+apasat; } else { // altfel eliminăm ultimul director: var directoare:Array; directoare = _root.dir.split("/"); // acum directoare conţine fiecare director pe // cate o poziţie diferită; refacem variabila dir: _root.dir = ""; for (i=0; i<directoare.length-1; i++) { _root.dir = _root.dir+directoare[i]+"/"; } _root.dir = _root.dir.substr(0, _root.dir.length-1); } // afişăm directorul curent în textfieldul cu // variabila asociata „txt”: _root.txt = "Directorul curent: "+_root.dir; // „curăţăm” cele două liste pentru o nouă încărcare: _root.list_dir.removeAll(); _root.list_fis.removeAll(); // încărcăm conţinutul directorului apăsat: fisiere.load("fisiere.php?dir="+_root.dir); }; // nu uităm să asociem listenerului obiectului list_dir: list_dir.addEventListener("change", listDirListener);

Ne-am folosit de listDirListener pentru a capta evenimentul apăsării unui nume de director (evident pentru a intra în acel director).

Selectarea fişierelor ce vor fi uploadate pe server va fi una de tip multiplu (pentru a putea trimite către server mai multe fişiere simultan).

Page 82: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

80

Din acest motiv ne-am folosit de obiectul FileReferenceList care va conţine la un moent dat o lista cu obiecte de tip FileReference. Pentru că ne-am folosit de amandouă clasele, ele vor fi importate împreună în Flash. După iniţializarea unor Array-uri vom purcede la crearea listei de fişiere ce vor fi uploadate:

// importăm cele două clase ce le vom folosi: import flash.net.FileReferenceList; import flash.net.FileReference; // construim două siruri care vor memora fisierele: var lista_fisiere:Array = Array(300); var upload_dir:Array = Array(300); var j = 0; // construim un listener (la fel ca în trimterea unui // singur fisier: var listener:Object = new Object(); // de aceasta data va trebui să procesăm o listă: listener.onSelect = function (fileRefList:FileReferenceList) { // construim lista fişierelor ce au fost selctate: lista = fileRefList.fileList; var fisier:FileReference; // şi adăugăm pe rând fişierele în lista globală: for (i=0; i<lista.length; i++) { _root.lista_fisiere[j] = lista[i]; // de fiecare dată va trebui să reţinem şi // directorul în care se va face upload: _root.upload_dir[j] = _root.dir; j++; } };

Uploadarea fişierelor este similară cu primul caz cu excepţia că de această dată se va face o trimitere secvenţială către server a fişierelor:

function uploadeaza_fisiere() { for (k=0; k<j; k++) { _root.lista_fisiere[k].upload("upload.php?dir="+_root .upload_dir[k]); } // resetam lista fisierelor: j = 0; // afisam fisierele din directorul curent dupa upload: _root.fisiere.load("fisiere.php?dir="+_root.dir); }

Page 83: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

81

După cum se observă fişierului upload.php îi este trimis folosind GET şi calea unde va trebui să pună pe server fişierul primit (cale reţinută în scriptul precedent). Totuşi să nu uităm că trebuie să modificăm şi conţinutul fişierului „upload.php” pentru a folosi această cale.

Deocamdată continuăm cu scriptul care mai trebuie să conţină liniile:

// crearea obiectului lista-de-fisiere: var fileRef:FileReferenceList = new FileReferenceList(); // şi adăugarea listenerului definit mai sus: fileRef.addListener(listener);

După selectarea fişierelor, acestea nu vor fi trimise pe server direct. Din acest motiv, pe lângă un buton de „browse” va trebui să avem şi un buton „upload”. Scriptul asociat butonului „browse” va fi:

on (release) { _root.fileRef.browse(); }

Iar cel asociat lui „upload”:

on (release) { _root.uploadeaza_fisiere(); }

Nu uităm de fişierul „upload.php”care va fi modificat astfel:

<?php // vom prelua stringul transmis prin get ce indica locul // unde vom adăuga fişierul: $dir=$_GET["dir"]; // creăm directorul în cazul în care nu există: if(!is_dir("./fisiere/$dir")) mkdir("./fisiere/$dir", 0777); // şi copiem fişierul în directorul precizat de „dir”: move_uploaded_file($_FILES['Filedata']['tmp_name'], "./fisiere/$dir/".$_FILES['Filedata']['name']); // pentru a avea acces la el, îi setăm drepturi de acces: chmod("./fisiere/".$_FILES['Filedata']['name'], 0777); ?>

Page 84: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

Figura 3-6 - Interfaţa managerului de fişiere

În cazul în care apăsăm un fişier din listă vom accesa resursa respectivă prin intermediul comenzii getURL (dacă am folosi metoda de descărcare a fişierelor, nu am putea vizualiza imaginea, pdf-ul sau alt document ce poate fi recunoscut de browser):

var listFisListener:Object = new Object(); listFisListener.change = function(obiect_apasat:Object) { apasat = obiect_apasat.target.value; var url = _root._url.substr(0, _root._url. lastIndexOf("/"))+"/fisiere"+dir+"/"+apasat; _root.txt = url; _root.getURL (url,"_blank"); }; list_fis.addEventListener("change", listFisListener);

Pentru crearea unui director nou adaugati în scenă o componentă de tip textInput, daţi-i numele de instanţă „creare_dir” după care construiţi un buton care să aibă asociat scriptul:

on (release) { // construim calea corecta: this.creare_dir = "fisiere"+_root.dir+"/"+_root.creare_dir.text; // apelăm un script PHP de pe server: loadVariables("creaza_dir.php", this, "GET");

82 // şi refacem cele două liste cu directoare/fisiere:

Page 85: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

83

_root.list_dir.removeAll(); _root.list_fis.removeAll(); _root.fisiere.load("fisiere.php?dir="+_root.dir); }

Pe server putem crea un director doar prin intermediul PHPului. În codul de mai sus necesar adăugării unui director nou celui curent, am apelat „creaza_dir.php” – fişier situat alături de toate celelate PHPuri în directorul „manager” şi care conţine următorul script:

<?PHP // preluăm numele directorului şi calea prin get: $a=$_GET["creare_dir"]; // creăm directorul dacă nu există şi setăm accesul: if(!is_dir("./$a")) mkdir("./$a", 0777); ?>

Exerciţiu: folosiţi managerul de fişiere pentru a uploada pe server imaginile necesare exemplului precedent.

Exerciţiu: Realizaţi un meniu cu câteva opţiuni disponibile atunci când executaţi clcik pe un fişier sau director (de exemplu ştergere, vizualizare, descărcare).

Exerciţiu: Adăugaţi o componentă list în care afişaţi toate fişierele ce asteapta să fie uploadate; ştergeţi lista după uploadarea fişierelor.

Exerciţiu: Daţi un spect îngrijit obiectului flash utilizînd componente de tip buton şi labeluri:

Page 86: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

Figura 3-7 – Interfaţa Flash construită numai cu componente

84

Page 87: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

85

Capitolul 6

4 Comunicarea în timp real

Jocurile sau comunicările de tip chat au nevoie de o sincronizare rapidă. Folosirea PHPului nu satisface pe deplin cerinţele unei comunicări în timp real. Câteva cuvinte despre SOCKETURI şi utlizarea lor în două exemple relevante: Chat şi Doodle.

4.1 Transmiterea datelor folosind SOCKETURI

Dificultate: 9;

Comunicarea între Flash şi un server WEB este asincrona. De fapt, această metodă de comunicare este normală ţinând cont de timpii mari pe care îi poate face informaţia de la server până la client.

Ne propunem în continuare să realizăm o aplicaţie de tip „chat”, în care două sau mai mule persoane comunică în timp real.

Mulţi programatori se folosesc de transmiterea asincronă a datelor pentru a „simula” timpul real – adică prima persoană transmite date către PHP, date care sunt salvate într-un fişier XML ce va fi încărcat la un anumit interval de timp – destul de mic – de către cel de-al doilea client. Această abordare este incorectă din următoarele motive:

- informaţia va ajunge la cel de-al doilea client doar la un interval de timp deci nu imediat;

- daca timpul este foarte mic (cum ar trebui pentru a prelua imediat fişierul şi a înlătura – oarecum – efectul primului punct) atunci clientul Flash va trimite foarte mule cereri către server. Împreună cu răspunsurile care vin de la server – şi care de multe ori reprezintă aceeaşi informaţie – vom avea de a face cu un trafic foarte mare pe reţea;

- retransmiterea aceleiaşi informaţii: dacă prima persoană a trimis o replică către serverul PHP, replică care a fost reţinută într-un fişier XML după care nu mai zice nimic timp de 10 secunde şi

Page 88: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

86

presupunând că obiectul Flash face cereri din 2 în 2 secunde pentru preluarea informaţiilor atunci aceeaşi informaţie va fi trimisă de 5 ori.

- fişierele în care se vor salva replicile ar trebui să fie destul de mici pentru a nu face trafic în reţea foarte mare. De aceea ele vor conţine un număr mic de replici – să zicem că acest fişier ar conţine doar o singură replică. Dacă cel de-al doilea flash (interlocutorul) încarcă replicile o dată la 2 secunde şi transmiţătorul trimite mai multe replici în aceste două secunde atunci numai ultima replică va ajunge corect la destinatar, restul fiind pierdute.

Probabil că există şi alte probleme în cazul încercării simulării unei transmisii în timp real folosind comunicarea asincronă.

Cum am putea rezolva această problemă? Ei bine, comunicarea ar trebui să se realizeze folosind Socketuri. Socketul este format din adresa IP şi portul pe care se face transmisia.

Jocurile în timp real (de exemplu Counter Strike – un joc ma moda) trebuie să ofere imediat unui jucător poziţia adversarului. Aceste jocuri ar fi imposibil de jucat dacă imaginea adversarului ar apărea din două în două secunde. Primul avantaj al folosirii Socketurilor este transmisia în timp real către toţi clienţii a informaţiilor recepţionate

Atunci când se folosesc Socketuri trebuie să existe un server central care să facă managementul mesajelor ce se vehiculează între diverşii jucători conectaţi la server (încă menţin paradigma unui joc multiplayer). În cazul jocurilor, de obicei, serverul este creat (de fapt lansat în execuţie) de unul din jucători care „face jocul” (de fapt setează anumite informaţii pe care serverul să le furnizeze tuturor jucatorilor: harta, poziţiile iniţiale ale jucatorilor etc.). Şi pentru aplicaţiile WEB ce vor comunica în timp real este necesar un server. Un server nu trebuie să aibă neapărat o interfaţă prietenoasă cu utilizatorul, el putând la fel de bine rulând într-o fereastră de tip MS-DOS:

Page 89: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

Figura 4-1 – Serverul pentru chat în timpul rulării

Serverul poate fi făcut în orice limbaj de programare dar deoarece aţi descărcat deja Apache2Triad – ultima versiune – care are inclusă versiunea 5 a limbajului PHP (versiune care permite comunicarea sincronă prin Socketuri) ne vom folosi de acest limbaj pentru a crea serverul ce transmite informaţiile între clienţii conectaţi. Vom încerca să realizăm un server destul de simplu: un chat.

Serverul pentru chat are rolul de a prelua mesajul transmis de un client conectat şi de a-l transmite celorlalţi cleinţi. Odată informaţia ajunsă la server ea poate fi modificată de acesta în orice fel (de exemplu ştergerea anumitor cuvinte sau scrierea cu literă mare la începutul propoziţiei sau chiar verificarea unui anumit destinatar şi transmiterea mesajului doar către acel destinatar).

Aplicaţia ce joaca rol de server trebuie să ruleze tot timpul conversaţiei (şi chiar dacă nimeni nu trimite nici un mesaj ea tot va rămâne în aşteptare) – deci calculatorul pe care rulează aplicaţia-server trebuie să fie deschis tot timpul şi serverul trebuie să fie mereu pornit. Un alt aspect este faptul că un client trebuie să se conecteze la server folosind un port şi o adresa IP (care formează un socket). Trebuie ca adresa IP sa fie una routabilă (sau cum se mai zice - impropriu10 – să aibă IP real). Un calculator care are adresa IP routabilă poate fi accesat de oriunde din reţeaua Internet. În caz ca nu aveţi o astfel de adresă va trebui să vă mulţumiţi să comunicaţi cu alte persoane din reţeaua locală.

Paşii pentru crearea serverului sunt:

8710 Nu există adrese IP false sau imaginare de aceea nici expresia “IP real” nu este corectă

Page 90: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

88

- crearea socketului şi adăugarea adresei IP şi a portului pe care îl folosim (IPul trebuie să fie cel al calculatorului pe care va rula serverul iar portul trebuie să fie unul care nu este deja folosit. Există o serie de porturi rezervate, listă pe care o puteţi găsi cu uşurinţă folosind un motor de cautare – Google de ex; Portul pe care il va folosi chatul va fi 12354).

- crearea unei liste în care să stocăm toţi clienţii ce sunt conectaţi

- recepţionarea unui mesaj nou: mesajul poate fi unul de conectare a unui nou client caz în care va fi adăugat listei clienţilor către care se va trimite informaţia, poate fi o informaţie vidă care de fapt este trimisă de client atunci când acesta vrea să se deconecteze sau poate fi un mesaj care va fi trimis tuturor clienţilor conectaţi (inclusiv emiţătorului).

Atunci când un client va inchide conexiunea, el va fi şters din listă lăsând în acest mod spaţii goale în lista clienţilor. Pentru a fi siguri că nu trimitem informaţia către un client inexistent, de fiecare dată când trimitem informaţia vom elimina spaţiile albe din lista celor conectaţi.

Atât în PHP cât şi în Flash eu voi folosi ca adresa IP valoarea „192.168.3.6” deoarce aceasta este adresa calculatorului meu. Aveţi grijă sa schimbaţi cu adresa calculatorului dumneavoastră (sau cu adresa calculatorului unde va rula serverul).

Algoritmul va fi explicat şi in codul PHP prin intermediul comentariilor:

#!/usr/bin/php –q <?php error_reporting(E_ALL); set_time_limit(0); ob_implicit_flush(); $address = '192.168.3.6'; // căutaţi şi in Flash IP-ul $port = 12354; // vom crea socketul: if (($sablon_socket=socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) { echo "Eroare: " . socket_strerror($sablon_socket)."\n"; } socket_set_option($sablon_socket, SOL_SOCKET,SO_REUSEADDR, 1);

Page 91: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

89

// adăugăm adresa IP şi portul (devinite mai sus): if (($ret=socket_bind($sablon_socket,$address,$port))<0){ echo "Eroare: ".socket_strerror($ret)."\n"; } if (($ret = socket_listen($sablon_socket, 5)) < 0) { echo "Eroare: ".socket_strerror($ret)."\n"; } // creăm lista clienţilor (acum va fi vidă): $lista_conectati = array($sablon_socket); //clienţii vor trimite mesaje încontinuu de aceea //trebuie să formăm o buclă infinită: for(;;) { // presupunem că fiecare socket are o informaţie nouă: $informatii_noi = $lista_conectati; //selectam mesajele primite $nr_mesaje_noi = socket_select($informatii_noi, $write = NULL, $except = NULL, NULL); // procesăm fiecare mesaj nou în parte: foreach($informatii_noi as $socket) { // dacă mesajul este de tip $sablon_socket înseamnă // că cineva încearcă să se conecteze la server: if ($socket == $sablon_socket) { //testăm dacă conexiunea nu s-a efectuat: if (($client=socket_accept($sablon_socket))<0) { echo "Eroare:".socket_strerror($msgsock)."\n"; continue; } else { // conexiune reusită, adăugam clientul listei: array_push($lista_conectati, $client); } // dacă mesajul nu e de tipul sablonului definit // înseamnă că cineva a trims un mesaj: } else { // dacă mesajul are dimensiunea 0, atunci clientul // s-a deconectat; calculăm dimensiunea mesajului: $bytes=socket_recv($socket,$mesajul_primit,2048,0); // dacă acesta este 0 atunci stergem cleintul //din lista clienţilor conectaţi: if ($bytes == 0) { // căutăm poziţia cleintului în listă:

Page 92: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

90

$index = array_search($socket, $lista_conectati);

:

cu toţi clienţii conectaţi

au

tra in care

client mesajul:

it);

// ştergem clientul de pe poziţia găsită unset($lista_conectati[$index]);

rver: // închidem conexiunea şi de la se socket_close($socket); // dacă mesajul e mai mare de 0 atunci a fost

// trimis un mesaj: }else{

creăm o listă // // pentru a le trimite mesajul:

i; $toti_clientii = $lista_conectat // eliminăm locurile libere (de unde // plecat alţi clienţi)

ii); array_shift($toti_client // afişam mesajul şi în fereas // rulează serverul:

echo $mesajul_primit; // transmitem fiecărui foreach($toti_clientii as $client) {

m socket_write($client,$mesajul_pri } } } } }

?>

Salvaţi fişierul PHP de mai sus în rădăcină (ca „c:\server.php”) şi pentru a-

va te

ostru. Clientul va ru

l rula deschideţi o fereastră de comandă (Start->Run şi scrieţi comanda „cmd” – se va deschide o fereastră de tip consolă) şi executaţi comanda „c:\apache2triad\php\bin\php.exe -q c:\server.php” (unde stringul „c:\apache2triad\php\bin\php.exe” reprezintă calea corectă spre executabilul PHP-ului instalat de apache2triad).

Fereastra ar trebui să rămână blocată – deoarece programul nu se rmina (motivul fiind bienînţeles bucla infinită creată cu „for(;;)”). Serverul

va accepta în acest moment conexiuni (vezi Figura 4-1).

Vom construi în continuare clientul pentru chatul nla la fiecare utilizator care va dori să se conecteze la serverul de chat şi va

fi realizat în Flash. Ca linii generale pentru ce trebuie să facă clientul vom stabili:

Page 93: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

- setarea identităţii utilizatorului chatului;

- recepţionarea şi afişarea mesajelor într-un textfield;

- trimiterea mesajelor către server.

Pentru început adăugaţi un cadru de tip cheie Flash-ului (veţi avea două astfel de cadre) şi în primul cadru introduceţi un textField de tip Input cu variabila asociată „nume”. Adăugaaţi apoi un buton cu numele de instanţă „continua”.

Tot în acest prim cadru adăugaţi scriptul:

continua.onRelease = function() { _root.play(); }; stop();

În cel de-al doilea cadru veţi construi tot chatul:

Interfaţa Flashului (aici la o scară redusă) va arăta astfel:

Figura 4-2 – Interfaţa clientului de chat la scară redusă

Creaţi două textField-uri într-o scenă cu ale cărui diemensiuni deja v-aţi obişnuit (640x480): unul mai mare, cu atributul HTML setat (apăsaţi butonul Render as HTML din fereastra de proprietăţi ale textField-ului) de tip dinamic în care vor fi afişate mesajele primite de la alţi clienţi, iar cea de-a doua fereastră de dimensiune redusă (in care să încapă doar un rând), de tip Input. Prima fereastră trebuie să aibă setat atributul Multiline iar cel de-al doilea Singleline.

Primului textField daţi-i numele de instanţă „mesaje” iar celui de-al doilea „mesaj_de_trimis”.

91

Page 94: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

92

În continuare adăugaţi un MovieClip în care introduceţi textul „Trimite” şi daţi-i numele de instanţă „trimite”.

În partea dreaptă a textFieldului dinamic în care se vor afişa mesajele aşezaţi (din fereastra de componente) o componentă de tip UIScrollBar şi în fereastra de proprietăţi apăsaţi tab-ul „Parameters” şi completaţi proprietatea _targetInstanceName cu valoarea „mesaje” (câmpul unde vor fi afişate mesajele va putea fi baleat prin intermediul acestui scrollBar).

Scriptul care va face toată treaba va fi inclus în primul cadru al celei de-a două scene.

Vom crea un obiect de tip XMLSocket şi ii vom atribui două funcţii: onConnect şi onClose care au rolul de a afişa în textFieldul principal informaţii despre starea conexiunii.

Adăugând o proprietate obiectelor de tip XMLSocket ea va fi disponibilă în oricare funcţie (la fel ca în cazul adăugării curbei Bezier MovieClip-urilor). Adăugăm evenimentul onData (adică momentul recepţionării unor informaţii) care are rolul de a adăuga textField-ului principal mesajul primit şi de a balea toate mesajele existente înspre partea superioară a textFieldul-ui ce conţine mesajele (pentru a fi vizibil ultimul mesaj adăugat).

Funcţia de transmitere a unui mesaj se foloseşte de metoda „send” din cadrul obiectelor de tip XMLSocket şi are rolul de a transmite un mesaj sub forma „Nume: mesaj” unde numele este cel introdus in primul cadru iar mesajul este cel existent în momentul apăsării tastei Enter sau a butonului de trimitere a mesajului.

Metoda de trimitere a mesajului va fi executată la apăsarea butonului „trimite” sau la apăsarea tastei Enter. Tratarea evenimentului apăsării butonului este banală iar pentru tratarea evenimentului apăsării tastei Enter ne vom folosi de Listenere (care funcţionează pe aceeaşi principiu ca şi în cazul mouse-ului).

Codul ActionScript care va trebui în cel de-al doilea cadru al Flashului este următorul:

// creare obiect: Socket = new XMLSocket(); //adăugarea metodei onConnect care va afişa mesajul // de reuşită sau de eşec:

Page 95: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

93

Socket.onConnect = function(success) { if (success) { mesaje.htmlText += "<b>Conexiune reusita!</b>"; }else{ mesaje.htmlText += "<b>Conexiune esuata!</b>"; } }; // în cazul închiderii aplicaţiei PHP se va inchide şi // conexiunea. Tratăm acest caz aici: Socket.onClose = function() { mesaje.htmlText += "<b>Conexiune inchisa de server</b>"; }; // când se primesc date noi ele vor fi adăugate împreună // cu numele clientului în fereastra principală: XMLSocket.prototype.onData = function(mesaj_receptionat) { mesaje.htmlText += mesaj_receptionat; // mutarea textului în sus: mesaje.scroll=mesaje.maxscroll; }; // aici iniţializăm conexiunea (IPul trebuie să fie cel al // calculatorului pe care ruleaă serverul) // portul este cel stabilit la început: Socket.connect("192.168.3.6", 12354); // transmiterea mesajului: function transmite_mesaj() { // ne asigurăm că avem ce transmite: if (mesaj_de_trimis.htmlText != "") { Socket.send("<b>"+_root.nume+": </b>"+ mesaj_de_trimis.htmlText+"\n"); // după transmitere vidăm câmpul pentru a fi //introdus un nou mesaj: mesaj_de_trimis.htmlText = ""; } } // apelarea funcţiei de transmitere prin apăsarea // butonului: trimite.onRelease = function(){ _root.transmite_mesaj(); } // crearea listenerului: var keyListener:Object = new Object();

Page 96: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

94

tratarea evenimentului apăsării unei taste (Enter) //keyListener.onKeyDown = function() { if (Key.getCode() == Key.ENTER){ // executarea funcţiei de transmitere:

“ascultarea” tastelor va începe aici:

u pentru a nu fi nevoiţi

transmite_mesaj(); } }; //

Key.addListener(keyListener); oprim Flashul în acest cadr//

// să reintroducem numele din nou: stop();

C şi exportaţi obiectul Flash după care din meniul File selectaţi op

ât şi în Flash eu am folosit ca adresa IP valoarea „1

limbaj de programare. În continuare vo

ompilaţi ţiunea „Publish”. Redenumiţi fişierul HTML situat în directorul un se

află Flashul cu numele „index.html” şi copiaţi toate aceste fişiere în directorul c:\apache2triad\htdocs\chat (care probabil că nu există deci va trebui să îl creaţi).

Atât în PHP c92.168.3.6” deoarce aceasta este adresa calculatorului meu. Lansaţi în

execuţie serverul realizat in PHP, deschideţi un browser Web şi ca adresă scrieţi “http://192.168.3.6/chat” (având grijă să înlocuiţi adresa cu cea pe care aţi trecut-o dumneavoastră. În obiectul Flash ar trebui să apară mesajul “Conexiune reuşită” şi la introducerea unui mesaj acesta va fi afişat în textFieldul “mesaje”. Daţi adresa şi altor colegi pentru a putea conversa (dacă adresa nu este routabilă exemplul va funcţiona doar în cadrul reţelei dumnevoastră).

Serverul poate fi realizat in orice m da ca exemplu un server de chat realizat in Perl:

#!/usr/bin/perl use IO::Socket; # utilizăm modulele de lucru cu reţeaua

care va fi folosit pentru a aştepta

sivă

ei

use IO::Select; $/ = "\0";

oclu# cream un s# cereri de la clienţi

ket::INET( $soclu_nou = new IO::Soc Listen => 1, # conexiune pa LocalPort => 12354, # portul folosit Reuse => 1, # reutilizarea adres Proto => 'tcp' ) # protocol TCP

Page 97: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

95

i!"); or die ("Eroare de pornire a serverulu# asteptam conexiuni...

soclu_nou ); $text = new IO::Select( $# citim de la fiecare posibil client while ( @reader = $text -> can_read ) {

i client

ctat

uam date de la un client

entul -a deconectat

trimis, "$input" );

imitem mesajul la toti clientii -> can_write(0) )

0";

f @trimis;

foreach $utilizator (@reader) { a unu # cerere de conectare din parte

if ($utilizator == $soclu_nou) { t; $conexiune = $soclu_nou -> accep

$text -> add($conexiune); nou cone # afisam adresa clientului

push( @trimis, a de la IP-ul: ' . 'A intrat cinev

$conexiune -> peerhost); }

e { els # prel $input = <$utilizator>; chomp $input;

c, cli s # n-am primit nimi if ($input eq '') {

lecat cineva de la:' . push( @trimis, 'A p $conexiune -> peerhost);

; $text -> remove($utilizator) $utilizator -> close; }

e { els push( @ } } }

r # t foreach $utilizator ( @writer = $text { foreach $line (@trimis) { print $utilizator "$line\ } } unde}

Execuţia serverului în perl se foloseşte de modulul Perl inclus în apache2triad prin lansarea comenzii „c:\apache2triad\perl\bin\perl.exe c:\server.pl” – atenţie la cele două căi de acces către fişierele perl.exe respectiv server.pl. Codul funcţionează similar, explicaţiile fiind furnizate în interiorul acestuia prin intermediul comentariilor.

Page 98: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

96

4.2 Utilizarea socketurilor pentru realizarea desenelor

Serverul PHP pe care l-am scris în exemplul anteriro poate fi folosit ca exemplu pentru foarte multe aplicaţii. Evident că pentru jocuri ar trebui ca pe server să se stabileaască reguli (cine mută, cine a câştigat etc). Vom folosi exact acelaşi server (care deja ştiţi cum trebuie rulat) pentru a realiza o aplicaţie în care toţi clienţii conectaţi au voie să deseneze şi fiecăruia în parte îi va apare la un moment dat desenul realizat de ceilalţi.

Pentru început vom construi scriptul necesar pentru a desena o linie (tot scriptul va fi aşezat în primul cadru al unui nou Flash). Deoarece toate desenele vor fi realizate în scena principală, putem desena direct în MovieClip-ul _root. Să setăm proprietăţi pentru acesta şi o funcţie care să traseze o linie între două puncte:

_root.lineStyle(0); _root.drawline = function(x1:Number, y1:Number, x2:Number, y2:Number) { // punctual de unde vrem să începem linia: _root.moveTo(x1, y1); // trasarea liniei p[Înă la cel de-al doilea punct: _root.lineTo(x2, y2); };

Putem în continuare să scriem scriptul necesar captării evenimentelor produse de mouse (evenimente pe care le-am mai tratat şi când modificăm săgeata implicită a mouse-ului) care de această dată vor prelua poziţia curentă de fiecare dată când mouse-ul a fost mişcat şi va crea un nou mesaj ce trebuie trimis la server:

var mouseListener:Object = new Object(); mouseListener.onMouseDown = function() { this.isDrawing = true; lastx = _xmouse; lasty = _ymouse; }; mouseListener.onMouseMove = function() { if (this.isDrawing) { curentx = _xmouse;

Page 99: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

97

curenty = _ymouse; mesaj = "#"+lastx+","+lasty+","+curentx+","+curenty+"#"; _root.transmite_mesaj(mesaj); _root.drawline(lastx, lasty, curentx, curenty); lastx = curentx; lasty = curenty; } updateAfterEvent(); }; mouseListener.onMouseUp = function() { this.isDrawing = false; }; Mouse.addListener(mouseListener);

Dacă eliminaţi linia „_root.transmite_mesaj(mesaj);” care are rolul de a trimite mesajul către server, atunci veţi obţine un Flash în care puteţi desena.

Cel mai important pas este cel al creării mesajului de trimis către server respectiv de desenare a liniilor primite de la alţi utilizatori:

Socket = new XMLSocket(); Socket.onConnect = function(success) { //putem scrie un mesaj de conectare ca in cazul chatului }; Socket.onClose = function() { //putem scrie mesaj de deconectare ca in cazul chatului }; XMLSocket.prototype.onData = function(mesaj_receptionat) { // mesajul recepţionat trebuie procesat… // spargem mesajul in funcţie de caracterul # // şirul de numere se va afla în sir[1] despărţite cu , sir = mesaj_receptionat.split("#"); // sir[1] în funcţie de “,” pentru a găsi valorile valori = sir[1].split(","); // linia pentru coordonatele venite de la alt client: _root.drawline(Number(valori[0]), Number(valori[1]), Number(valori[2]), Number(valori[3])); }; // folosim acelaşi IP şi port ca şi serverul // modificaţi cu datele serverului dumneavoastră: Socket.connect("192.168.3.6", 12354);

Page 100: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

// funcţia ce transmite mesajul apelată din funcţia de // tratare a mişcării mouseului: function transmite_mesaj(mesaj_de_trimis) { Socket.send(mesaj_de_trimis); }

Figura 4-3 – Desenul într-un Flash conectat la server apare şi în celelalte Flashuri

Atunci când foarte mulţi utilizatori desenează în acelaşi timp pe aceeaşi suprafaţă, numărul mare de vectori va îngreuna Flash-ul. Pentru a şterge imaginea aţi putea apăsa butonul de reîncărcare a paginii (refresh) dar acest lucru ar duce la închiderea conexiunii şi deschiderea unei noi conexiuni. Mai corect ar fi să creaţi un buton în care să ştergeţi doar _root-ul. Atunci când ştergeţi documentul _root se şterg şi setările privind tipul liniei cu care se va desena. Din acest motiv butonul de ştergere al ecranului ar trebui să aibă asociat următorul cod:

on (press) { _root.clear(); _root.lineStyle(0); }

98

Page 101: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

99

Pentru a stăpâni mai bine cunoştinţele acumulate aţi putea să rezolvaţi următoarele exerciţii:

- Adăugaţi programului de desenare funcţii de creare a unui pătrat, a unei curbe bezier sau a altor figuri geometrice. Construiţi controale pentru schimbarea culorii liniei de desen şi a grosimii acesteia.

- Îmbunătăţiţi puzzletul construit la unul din exemplele precedente astfel încât să poată fi rezolvat de mai mulţi clienţi care mută piesele în timp real.

- Îmbunătăţiţi serverul de chat astfel încât să permită existenţă chat-room-urilor în care vor vorbi doar câte doi utilizatori fără ca ceilalţi să poată vizualiza discuţia dintre ei (pentru cei care cunosc PHP).

Page 102: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

100

Capitolul 7

5 Şi câteva exemple “de efect”

În acest capitol vom construi cateva exemple destul de interesante şi de foarte multe ori necesare atunci când construiţi aplicaţii Flash: realizarea unui efect pentru o imagine, construirea unui preloader, a unui MP3 player etc.

5.1 Efecte aplicate asupra imaginilor

Pentru a putea aplica un efect asupra unei imagini trebuie ca această imagine să existe în interiorul obiectului Flash şi să o identificăm prin ceva.

Imaginea poate fi importată atunci când creăm obiectul Flash sau poate fi importată în timpul rulării. Deoarece prima metodă are rolul de a mări dimensiunea fişierului swf (şi nu vrem să avem fişiere mari care să ajungă greu pe calculatorul celui care vizualizează filmul Flash) vom încerca să ne folosim de cea de-a doua soluţie.

Să vedem care ar fi problemele care se pun atunci când se încarcă o imagine din exteriorul Flashului:

- imaginea este destul de mare şi încărcarea nu va fi imediată. Trebuie să ne folosim de evenimentul încărcării imaginii pentru a ne putea fi siguri că aceasta a fost încărcată.

- încărcarea imaginii se realizează cu comanda loadMovie care teoretic ar trebui să încarce doar MovieClip-uri în interiorul Flash-ului. Deoarece obiectele MovieClip au propriile evenimente, acestea vor rescrie evenimentele obiectului în care se încarcă în momentul terminării încărcării (şi astfel evenimentul onLoad ce ar trebui să fie tratat conform primei „probleme” va dispare.

Pentru a rezolva ambele probleme ne vom folosi de clasa MovieClipLoader pe care am mai utilizat-o şi atunci când am realizat albumul foto.

Page 103: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

101

Vom încărca o imagine într-un film Flash în care modificaţi setările predefinite astfel încât filmul să ruleze cu 40 de cadre pe secundă. Codul necesar pentru a încărca imaginea „moto.jpg” din acelaşi director în care este salvat şi flashul (fişierul swf), este următorul:

_root.createEmptyMovieClip("loc_de_incarcat",0); var un_obiect:Object = new Object(); un_obiect.onLoadComplete = function():Void { //play_effect(_root.loc_de_incarcat); trace("incarcat"); }; un_obiect.onLoadError = function(destinatie:MovieClip, httpStatus:Number):Void { trace ("Eroare"); }; var monitor:MovieClipLoader = new MovieClipLoader(); monitor.addListener(un_obiect); monitor.loadClip("moto.jpg", loc_de_incarcat);

Deoarece codul este similar ca şi cel de la albumul foto, nu intrăm în amănunte. La încărcarea imaginii „moto.jpg” va fi afişat mesajul „incarcat”. În cazul apariţiei unei erori, aceasta va fi semnalată prin apariţia mesajului „eroare”. În funcţia un_obiect.onLoadComplete care este executată automat în momentul încărcării imaginii, găsiţi comentată linia //play_effect …… pe care o va trebui să o decomentaţi din cauză că în continuare vom construi această funcţie care are rolul de a introduce într-un mod frumos imaginea în scenă.

Deoarece nu vrem să descriem doar un astfel de efect, vom da în continuare mai multe astfel de funcţii „play_effect” care pot fi înlocuite pentru obţinerea de efecte diferite.

De obicei o funcţie în care este construit un efect trebuie să fie legat într-un fel de o variabilă temporală (deci care se modifică în timp). Pentru a putea modifica variabila temporală în timp, ne vom folosi de funcţia onEnterFrame asociată MovieClip-ului _root. După terminarea efectului această funcţie va fi distrusă (nu avem nevoie să avem o funcţie care să ruleze inutil la nesfârşit).

Prima funcţie pe care o vom construi va avea rolul de a introduce imaginea în scenă printr-un efect de „fade”:

function play_effect(mc:MovieClip){

function play_effect(mc:MovieClip){

Page 104: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

102

_root.opacitate=0; mc._alpha=opacitate; _root.onEnterFrame = function(){ _root.opacitate++; mc._alpha = opacitate; if (_root.opacitate==100) _root.onEnterFrame = null; } }

Funcţia are ca parametru MovieClip-ul căruia îi trebuie modificat parametrul „_alpha” de la complet transparent până la opac. Variabila _root.opacitate are rolul de a stabili opacitatea obiecului la un momoent dat şi aşa cum se vede, această variabilă va fi incrementată în funcţia MovieClip (care se execută într-o secundă de un număr de ori egal cu numărul de cadre pe secundă: 40). Cum opacitatea maximă este 100, în momentul atingerii acesteia nu mai are sens să continuăm şi distrugem funcţia onEnterFrame dându-i valoarea null.

Cel de-al doilea efect este va face ca imaginea să apară din pătrate care îşi măresc dimensiunea. Pentru aceasta, întâi vom crea un al doilea MovieClip cu care vom masca imaginea. În acest MovieClip (pe care în cod l-am numit temp) vom crea un număr de MovieClip-uri, în fiecare vom desena câte un pătrat şi le vom dispune în aşa fel încât să acopere toată scena (puteţi să suprapuneţi şi numai deasupra imaginii). Iniţial toate pătratele sunt scalate la 0% şi în timpul animaţiei acest factor va creşte până la dimensiunea maximă (100%). Când acest procent este atins, eliminăm funcţiile de mărire a pătratelor, eliminăm MovieClip-ul „temp” şi scoatem masca de pe Clipul principal.

Funcţia de redare a efectului (care va înlocui funcţia play_effect scrisă anterior) este următoarea:

function play_effect(mc:MovieClip) { latura = 40; // desi ar fi trebuit sa avem dimensiunile pozei latime = Stage.width; inaltime = Stage.height; nr_patrate_orizontal = latime/latura; nr_patrate_vertical = inaltime/latura; _root.createEmptyMovieClip("temp", _root.getNextHighestDepth()); _root.temp._x = mc._x; _root.temp._y = mc._y; mc.setMask(temp); for (i=0; i<nr_patrate_orizontal; i++) {

Page 105: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

103

for (j=0; j<nr_patrate_vertical; j++) { _root.temp.createEmptyMovieClip( "patratel_"+i+"_"+j, i*nr_patrate_vertical+j); _root.temp["patratel_"+i+"_"+j]._lineStyle(1, 0, 0); _root.temp["patratel_"+i+"_"+j]._x = i*latura; _root.temp["patratel_"+i+"_"+j]._y = j*latura; _root.temp["patratel_"+i+"_"+j].moveTo (-latura/2, -latura/2); _root.temp["patratel_"+i+"_"+j].lineTo (-latura/2, latura/2); _root.temp["patratel_"+i+"_"+j].lineTo (latura/2, latura/2); _root.temp["patratel_"+i+"_"+j].lineTo (latura/2, -latura/2); _root.temp["patratel_"+i+"_"+j].lineTo (-latura/2, -latura/2); _root.temp["patratel_"+i+"_"+j]._xscale = 0; _root.temp["patratel_"+i+"_"+j]._yscale = 0; // de aici _root.temp["patratel_"+i+"_"+j].onEnterFrame = function() { if (this._xscale<100) { this._xscale += 5; this._yscale += 5; } else { mc.setMask(null); _root.temp.removeMovieClip(); this.onEnterFrame = null; } }; } // pana aici } }

Unul din paşii efectului poate fi vizualizat în imaginea următoare:

Page 106: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

Figura 7-0-1 - efectul construirii imaginii din pătrate spre final

Un efect chiar şi mai interesant pentru imaginea noastră se obţine dacă în această ultimă funcţie înlocuiţi codul marcat intre comentariile //de aici şi //pana aici cu următorul cod care face ca apariţia pătratelor să nu fie simultană ci fiecare pătrat să-şi înceapă animaţia aleatoriu (la momente diferite de timp):

_root.temp["patratel_"+i+"_"+j].go = random(100); _root.temp["patratel_"+i+"_"+j].onEnterFrame = function(){ this.go++; if (this.go>100) { if (this._xscale<100) { this._xscale += 5; this._yscale += 5; } else { if (this.go>300) { mc.setMask(null); _root.temp.removeMovieClip(); this.onEnterFrame = null; } } } };

Unul din paşii efectului obţinul este reprezentat în următoarea imagine:

104

Page 107: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

Figura 7-0-2 - Acelaşi efect doar că pătratele nu îşi pornesc animaţia simultan ci

aleator

Puteţi să generaţi şi un efect în care pătratele să apără ordonat dacă îlocuiţi în codul precedet prima linie:

_root.temp["patratel_"+i+"_"+j].go = random(100);

Cu:

_root.temp["patratel_"+i+"_"+j].go = i*2+j*2;

Discuţia despre felurile în care aţi putea masca imaginea sau ce efecte aţi putea forma utilizând măşi poate continua la nesfârşit. De obicei dacă vedeţi o imagine care apare din nişte forme geometrice mai mult sau mai puţin asemănătoare, efectul este în mod sigur realizat prin intermediul măştilor. Imaginea poate aşadar apare din fâşii, steluţe, inimioare sau orice altceva. O ultimă imagine ce reprezintă un efect realizat cu măşti şi pe care vă provocăm să îl realizaţi singuri:

105

Page 108: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

Figura 7-0-3 - Efectul precedent format din cercuri (diametrul cercului trebuie să fie

mai mare decât diagonala pătratului)

Până la versiunea 7 de Flash, imaginile erau considerate obiecte şi nu se puteau face nici un fel de procesări ale acestora (cu excepţia câtorva de tip hue, saturation dar care nu presupuneau manipularea imaginilor la nivel de pixel). Începând cu versiunea 8 a Flash-ului au fost introduse câteva clase care permit prelucrarea fiecărui pixel a unei imagini.

O imagine are destui de mulţi pixeli (numai o imagine de rezoluţie mică: 320x240 are 76800 pixeli). O imagine poate fi considerată a fi o matrice de dimensiuni destul de mari şi pentru a o prelucra, uneori avem nevoie de anumite funcţii care automatizează lucrul cu aceste valori.

Una din aceste funcţii care face prelucrare autmoată pentru imagini este threshold.

În acest caz suntem obligaţi să aflăm dimensiunile pozei pentru a putea crea un obiect de tip bitmap în care vom încărca imaginea. Deoarece în momentul lansării funcţiei „play_effect” Flashul încă nu cunoaşte aceste informaţii, îl vom opri într-o buclă a funcţiei onEnterFrame asociată _root-ului până când dimensiunile vor fi disponibile. Vom distruge apoi această funcţie pentru a o recrea mai jos. Ne vom folosi de câteva clase externe aşadar va trebui să le importăm.

Obiectul de tip bitmapData nu poate fi afişat pe ecran decât dacă unui MovieClip i se ataşează imaginea prin utilizarea comenzii attachBitmap. Operaţia inversă de desenare din MovieClip în obiectul de tip bitmap, se realizează prin intermediul comenzii draw specifică obiectelor de tip 106

Page 109: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

107

bitmap. Aşadar, în primă fază, vom copia conţinutul MovieClip-ului nostru primit ca parametru (mc) într-un obiect de tip bitmap (bitmap), vom construi încă un boiect de tip bitmpap (bitmap2) pe care îl vom asocia cu un nou MovieClip (poza_noua) pentru a-l putea afişa şi apoi definim funcţia _root.onEnterFrame care are rolul de a verifica pe rând toţi pixelii din bitmap şi a-i copia în obiectul bitmap2 pe acei dintre ei care satisfac o anumită condiţie. Condiţia este pusă de către o variabilă i care se încrementează şi care la fiecare pas al animaţiei va schimba condiţia aplicată pixelilor şi mai mulţi pixeli se vor copia în bitmap2. În final toţi biţii vor fi copiaţi dar ca să ne asigurăm că nici unul dintre ei nu a rămas pe dinafară, vom copia în întregime bitmap în bitmap2 (şi evident vom elimina funcţia _root.onEnterFrame pentru a nu solicita inutil procesorul):

function play_effect(mc:MovieClip) { _root.onEnterFrame = function() { if (mc._width>0) { _root.onEnterFrame = null; import flash.display.BitmapData; import flash.geom.Rectangle; import flash.geom.Point; var bitmap:BitmapData = new BitmapData( mc._width, mc._height, false, 0x00CCCCCC); bitmap.draw(mc); var bitmap2:BitmapData = new BitmapData( mc._width, mc._height, false, 0x00ffffff); _root.createEmptyMovieClip("poza_noua", this.getNextHighestDepth()); poza_noua._x=mc._x; // efectul va apare peste poza_noua._y=mc._y; // poza incarcata in mc poza_noua.attachBitmap(bitmap2, this.getNextHighestDepth()); i = 0x00ffffff; _root.onEnterFrame = function() { i -= 65793; if (i>0) { bitmap2.threshold(bitmap, new Rectangle(0, 0, 640, 480), new Point(0, 0), "<=", i, 0x00FFFFFF, 0x00ff0000, true); }else{ bitmap2.draw(mc); _root.onEnterFrame = null; } }; } };

Page 110: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

}

Rezultatul acestui efect poate fi vizualizat în imaginea următoare:

Figura 7-4 – Moment intermediar din efectul construirii imaginii din pixeli

În cazul în care aveţi impresia că efectul este prea lent pentru cele 40 de cadre pe secundă pe care le aveţi setate, recomandăm mărirea numărului ce se scade de fiecare dată din valoarea lui i (în prezent acesta este de 65793).

Aşa cum v-aţi obişnuit deja urmează o mică temă. De această dată tema va fi puţin mai amplă şi constă în realizarea unei galerii de fotografii care după încărcarea unei poze îi va aplica şi un efect pentru a o aduce în scenă. Vom folosi galeria în cadrul sitului şi din acest motiv vă rog să vă daţi silinţa ca aceasta să arate cât mai bine şi să funcţioneze corect.

5.1 Construirea unui preloader

Dificultate: 5;

În primul rând ce reprezintă un preloader ?

Oricine a văzut în siturile Flash o bară de progres care indică cât s-a încărcat din filmul curent. Uneori găsim astfel de indicatoare care, deşi ştim că încărcarea filmului este completă, ele tot stau şi ne sâcâie cu prezenţa lor. Nu vom vorbi despre aceste „făcături” sau „minciunele” ci despre cum şi

108

Page 111: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

109

de ce avem nevoie de „adevăratele” preloadere – cele care indică în mod real cât s-a încărcat dintr-un film.

Pentru a putea să „înţelegem” preloaderele ar trebui să ştim câteva despre modul în care se încarcă un fişier SWF în memoria calculatorului. Ei bine, răspunsul este unul destul de simplu: ca o secvenţă de cadre. Acest lucru înseamnă că primele cadre sunt independente de ultimele şi din acest motiv ele pot fi afişate fără ca tot filmul să fie încărcat în memoria calculatorului.

Fişierul SWF este unul în format vectorial11 şi deşi poate include unele resurse (cum ar fi imagini sau sunete), nu ar trebui să facă acest lucru. Atunci când aceste resurse sunt incluse, dimensiunea fişierelor creşte şi cel care întâlneşte o pagină făcută în Flash (repet: făcută rău în Flash) are tendinţa de a sta câteva secunde în aşteptarea întâmplării a „ceva” şi când acest „ceva” nu are loc, de obicei pagina este schimbată). Preloaderul este cel care îi comunică utilizatorului cât mai are de aşteptat şi totodată îi zice că „DA! … aici se întâmplă ceva, te rog mai aşteaptă”.

Principiul de funcţionare a unui preloader este unul destul de simplu: se încarcă primul cadru, se execută codul aflat în interiorul său, cod care ar trebui să nu permită trecerea la următoarele cadre decât în cazul încărcării complete a filmului. Putem determina câţi bytes au fost încărcaţi până la un moment dat prin apelul funcţiei getBytesLoaded, funcţie disponibilă pentru orice MovieClip şi deci şi pentru _root. Aflarea dimensiunii totale se realizează cu _root.getBytesTotal(). Aceste două funcţii ar trebui să se execute la un interval de timp pentru a reactualiza în mod constant dimensiunea din film care a fost încărcată. Din acest motiv această comandă va fi executată de fiecare dată când se va intra într-un nou cadru al unui MovieClip (şi vom considera ca MovieClip chiar _root-ul).

Într-un nou document adăugaţi un caru-cheie. În cel de-al doilea cadru importaţi o imagine destul de mare (care ar lua ceva timp pentru a fi încărcată din Internet) şi în primul cadru ataşaţi scriptul:

incarcat = _root.getBytesLoaded(); total = _root.getBytesTotal(); if (incarcat != total) { _root.onEnterFrame = function() { incarcat = _root.getBytesLoaded();

11 Una din caracteristicile fişierelor vectoriale este aceea că sunt reduse ca dimensiuni (sau theoretic aşa ar trebui să se întâmple de obicei).

Page 112: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

110

total = _root.getBytesTotal(); trace(incarcat+" - "+total); if (incarcat == total) { _root.gotoAndPlay(2); this.onEnterFrame = null; } else { _root.gotoAndStop(1); } }; } else { //dacă s-a terminat de încărcat, sărim la cadrul 2 gotoAndPlay(2); }

Teoretic acest script se va executa de fiecare dată când se va ajunge în primul cadru al _root-ului. Pentru a evita funcţionarea preloaderului şi după ce încărcarea a fost completă, vom testa dacă nu cumva documentul este încărcat în întregime (vom defini funcţia onEnterFrame doar dacă incarcat != total). Presupunând că nu este cazul, vom defini funcţia în care vom prelua de fiecare dată noile dimensiuni şi în cazul în care filmul nu este ă încărcat vom opri filmul în primul cadru. Când încărcarea este completă vom porni filmul (care dacă va mai reveni la cadrul 1 nu va mai re-defini funcţia onEnterFrame) şi vom elimina din memorie definiţia acestei funcţii. Pentru a testa preloaderul apăsaţi de două ori CTRL+Enter (cea de-a doua oara va testa filmul ca şi cum ar fi încărcat din Internet – puteţi simula o anumită bandă de transmisie dacă în timpul testării din meniul View modificaţi opţiunea DownloadSettings).

Comanda trace are rolul de a afişa valorile intermediare (cât s-a încărcat/ total). Această funcţie poate fi înlocuită cu o funcţie care să deseneze o bară de progres ce va fi scrisă la începutul scriptului (puteţi adăuga această funcţie în grafix.as deoarece vom folosi preloaderele şi în viitor):

MovieClip.prototype.desenaza_bara_progres = function(pozx, pozy, lungime, grosime, incarcat, total) { procent = incarcat*lungime/total; this.clear(); this.lineStyle(1, 0xff0000, 100); this.moveTo(pozx, pozy); this.lineTo(pozx+lungime, pozy); this.lineTo(pozx+lungime, pozy+grosime); this.lineTo(pozx, pozy+grosime); this.lineTo(pozx, pozy); this.beginFill(0xff0000, 50); this.moveTo(pozx, pozy);

Page 113: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

111

this.lineTo(pozx+procent, pozy); this.lineTo(pozx+procent, pozy+grosime); this.lineTo(pozx, pozy+grosime); this.lineTo(pozx, pozy); };

Comanda de ştergere a _root-ului (_root.clear();) ar trebui adăugată şi în interiorul condiţiei care validează încărcarea completă a filmului. Evident că trace-ul va trebui să fie înlocuit de o comandă de genul _root.desenaza_bara_progres(100, 100, 300, 7, incarcat, total);

Încercaţi să descifraţi singuri acest script, să modificaţi culori/transparenţe sau imaginea preloader-ului curent (de tip bară) - de multe ori veţi întâlni preloadere care să „coloreze” o imagine de tip bitmap. Puteţi realiza acest lucru12 ?

După cum aţi observat, comenzile de testare a dimensiunilor sunt aplicate unui obiect de tip MovieClip. De fapt testarea procentului de film încărcat chiar din interiorul filmului este puţin artificială. Comenzile getBytesLoaded şi getBytesTotal ar trebui utilizate pentru a calcula procentul rămas de încărcat a unei resurse externe (de exemplu atunci când încărcăm o imagine). Aici apar alte probleme: dacă în cazul fişierului SWF se ştia sigur că fişierul există (pentru că el tocmai se încărca), atunci când pornim un preloader pentru o resursă externă (de exemplu o imagine) nu putem fi siguri de existenţa pe server a acelei resurse. Ar trebui să avem unele modalităţi de a „testa” eventualitatea producerii unei erori.

Vom numi „monitor” un obiect prin intermediul căruia putem să detectăm diversele evenimente asociate altor obiecte folosite în Flash. Putem prin intermediul acestor monitoare să captăm evenimente asociate mouse-ului, tastaturii sau chiar evenimente asociate încărcării unei resurse externe (evenimente cum ar fi începerea încărcării, producerea unei erori sau terminarea încărcării). Dacă nu am folosi astfel de monitoare am putea uneori întâmpina probleme: în exemplul de mai sus, dacă în timpul încărcării s-ar produce o defecţiune în reţea şi resursa cerută (fişierul SWF) nu ar mai fi disponibilă atunci filmul Flash se va bloca în primul cadru încercând la nesfârşit să găsească momentul în care dimensiunea încărcată egalează dimensiunea totală – acest lucru nu se va produce niciodată.

12 Soulţia este dată de incărcarea a două imagini, una alb-negru pe un strat inferior şi una colorată pe stratul superior. Impresia de “colorare” va fi realizată prin deplasarea unei măşti peste imaginea colorată în funcţie de procentul din film încărcat.

Page 114: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

112

Pentru exemplul următor vom construi un monitor ce va superviza încărcarea unui fişier în format JPG din exteriorul filmului Flash. Acestui monitor îi putem asocia tratarea diverselor evenimente dar vom folosi doar evenimentul începerii încărcării (pentru afişarea barei de progres), evenimentul produs în timpul încărcării (pentru reactualizarea barei), evenimentul terminării încărcării (pentru ştergerea barei) şi evenimentul producerii unei erori (pentru afişarea unui mesaj de eroare).

Vom scrie din nou funcţia de desenare a barei de progres (de fapt aţi putea-o adăuga în fişierul „grafix.as” pe care să-l importaţi la începutul fiecărui preloader (aşa cum aţi făcut cu curba Bezier). Restul scriptului ar trebui să conţină:

O metodă de creare a monitorului care va fi definit ca un obict oarecare (el va deveni monitor doar în momentul în care îl vom ataşa explicit unui MovieClip):

var un_obiect:Object = new Object();

Ca membri ai obiectului de monitorizare vom defini funcţia de captare a evenimentului începerii încărcării:

un_obiect.onLoadStart = function():Void { _root.createEmptyMovieClip("bara_progres", 10000); };

O funcţie care va monitoriza încărcarea şi o va reflecta în valoarea barei de progres:

un_obiect.onLoadProgress = function(destinatie:MovieClip, bytesLoaded:Number, bytesTotal:Number):Void { _root.bara_progres.desenaza_bara_progres (100, 100, 300, 7, bytesLoaded, bytesTotal); };

O funcţie care va elimina bara de progres la sfârşitul încărcării:

un_obiect.onLoadComplete = function():Void { _root.bara_progres.unloadMovie(); };

Şi în final o funcţie de tratare a apariţiei unei erori:

un_obiect.onLoadError = function(destinatie:MovieClip, httpStatus:Number):Void { trace("Eroare: "+httpStatus);

Page 115: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

113

_root.bara_progres.unloadMovie(); };

Toate acestea vor fi ataşate unui obiect de tip listener – deci monitorul nostru care apoi va fi asociat cu un obiect de tip MovieClip creat dinamic în momentul lansării în execuţie a filmului Flash (obiectul va purta denumirea de „img”):

var monitor:MovieClipLoader = new MovieClipLoader(); monitor.addListener(un_obiect); _root.createEmptyMovieClip("img", 9999); monitor.loadClip("imagine.jpg", "img");

Fişierul care se încarcă din exterior poartă numele de „imagine.jpg”. Încercaţi să redenumiţi acest fişier pentru a produce o eroare. Ce s-ar fi întâmplat dacă nu am fi tratat eroarea prin intermediul unui obiect de monitorizare şi ne-am fi folosit direct doar de getBytesLoaded şi getBytesTotal (se poate aplica aceste metode unui MovieClip în care imaginea se încarcă prin intermediul comenzii loadMovie).

Tema pentru acest exerciţiu este de a face un preloader pentru puzzle-ul din exemplul precedent în care să captaţi şi afişaţi eventualele erori apărute.

5.2 Mişcări “elastice” ale MovieClip-urilor

Dificultate: 4;

Cel mai des întâlnite tipuri de mişcări ale MovieClip-uilor, mişcări realizate prin intermediul ActionScript-ului, sunt cele de mişcare încetinită şi cele de mişcare elastică.

Principiul de funcţionare a mişcării încetinite este unul destul de simplu: de fiecare dată obiectul este mutat la o distanţă mai mică faţă de punctul final. De exemplu dacă obiectul se află la 100 de puncte faţă de punctul final, în primul pas acesta va fi mutat la 50 de puncte, apoi la 25 de puncte, 12 puncte etc. Cu alte cuvinte obiectul este mereu mutat la o distanţă egală cu jumătatea distanţei rămase până la punctul final. Teoretic obiectul nu va ajunge niciodată în punctul final dar practic, la un moment dat (din cauză că la un moment dat zecimalele sunt ignorate), Flash-ul nu va mai putea distinge între punctul final şi cel actual. Atunci putem considera că obiectul a ajuns la destinaţie.

Page 116: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

114

Funcţia de deplasare încetinită o vom numi „smoothMove” pentru a fi în concordanţă cu celelalte funcţii asociate MovieClip-urilor şi vom adăuga această funcţie clasei MovieClip aşa cum am făcut şi în cazul curbei bezier. De menţionat este totuşi că această funcţie va distruge orice funcţie asociată evenimentului onEnterFrame asociată în prealabil obiectului.

Aşadar funcţia de mişcare încetinită este următoarea:

MovieClip.prototype.smoothMove = function(x, y, factor) { this.onEnterFrame = function() { difx = (x-this._x)/factor; dify = (y-this._y)/factor; this._x += difx; this._y += dify; if (difx+dify == 0) { this.onEnterFrame = null; } }; };

Se creează o funcţie care va trata evenimentul intrării într-un cadru care are rolul de a calcula distanţa la care trebuie repoziţionat obiectul – difx, dify (în exemplul dat factorul era 2 deoarece distanţa se înjumătăţea; este preferabil să utilizaţi un factor mai mare). În continuare este adăugată poziţiei actuale diferenţa calculată şi funcţia este eliminată (this.onEnterFrame = null;) atunci când diferenţele devin ambele nule (deci şi suma lor este 0).

Mişcarea elastică diferă cu puţin faţă de cea încetinită, principiul de bază fiind acelaşi. În mişcarea încetinită poziţionam obiectul la o poziţie intermediară între poziţia anterioară şi cea finală. De această dată poziţia la care vom poziţiona obiectul este pe linia formată de poziţia curentă şi cea finală dar de fiecare dată obiectul va fi situat după punctul final – evident de fiecare dată la o distanţă din ce în ce mai mică. Această logică este aplicată atât pe axa oX cât şi pe oY.

MovieClip.prototype.elasticMove = function(pozx, pozy, accx, accy, frecare) { vitezax = 0; vitezay = 0; this.onEnterFrame = function() { vitezax += (pozx-this._x)*accx; vitezax *= frecare; this._x += vitezax; vitezay += (pozy-this._y)*accy;

Page 117: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

115

vitezay *= frecare; this._y += vitezay; if ((Math.abs(vitezax)<0.3) && (Math.abs(vitezay)<0.3)) { this.onEnterFrame = null; } }; };

Funcţia de mişcare elastică are ca parametri de intrare coordonatele x şi y ale poziţiei finale, acceleraţia pe cele două axe şi un factor de frecare. Pentru ca mişcarea să aibă o finalitate (obiectul să ajungă în poziţia x,y şi să se oprească acolo) trebuie ca măcar unul din parametri acceleraţie sau frecare să fie subunitar – altfel distanţa dintre poziţia obiectului şi cea finală nu se va micşora niciodată ci dimpotrivă se va mări.

În mod asemănător putem defini o mişcare de scalare elastică:

MovieClip.prototype.elasticScale = function(procent_marime_finala, acceleratie, frecare) { viteza = 0; this.onEnterFrame = function() { viteza += (procent_marime_finala-this._xscale)*acceleratie; viteza *= frecare; this._xscale = this._yscale += viteza; if (Math.abs(viteza)<0.3) { this.onEnterFrame = null; } }; };

Şi de această dată trebuie să aveţi grijă ca valorile acceleraţiei şi a frecării să fie subunitare.

Nu uitaţi să adăugaţi şi aceste metode noi în fişierul „grafix.as”.

5.3 Comunicarea între obiectele Flash de pe aceeaşi pagină

Pentru a construi un site în întregime în Flash vom crea întâi o scenă principală în care se vor încărca pe rând diferitele „pagini” reprezentate tot de obiecete Flash. De obicei, aceste obiecte Flash se vor încărca în momentul în care apăsaţi un buton şi din cauză ca nu trebuie să se încarce

Page 118: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

116

toate simultan, fiecare poate avea propriul preloader (care va funcţiona corect).

Totuşi la un moment dat, probabil, vă veţi „izbi” de vreun site care nu se încarcă într-un obiect Flash principal ci este format din HTML şi are diverse porţiuni de Flash. Este cazul unui prieten care a „păţit-o” şi deoarece el vroia să construiască un preloader central pentru mai multe obiecte Flash, voi încerca să vă explica cum s-ar putea realiza acest lucru.

Ideea de bază este că obiectele Flash care rulează pe un acelaşi calculator pot comunica între ele (indiferent dacă sunt sau nu pe aceeaşi pagină). Exemplul pe care îl vom realiza va conţine două obiecte Flash, destul de mari (ca şi cantitate de informaţie ce trebuie încărcată) şi care vor „comunica” între ele: A şi B. Obiectul Flash A are rolul de a afişa trei bare de loading: pentru el, pentru obiectul Flash B şi una care să afişeze totalul. Tot obiectul A va iniţia o conexiune la nivel local între el şi B, conexiune prin care B îi va putea comunica care este mărimea informaţiilor ce trebuie încărcate respectiv cât s-a încărcat.

Setaţi dimensiunea scenei la 400x200 şi salvaţi documentul curent cu numele „A.fla” (să reţinem că la exportare obiectul se va numi A.swf).

Ca să obţinem pagina în format HTML din meniul File al Flash-ului selectăm opţiunea Publish. Fişierul HTML este în format text şi-l vom edita cu orice editor (de preferat este totuşi Notepad; se poate folosi orice editor dar unele vor recunoaşte pagina WEB şi o vor edita într-un mod specific).

Pentru început să vedem cum aşezăm cele două obiecte Flash în aceeaşi pagină. Pentru ca un obiect Flash să fie aşezat corect într-o pagină WEB, în codul HTML al acesteia trebuie să existe o secţiune Object care să furnizeze informaţii privitoare la modul de afişare. Această secvenţă de cod este asemănătoare cu:

<object classid="clsid:d27cdb6e-ae6d-11cf-96b8- 444553540000" codebase="http://fpdownload. macromedia.com/pub/shockwave/cabs/flash/swflash. cab#version=8,0,0,0" width="400" height="200" id="A" align="middle"> <param name="allowScriptAccess" value="sameDomain" /> <param name="movie" value="A.swf" /> <param name="quality" value="high" /> <param name="bgcolor" value="#ffffff" /> <embed src="A.swf" quality="high" bgcolor="#ffffff" width="400" height="200" name="A" align="middle"

Page 119: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

117

allowScriptAccess="sameDomain" type="application/x- shockwave-flash" pluginspage="http://www.macromedia. com/go/getflashplayer" /> </object>

Încercând să descifrăm câteva informaţii vom observa că în acest cod putem găsi câteva setări pe care noi le-am efectual (dimensiunea scenei : 400x200, numele cu care a fost salvat obiectul „A.swf”, culoarea backgroundului etc.). O observaţie pe care trebuie să o facem este aceea că toate informaţiile sunt scrise de două ori (de exemplu vom găsi de două ori „A.swf”(în codul de mai sus am îngroşat această informaţie tocmai pentru a fi mai uşor de găsit). Motivul pentru care codul apare de două ori este că prima metodă este specifică introducerii obiectului Flash în browsere ce se bazează pe Internet Explorer iar cea de-a doua parte (care conţine aceleaşi informatii dar este inclusă într-un marcaj „embed”) este necesară altor browsere (Firefox, Netscape).

Ceea ce avem de făcut în continuare este să copiem codul încă o dată imediat după cel existent şi să modificăm „A.swf” cu „B.swf”. Pentru a remarca mai bine existenţa a două Flash-uri diferite am schimbat şi culoarea fondului paginii HTML modificând linia:

<body bgcolor="#ffffff">

În

<body bgcolor="#dddddd">

Ceea ce mai rămâne este să mai construim încă obiect Flash cu aceleaşi dimensiuni (400x200) şi să-l Salvăm lângă primul ca „B.fla”.

Aţi învăţat deja să faceţi preloadere într-un exemplu precedent, construiţi câte un preloader pentru fiecare din Flash-uri (şi pentru A şi pentru B). Folosiţi primul tip de preloader învăţat – cel în care ştiţi deja că există obiectul SWF, cu un script în primul cadru şi o imagine în al doilea (nu uitaţi că imaginea trebuie să aiba dimensiuni maricele pentru a putea observa mai bine felul în care funcţionează preloaderul).

Deoarece Flash-ul B.fla este mai uşor de făcut vom da scriptul care se află în primul cadru al acestuia:

#include "grafix.as" conex_transm = new LocalConnection(); incarcat = _root.getBytesLoaded(); total = _root.getBytesTotal();

Page 120: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

118

if (incarcat != total) { _root.onEnterFrame = function() { incarcat = _root.getBytesLoaded(); total = _root.getBytesTotal(); _root.desenaza_bara_progres(50, 50, 100, 7, incarcat, total); conex_transm.send ("conexiune1", "metoda_apelata", incarcat, total); if (incarcat == total) { _root.gotoAndPlay(2); this.onEnterFrame = null; } else { _root.gotoAndStop(1); } }; } else { _root.clear(); gotoAndPlay(2); }

Ceea ce este diferit este apariţia unui obiect de tip LocalConnection şi folosirea metodei send din cadrul acesteia. Dacă aveţi mai multe Flashuri care vreţi să comunice între ele folosiţi alte denumiri în locul „conexiune1”, conexiunea între obiecte fiind identificată prin acest nume. Transmiterea de fapt nu face altceva decât să apeleze o metodă (respectiv „metoda_apelata”) cu anumiţi paramteri (incarcat şi total) – evident funcţia aceasta va trebui să o regăsim în Flashul A.

Primul Flash (A) îl vom construi similar cu B: din două cadre, al doilea conţinând o imagine iar primul avand următorul script asociat:

#include "grafix.as" incarcat = _root.getBytesLoaded(); total = _root.getBytesTotal(); if (incarcat != total) { _root.onEnterFrame = function() { incarcat = _root.getBytesLoaded(); total = _root.getBytesTotal(); _root.desenaza_bara_progres(50, 50, 100, 7, incarcat, total); if (incarcat == total) { _root.gotoAndPlay(2); this.onEnterFrame = null; }

Page 121: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

119

e els {

_r oot.gotoAndStop(1);

gotoAndPlay(2);

} }; }

e els{

}

În plus va trebui să tratăm într-un fel şi mesajele care vor veni de la SW

_root.createEmptyMovieClip("bara2",-100);

Ful B. Din acest motiv vom introduce un nou layer (cu două cadre – apăsaţi tasta F5 pentru a insera un nou cadru) în care vom adăuga scriptul:

var conex_recept = new LocalConnection(); conex_recept.metoda_apelata = function(incarcatB, totalB) {

_root.bara2.desenaza_bara_progres(50, 70, 100, 7, incarcatB, totalB); };

x_recept.connect("conexiune1"); cone

O preia cei doi parametri şi de

ele incarcat şi total care su

obiecte Flash, primul conţinând 3 butoane, la ac

bservăm metoda „metoda_apelata” care senează preloaderul SWF-ului B (preloaderul SWFului A fiind desenat în

scriptul de pe layer-ul original, primul cadru).

Tot în această funcţie, folsindu-vă şi de variabilnt specifice clipului A puteţi face un total şi desena un progressbar care

sa indice totalul celor două.

Ca exerciţiu realizaţi douăţionarea fiecăruia dintre ele se va încărca câte o poza (diferită) în cel de-al

doilea obiect Flash.

5.4 Crearea unui MP3 player

Putem realiza un mic player de MP3-uri. În versiunea 8 de Flash, ca şi în 6

ă tot timpul în situl nostru, pentru aceasta avem o lecţie separată (imediat după aceasta). Deoarece va

sau 7, nu sunt posibil decât un număr redus de acţiuni asupra unui fişier MP3: de exemplu schimbarea volumului sau schimbarea volumului pentru boxele stânga/dreapta.

MP3-ul pe care îl vom face nu va cânta muzic

Page 122: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

120

co

”, „cântă”, „oprire” (Butoanele vor avea numele: ff, pl, st,

rul instrumentului „select” se

ntru că deşi ar

dia în

nuare vom aduce în scenă din fereastra de componente (User Interface) o componentă de tip „list”. Numele de instanţă a acestei componente va fi „melodii” şi va fi locul în care vom afişa melodiile încărcate. Aşezarea în scenă a playerului meu este ca în imaginea alăturată.

Butoanele vor avea numele: ff,

nstitui o pagină de sine stătătoare, ne vom permite să facem acest player de MP3uri de dimensiuni destul de mari. Setaţi scena la 640x480 (aşa cum deja v-aţi obişnuit).

În continuare construiţi câteva butoane cu rol de „melodia anterioară”, „melodia următoare

rr - în această ordine). Vom construi de asemenea şi un cursor pentru a naviga în interiorul melodiei (de exemplul să ascultăm porţiunea din mijloc fără a trebui să reluăm melodia de la început). Acesta va avea forma unei săgeţi îndreptate în jos şi se construieşte astfel:

Cu ajutorul instrumentului text, setaţi fontul ca „Windings3”, dimensiunea 16 şi apăsaţi tasta „i’. Cu ajuto

lectaţi săgeata şi apăsaţi de două ori CTRL+B pentru a o transforma în element grafic. Construiţi un dreptunghi care ar putea acoperi săgeata tocmai făcută (dar nu deasupra acesteia) şi convertiţi-l în MovieClip. Duceţi acum acest MovieClip peste săgeată şi setaţi-i parametrul alpha din fereastra de proprietăţi la 0. Selectaţi atât dreptunghiul invizibil cât şi săgeata şi convertiţi-le (pe ambele în acelaşi timp) în MovieClip cu punctul de înregistrare în mijloc, jos şi cu numele de Linkage „cursor”.

Paşii pentru cursor au fost necesari ca să nu fiţi nevoiţi să agătaţi o săgeţică şi să o mutaţi (un MC în formă de dreptunghi – pe

ată ca o săgeată, este un dreptunghi) este mult mai uşor de „apucat”.

Creaţi un textField în care să putem scrie mai multe linii şi ca variabilă asociată treceţi „info” – în acest loc vom scrie informaţii despre melo

cărcată.

În conti

Figure 0-1 Interfaţă aproximativă (în dreapta avem lista, în stânga butoane de control şi

Page 123: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

121

pl

teţi pune acolo folosind un textfield. anumite date vor fi puse în scenă din

un fişier XML (lista.xml) cu următoarea truit şi dinamic din PHP prin procedee :

, st, rr (în această ordine).

Textul „MP3 Player” îl puCursoarele şi liniile ce reprezintăActionScript.

Melodiile vor fi ţinute într-structură (XMLul poate fi consînvăţate în exemplele anterioare)

<melodii>

textField cu informaţii)

<melodie fisier="Redn <melodie fisier="Anda <melodie fisier="

ex - Wish You Were Here.mp3" />

Kans</melodii>

Calugareanu - O portocala.mp3" /> as - Dust In The Wind.mp3" />

Vom începe cu declararea unor variabile sau a unor obiecte necesare pentru realizarea MP3 playerului. Dintre acestea, probabil, cel mai interesant va fi obiectul muzica de tip Sound pentru că este folosit pentru pr

esponsabil cu sunetul

ima oară. Puteţi remarca aducerea în scenă a cursoarelor în formă de săgeată respectiv noile nume cu care le vom referi:

muzica = new Sound(); //rdragging = false; //pentru a şti cand „navigăm” in melodie

getNextHighestDepth()); // cursor volum

umul

lungime = 250; // lungime control scroll in melodie var lista_melodii = new XML(); //lista melodiilor

xml_loaded = false; //lista e incarcata _root.attachMovie("cursor", "volum", _root._root.attachMovie("cursor", "pan", _root.getNextHighestDepth());// cursor balans _root.attachMovie("cursor", "cursor", -20); // „navigator” _root.createEmptyMovieClip("bara_total", _root.getNextHighestDepth());//pozitia in melodie _root.createEmptyMovieClip("bara_vol", _root.getNextHighestDepth()); //vol_root.createEmptyMovieClip("bara_pan", _root.getNextHighestDepth());//balans stanga - dreapta _root.cursor._y = 99; // ultimele trei sunt pentru a desena cateva bare

Funcţia „cântă” are rolul de a porni o nouă melodie:

function canta(fisier:String) { muzica.start(0); // pornim de la început //încărcăm în regim de streaming fişierul primit ca

Page 124: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

122

//parametru, melodia va începe automat să cânte: muzica.loadSound(fisier, true); }

P tim dimensiunea tota ărcat – încărcarea se încă după ce ace a funcţie ap âte secunde au fost adu r a fost adus din internet (de exe ezintă 20% din fişi – d

ct loaded:Number,

entru a naviga în interiorul melodiei ar trebui să ş înclă în secunde a melodiei şi până la ce secundă s-a

face în regim de streaming (deci în timp ce se audiază se va face şi rcarea). Vom putea şti sigur câte secunde are melodia doar

asta a fost adusă în întregime din Internet. Următoareroximează câte secunde are melodia în funcţie de c

se din Internet şi ce procent din fişieplu m dacă ştim că au fost aduse 30” şi că acestea repr

er, putem să aproximăm că melodia noastră are două minute şi jumătatee cinci ori mai mult decât 30”):

fun ion estimeaza_timp(curent:Number, filesize:Number) { return (Math.round(filesize*curent/loaded)); }

În continuare încărcăm XMLul ce conţine lista melodiilor şi pornim prima melodie:

lista_melodii.ignoreWhite = true;//ignoram spaţiile lista_melodii.onLoad = function() { //dacă s-a încărcat, adăugăm melodiile in componenta list: for (i=0;i<lista_melodii.firstChild.childNodes.length;i++) { melodii.addItem(lista_melodii.firstChild.

;

ţinem minte că este vorba despre prima melodie:

_melodii.firstChild. childNodes[0].attributes.fisier);

.

childNodes[i].attributes.fisier)} selectăm în list prima melodie: //

_root.melodii.selectedIndex = 0; //_root.nr_melodie = 0; //şi o încărcăm/cântăm cu funcţia definită mai sus canta(lista

//de asemenea reţinem că XMLul s-a încărcat cu succesxml_loaded = true; }; lista_melodii.load("lista.xml"); //evident, încărcăm lista

Page 125: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

123

Asupra listei de melodii (list-ului) trebuie să aplicăm un listener care are rolu ată altă melodie să înceapă să cân

l ca atunci când detectează că a fost selectte această melodie:

var listenerMelodii:Object = new Object(); listenerMelodii.change = function(obiect_apasat:Object) {

l obiectului de tip list:

canta(obiect_apasat.target.value); x; _root.nr_melodie = obiect_apasat.target.selectedInde

}; adăugăm listeneru//

melodii.addEventListener("change", listenerMelodii);

Funcţiile asociate fiecărui cursor (volum, balans, navigare) sunt tratate în continuare. De fapt funcţiile următoare nu ajută decât la descrierea modului în care cursoarele pot fi mutate în scenă:

// pentru navigarea în melodie: cursor.onPress = function() { _root.dragging = true; this.startDrag(true, 20, this._y,

(20+_root.lungime_incarcata), this._y); }; cursor.onRelease = function() { this.stopDrag(); poz_in_ms = _root.timp_total*(this._x-20)/ _root.lungime; muzica.start(poz_in_ms/1000); _root.dragging = false; }; cu r.onReleaseOutside = furso

_root.lungime; ;

t.volum._x = 40;

20, this._y);

nction() { this.stopDrag(); poz_in_ms = _root.timp_total*(this._x-20)/ muzica.start(poz_in_ms/1000) _root.dragging = false; }; //pentru modificarea volumului: _root.volum._y = 120; _roo_root.volum.onPress = function() { this.startDrag(true, 20, this._y, 1}; _root.volum.onRelease = function() {

Page 126: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

124

this.stopDrag(); _root.muzica.setVolume(this._x-20)

;

t.volum.onReleaseOutside = function() { this.stopDrag();

_x-20);

ânga-dreapta:

t, 270, this._y);

_root.pan.setVolume(this._x-170);

};_roo _root.muzica.setVolume(this.}; // si pentru balans st_root.pan._y = 120; _root.pan._x = 220;

.pan.onPress = function() { _roo this.startDrag(true, 170, this._y}; _root.pan.onRelease = function() {

this.stopDrag(); _root.pan.setVolume(this._x-170); }; _root.pan.onReleaseOutside = function() {

this.stopDrag(); };

F ne sunt uşor de construit şi înţeles: uncţiile celor patru butoa

// salt la următoarea melodie ff.on

următoarea melodie

ldNodes.length;

elodie;

utes.fisier);

este identic):

h;

ength;

Press = function() { _root.nr_melodie++; // trecem la _root.nr_melodie %= _root.lista_melodii.firstChild.chi

//îi memorăm numărul _root.melodii.selectedIndex = _root.nr_m // o încărcăm/audiem canta(_root.lista_melodii.firstChild.

childNodes[_root.nr_melodie].attrib }; // salt la melodia anterioară (rr.onPress = function() { _root.nr_melodie +=

odii.firstChild.childNodes.lengt _root.lista_mel _root.nr_melodie--; _root.nr_melodie %= _root.lista_melodii.firstChild.childNodes.l

dIndex = _root.nr_melodie; _root.melodii.selecte canta(_root.lista_melodii.firstChild. childNodes[_root.nr_melodie].attributes.fisier);

Page 127: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

125

}; pl.onPress = function() {//pornim o melodie oprită

//oprim melodia:

muzica.start(); }; st.onPress = function() { muzica.stop(); };

I toate informaţiile asociate melodiei: numele, albumul, anul producerii, cân reţul etc (în cazul în care aceste informaţii sunt disponibile). Preluarea şi a toare:

{

nformaţiile despre melodie pot fi regăsite într-un obiect ID3 care conţine

tăfişarea acestor informaţii se realizează cu ajutorul funcţiei urmă

muzica.onID3 = function() info = ""; if (muzica.id3.songname != "undefined") {

ame+"\n";

!= "undefined") { info += "cantaret: "+muzica.id3.artist+"\n";

"undefined") { t+"\n";

info += "melodie: "+muzica.id3.songn } if (muzica.id3.artist } if (muzica.id3.album != "undefined") { info += "album: "+muzica.id3.album+"\n"; } if (muzica.id3.year != "undefined") { info += "an: "+muzica.id3.year+"\n"; }

id3.comment != if (muzica. info += "comentarii: "+muzica.id3.commen } };

T care are rolu e lungă treb

ot motorul MP3 playerului se află totuşi în următoarea funcţie verifica dacă cele trei cursoare au fost mutate sau cât dl de a

uie să facă bara ce arată cât din melodie s-a încărcat:

_root.onEnterFrame = function() { if (xml_loaded){ // aici ne asigurăm ca totul a fost OK

ica.duration, ytesTotal());

//estimam durata melodiei curente: _root.timp_total = estimeaza_timp(muz

muzica.getBytesLoaded(), muzica.getB //vom desena bara pentru a indica bufferingul:

_root.bara_total.clear();

Page 128: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

126

_root.bara_total.lineStyle(0); _root.bara_total.moveTo(20, 100); _root.bara_total.lineTo(_root.lungime+20, 100); _root.bara_total.lineStyle(1, 0xff0000); _root.bara_total.moveTo(20, 102); // aici este calculată lungimea barei ce indica

ărcată:

a, 102);

t.muzica.duration) uzica.duration>20))

;

// cât din melodie a fost înc _root.lungime_incarcata = Math.round(_root.lungime*

t.timp_total); muzica.duration/_roo // ne asigurăm că valoarea este pozitivă deoarece // înainte de a se începe încărcarea, această // valoare este uneori mai mică decât 0.

<0) { if (_root.lungime_incarcata _root.lungime_incarcata = 0; } // desenarea efectivă a procentului din melodie _root.bara_total.lineTo (

incarcat 20+_root.lungime_ // dacă nu mutăm noi manual cursorul de navigare

sta se va // (de fapt capul pentru „play”), ace //deplasa singur în funcţie de nr. secunde cântate: if (!_root.dragging) { _root.cursor._x = 20+Math.round(_root.lungime*

l); muzica.position/_root.timp_tota }

odiei // dacă am ajuns la sfârşitul meloo if((_root.muzica.position+10>=_r

&& (_root.m {

rmătoarea meldoie: // trecem şi încărcăm u _root.nr_melodie++; _root.nr_melodie %= _root.lista_melodii.

th firstChild.childNodes.leng _root.melodii.selectedIndex = _root.nr_melodie;

lodii.firstChild.childNodes canta(_root.lista_me [_root.nr_melodie].attributes.fisier); } // desenăm bara de volum: _root.muzica.setVolume(_root.volum._x-20); _root.bara_vol.clear();

oot.bara_vol.lineStyle(0, 0); _r _root.bara_vol.moveTo(20, _root.volum._y);

20, _root.volum._y); _root.bara_vol.lineTo(1 _root.bara_vol.lineStyle(0, 0xFF0000); _root.bara_vol.moveTo(20, _root.volum._y+2); _root.bara_vol.lineTo(_root.volum._x, _root.volum._y+2);

Page 129: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

127

// şi bara ce indică balansul:

ot.muzica.setPan((_root.pan._x-220)*2); _ro _root.bara_pan.clear();

0);

, _root.pan._y); 000);

._y+2);

_root.bara_pan.lineStyle(0, _root.bara_pan.moveTo(170, _root.pan._y); _root.bara_pan.lineTo(270 _root.bara_pan.lineStyle(0, 0xFF0 _root.bara_pan.moveTo(220, _root.pan._y+2); _root.bara_pan.lineTo(_root.pan._x, _root.pan } };

C în ace

- omentul în

-

- eia prima

de melodii – s-ar putea implementa un playlist cu melodiile referate);

că dacă o

melodie se va încărca şi ea ocupând în acest fel banda melodiei celei mai recente. Astfel dacă utlizatorul apasă rapid

şi cele peste care s-a sărit.

- Lului exemplificat mai sus.

funcţi

Unude pr

am acesta este tot MP3 playerul pe care mi l-am propus să îl explic ne. Construiţi-l şi jucaţi-vă cu el. Veţi observa că: astă secţiu

vă lipseşte un buton de pauză (care să reia melodia din mcare a fost ooprită);

lista de melodii va fi mereu cântată în aceeaşi ordine – cea din XML (nu puteţi face „shuffle” acestei liste);

după terminarea listei am făcut în aşa fel încât să se rmelodie (nu aveţi opţiunea de a repeta o singură melodie sau un grupp

- după ce aţi pus exemplul online, melodiile se vor încărca mai greu (se vor încărca în regim de streamin). Problema estemelodie nu s-a terminat de încărcat şi totuşi utilizatorul selectează altă melodie, prima

de trei ori pe butonul „ff” (salt la următoarea melodie), nu se va încărca numai o singură melodie ci(rezolvare: s-ar putea face un „lock” în momentul în este selectată altă melodie şi melodia curentă nu a fost în întregime încărcată) ;

nu există un program PHP care să furnizeze lista fişierelor MP3 în formatul XM

Vă las ca temă „repararea” acestor neajunsuri (deşi MP3 playerul onează corect şi în această variantă).

l din motivele pentru care cred că Flashul ar trebui învăţat ca limbaj ogramare în şcoli este uşurinţa cu care obţinem lucruri interesante

Page 130: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

128

fără a exempcauzăpentru cru nu sco tr

anţă „melodii”.

scrie prea mult cod. Uneori acest cod nu este chiar foarte mic (ca de lu în cazul acestui player MP3) dar acest lucru nu este neapărat din

că nu s-ar putea să fie mai mic. Am prezentat versiunea mai lungă a arăta că poate fi făcut în întregime din ActionScript – acest lu

e te neapărat rău pentru că puteţi da orice interfaţă doriţi aplicaţiei ns uite de dumneavoastră.

Flashul ne pune la dispoziţie unele componente cu ajutorul cărora puteţi foarte repede dezvolta aplicaţii de genul MP3 playerului:

Din fereastra de compoente, din categoria Media – Player 6-7 selectaţi componenta MediaPlayback şi aduceţi-o în scenă. Daţi-i numele de instanţă „mp”, tot în fereastra de proprietăţi selectaţi tabul Parameters şi apăsaţi butonul „Launch Media Inspector” selectaţi „MP3”, iar în secţiunea „Control Visibility” selectaţi „On”. Închideţi Media Inspector. Redimensionaţi compoenta trecând în câmpul H (din fereastra de propriuetăţi) valoarea 80. Aduceţi în scenă şi o componentă „list”, redimensionaţi-o pentru a o putea alinia frumos cu compoenta Media Player şi setaţi-i numele de inst

Figure 0-2 - MP3 Player din două componente

Playerul nu va avea toate facilităţile celui pe care l-am făcut din script, dacă doriţi să mai adăugaţi dintre acestea puteţi să manipulaţi compoentele folosite cu ajutorul funcţiilor specifice (consultaţi pagina de Help a flashului pentru o listă completă a acestor funcţii).

Scriptul care trebuie ataşat în primul cadru al filmului Flash implică încărcarea XMLului, afişarea melodiilor în componenta list şi tratarea evenimentului de selectare a altei melodii (decât cea curentă) din listă:

var lista_melodii = new XML(); lista_melodii.ignoreWhite = true;

Page 131: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

lista_melodii.onLoad = function() { for(i=0;i<lista_melodii.firstChild.childNodes.length;i++)

melodii.addItem(lista_melodii.firstChild. childNodes[i].attributes.fisier);

_root.mp.contentPath = lista_melodii.firstChild. childNodes[0].attributes.fisier;

lista_melodii.load("lista.xml");

var listenerMelodii:Object = new Object();

{

}

};

listenerMelodii.change = function(obiect_apasat:Object) { //aşa pornim componenta MediaPlayer cu o nouă melodie: _root.mp.contentPath = obiect_apasat.target.value; }; melodii.addEventListener("change", listenerMelodii);

Deşi multe aplicaţii pot fi făcute numai din componente (programele fă

antă pentru exe

cute de-a gata), voi evita să le folosesc deoarece ratăm chiar felul în care se programează Flashul. Componentele vor fi folosite (sau au fost folosite) atunci când implementarea în Flash a sa este prea mare şi nu este relev

mplul în discuţie.

5.5

Pun MP3 player. Ce vom realiza aici totu fost 8 (s-ar put etului din n Flash mi-am dorit să fac un SW să afişeze câteva bare care să „da mp).

D folo n şir de valori re Mai mu ăsi în ar

Muzică de fundal pentru viitorul vostru site

layer-ul pentru muzica de fundal nu trebuie să fie atât de pretenţios ca şi este un „fals”. Problema care nu a

rezolvată încă în Flash (cel puţin nu până în versiunea de Flash tuşi să fie rezolvată pentru Flash 9) este aceea a analizei sunea to

piesele audio. Încă din primii mei paşi îcare nu numai să cânte MP3-urile ci F

nseze” în ritmul muzicii (la fel de exemplu ca în WinA

eşi încă nu se poate acest lucru, putem să păcălim utilizatorulsindu-ne de terţe programe care pot analiza melodiile şi furniza u

prezentând înălţimile barelor dintr-un anumit moment. lte informaţii despre cum poate fi analizată o melodie puteţi g

ticolul „In the Edge: Audio tips for Flash video producers” pe care îl puteţi găsi la adresa: http://www.adobe.com/devnet/flash/. Aplicaţia folosită în acest tutorial este Soundbooth.

129

Page 132: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

130

oundbooth) vom folosi resurse deja existente pe WEB. La adresa http://www.flashkit.com, puteţi găsi filme Flash, fonturi, sunete, muzică de background (Sound Loops). SoundLoops au proprietatea

a fi întreruptă ta la nesfârşit

făr

sculta prin intermediul

scena cea mai mică din toate exemplele pe care le-am rea

entru a insera cadre-keie în fiecare cadru al filmului. Cu excep

Pentru simplitate (sunt sigur că nu vreţi – deocamdată să va stresaţi cu felul în care se lucrează cu S

că după ce melodia ajunge la final, dacă este reluată, nu pare – chiar dacă melodia ţine doar 20 de secunde, ea se poate repe

ă ca cineva să-şi poată da seama când s-a terminat şi a reînceput. Pe situl indicat, aceste „sound loops” sunt aşezate în mai multe categorii (Rock, tehno, rap, alternative), personal îmi plac cele din categoria „Ambient” (alegeţi muzica de fundal în funcţie de situl pe care îl realizaţi, nu de muzica care vă place: nu veţi pune o muzică rock dacă veţi realiza un sit dedicat copiilor).

Când veţi descărca melodia preferată (pe care o puteţi a unui player ca cel pe care îl vom realiza aici), veţi fi puşi în

postura de a alege între formatele WAV, MP3 sau FlashTrack. Puteţi să descărcaţi sunetul în toate formatele, cel pe care îl vom folosi totuşi este FlashTrack (care de fapt este un fişier SWF ce conţine atât sunetul cât şi un şir de numere reprezentând valorile barelor la anumite intervale de timp; fişierul se va numi data.swf).

Probabil că acest exemplu va avea lizat: vrem ca playerul să fie afişat discret într-

un colţ şi să nu aibă decât funcţia pornit/oprit. Setaţi aşadar scena la dimensiunile 40 x 22. Playerul pe care îl construim este inspirat dintr-un player existent pe situl de unde aţi descărcat melodia de background dar este adaptat pentru Flash 8 (mai mult ca sigur după ce v-aţi obişnuit cu programarea AS din Flash8, v-ar fi fost greu sa vă adaptaţi la versiunea 5 de Flash).

Pentru început creaţi un MovieClip (gol) şi daţi-i numele de instanţă „player_mc” (va fi situat în poziţia 0,0). Editaţi noul MovieClip şi în interiorul său adăugaţi un nou strat (layer). În cel de-al doilea layer creaţi un MovieClip cu numele de instanţă „load”. Selectaţi primul strat şi apăsaţi de 8 ori tasta F6 p

ţia „a”-urilor care indică că în cadrul respectiv se află un script, cele două layere ar trebui să arate astfel:

Page 133: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

Figure 0-3 – Cum ar trebui să arate cadrele inserate (cu excepţia “a”-urilor din

fiecare cadru)

MovieClip-ul „load” construit puţin mai înainte în cel de-al doilea strat va fi folosit pentru încărcarea melodiei (de fapt al SWFului conţinând melodia). Din acest motiv în primul cadru din primul strat vom avea scriptul :

var doty = new Array (8);// un şir ce ne va ajuta ulterior load.loadMovie("data.swf");// încărcam melodia eqy = 20; // poziţia în care vor fi afişate barele (axa Y) eqx =6; // respectiv pe axa X

În cel de-al doilea cadru vom verifica dacă SWFul conţinând sunetul a fost încărcat în întregime. Deşi este o metodă artificială, era metoda folosită în Flash 5 (în care este făcut „data.swf”):

// aici testăm variabila „load” din filmul „load” // când se va termina de încărcat, va avea valoarea „yes”:

if (load.load == "yes") { gotoAndPlay(4);

}

În cazul în care nu s-a făcut saltul la cadrul al 4-lea (deoarece sunetul de fu

ndPlay(2); // script din cadrul 3, layer 1

ndal nu s-a încărcat în întregime), în cadrul al treilea vom face un salt înapoi în cadrul 2 pentru a re-testa încărcarea melodiei:

gotoA

Pconmuvom se aude nimic). De asemenea vo

re vom trece la următorul cadru din filmul nostru, cadru ce are rolul de a modifica barele în funcţie de şirul de va c

resupunând că s-a terminat de încărcat, în cadrul al patrulea vom sa” în ritmul strui într-un „for” cele 8 bare şi 8 puncte care vor „dan

zicii. De asemenea vom poziţiona corect fiecare bară şi fiecare punct, scala barele pe axa Y la 1% (iniţial nu

m reţine (în şirul doty construi în primul cadru) poziţiile punctelor. Pentru a porni muzica din „load” va trebui să apelăm o funcţie de tipul gotoAndPlay acestui MovieClip după ca

numere din „data.swf”. Aşadar cadrul cu numărul 4 de pe primul strat onţine scriptul:

131

Page 134: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

132

r (i=0; i<8; i++) { fo this.createEmptyMovieCl

{ ip("bar"+i, 10+i);

beginFill(0x000000, 50);

"+i]._yscale = 1;

l doty:

with (this["bar"+i]) moveTo(-1, 0); lineTo(1, 0); lineTo(1, -20); lineTo(-1, -20); lineTo(-1, 0); } this.createEmptyMovieClip("eqdot"+i, 20+i); // va invităm să scrieţi liniile următoare // într-o structură „with” (ca mai sus): this["eqdot"+i].beginFill(0x000000, 100); this["eqdot"+i].moveTo(-1, 0); this["eqdot"+i].lineTo(1, 0); this["eqdot"+i].lineTo(1, -1); this["eqdot"+i].lineTo(-1, -1); this["eqdot"+i].lineTo(-1, 0); this["bar"+i]._x = eqx+i*4; this["eqdot"+i]._x = eqx+i*4; this["bar"+i]._y = eqy; this["bar doty[i] = 0; // poziţiile punctelor sunt în funcţie de şiru

y-1-doty[i]; this["eqdot"+i]._y = eq} load.gotoAndPlay("play"); this.gotoAndPlay(5); status = "play";

T sul” barelor. „Dansul” este de fap m arelor – deci un şir de numere pe car oate fi con lodie.

C deşi este ese a un caz con are encodate 1280 de val em câte 1280/20 = 64 de te două valori la un mo ăr între 0 şi 99 adică pro ntu i bare). Deci în total pentru o afiş amnă că în fiecare secundă vom put arelor de 4 ori (câte un cadru la

rebuie să sincronizăm melodia cu „dant un şir de nu ere ce indică scalarea be îl putem controla pe când melodia este un sunet ce nu p

in metrolat ci doar putem şti cât timp a trecut la un moment dat d

a o paranteză pe care nu trebuie neapărat să o înţelegeţi (odia) vom dnţa felului în care sincronizăm barele cu mel

ecret: folosim o melodie de 20 de secunde carori, ceea ce înseamnă că pentru fiecare secundă av

âvalori. Vom avea 8 bare şi fiecare va folosi cent un numm dat (deoarece două valori indică

ce l necesar pentru redimensionarea une = 4 înseare vom folosi 16 valori. Cum 64/16

ea să „reîmprospătăm” poziţiile b

Page 135: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

133

250valori fiin

I în MovieClip-ul „load” deoarece în el s-a drul cu numărul 5 reţinem timpul în care a început melodia pentru a putea şti în fiecare moment cât timp a trecut şi a afi

ms). Calculele acestea sunt fictive, diferind de la caz la caz, adevăratele d disponibile în „data.swf”.

nformaţiile necesare le vom găsiîncărcat „data.swf”. În ca

şa barele curente. Deocamdată în cadrul al cincilea vom scrie scriptul:

starttime = getTimer(); loop = "0"; // un contor an numărului de repetiţii maxloops = "300"; // numărul maxim de repetiţii

În cadrul al şaselea calculăm timpul care a trecut şi care este setul de 16 numere ce indică poziţia celor 8 bare. Odată setul găsit nu avem decât să redimensionăm barele. Comportamentul punctelor este următorul: dacă punctul se află mai jos decât valoarea maximă pe care o va atinge bara atunci el este mutat în această valoare maximă. Dacă punctul se află deja deasupra barei atunci el va descinde cu 3 pixeli:

// calculăm timpul scurs de la începutul unei noi bucle // ale melodiei: playtime = getTimer()-starttime; // calculăm poziţia celor 16 numere (dimensiunile barelor) j = int(playtime/((load.step)));

:

]/5;

// vom modifica fiecare bara / punct: for (i=0;i<8;i++){ // dacă melodia se aude calculăm poziţiile curente: if (status=="play") { sc = Number(substring( this.load["data"+j], (i*2)+1, 2)); }else{ // dacă nu cântă vom duce barele şi punctele pe 0 sc = 0; } // scalăm barele: this["bar"+i]._yscale = 1+sc; // pozitia punctului şi dacă acesta va descinde sau nu: if (sc>=doty[i]) { doty[i]=sc; }else{ doty[i]-=3; }

ea punctului: // repoziţionar this["eqdot"+i]._y=eqy-1-doty[i}

Page 136: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

134

Î că am terminat de afişat toate bar rmativ reluăm procesul pen

am terminat bucla curentă:

n cel de-al şaptelea cadru ne întrebăm daele (deci şi melodia s-a terminat). În caz afitru o nouă buclă:

if (j<load.rows) { // daca nu gotoAndPlay(6); // sărim la cadrul anterior: reafiş

(loop<maxloops-1) { am

ţii

= getTimer(); // resincronizam cu muzica / şi reluăm barele

} else if // am terminat bucla; si nu atins nr maxim de repeti

incrementăm contorul loop++; //starttime

gotoAndPlay(6); / }

După cum se observă nu se ajunge în cadrul cu numărul opt decât dacă s-a dec opt vom avea scriptul:

ajuns la numărul maxim dadrul

e repetiţii. În acest caz nu vom face altceva ât să oprim filmul. În c

stop();

În primul ca vom scrie un script care are cineva apasă pe micul nos tru va face parte dintr-un site şi va fi aşezat într-un colţ; dacă cineva vrea să oprească muzica, este de

dru al celui de-al doilea strat (layer) rolul de a opri muzica în momentul în care

MovieClip (aşa cum am zis MovieClip-ul nostru

ajuns să apese pe barele „dansatoare”). Aşadar, în primul cadru de pe al doilea strat vom scrie scriptul:

// creăm un nou MovieClip cu rol de buton: this.createEmptyMovieClip("mute", 10000); this.mute.beginFill(0, 1); // dar îl facem transparent… this.mute.moveTo(0, 0); this.mute.lineTo(0, 22); // desenăm un dreptunghi cât this.mute.lineTo(40, 22); // toată zona în care se miscă

is.mute.onPress = function() { // şi dacă îl apăsăm:

);

s._parent.status = "play";

this.mute.lineTo(40, 0); // barele noastre this.mute.lineTo(0, 0); th if ((this._parent.status == "stop") || (this._parent.status == "undefined")) { // fie îi dăm drumu (play) this._parent.load.gotoAndPlay("play" this._parent.gotoAndPlay(5); thi }else{ // fie îl oprim dacă deja cânta: this._parent.load.gotoAndPlay("mute"); this._parent.gotoAndStop(0); this._parent.status = "stop";

Page 137: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

} };

T uitaţi să puneţi în ace rcat de la adresa http :

ot ce mai aveţi de făcut este să testaţi Flashul (nu ălaşi director fişierul „data.swf” pe care l-aţi desc

://www.flashkit.com). Imaginea mărită a LoopPlayer-ului arată astfel

Figure 7-0-4 – Sunet cu imagine trucată

P tutorial pentru a face şi alte chiar în cadrul situ

uteţi să vă folosiţi de explicaţiile date în acest tipuri de LoopPlayere (mai multe idei le puteţi găsi lui flashkit).

5.

provine din latinescul t.

Fractalii cei ndelbrot, aici vom da totuşi metode d şi mai uşor de înţeles. Vo re generează un arbore după numit „curba dragonului”.

Procesul de construi cel mai multe ori unul recursiv. Din acest mo est termen.

Recursivitatea est e sunt folosite ele în

şi pe oricare din următoarele valoarea sumei dintre numărul de pe penultima poziţie şi antipenultima (1,1,2,3,5,8,13,21,34,55…

6 Fractali

Un fractal este o formă geometrică care poate fi subdivizată şi fiecaredintre aceste subdiviziuni să fie o copie în miniatură a întregului. Termenul

fractus care înseamnă rupt sau fractura

mai cunoscuţi sunt cei din mulţimea lui Mae realizare a unor fractali mai simpli

m vedea pentru început un fractal simplu ca care vom realiza unul mai complex

re a unui fractal este de tiv voi încerca să vă familiarizez cu ac

e o metodă de a defini funcţii carsele pentru a fi definite (dar la o altă scară). Un exemplu clasic în acest

sens este şirul lui Fibonacci: un şi de numere care are pe primele două poziţii valorea 1

135

Page 138: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

136

Flash care implementeaza şirul lui Fibonacci şi afişează toate elementele şirului mai mici ca 100.000 este: etc). Exemplul în

function fibo (nr1:Number, nr2:Number){ trace (nr1); if (nr1<100000) fibo(nr2, nr1+nr2); } fibo (1,1);

În fiecare funcţie recursivă trebuie ca apelul funcţiei din interiorul său să fie condiţionată pentru a nu se forma o buclă infinită. În exemplul nostru, funcţia nu se va mai auto-apela dacă nr1 depăşeşte valoarea 100.000.

tru realizarea programelor recursive (daca va interesează mai mult subiectul, su

ă fie salvată corect).

E anume prin crearea la fiec r direct în acesta (ca var

U u

e (ip

ActionScript nu este nici pe departe limbajul de programare ideal pen

gerăm Java, C++, Delphi etc.). Problema majora pe care o are Flashul constă în felul în care ActionScriptul îşi salvează stiva (sper ca aceasta să fie reparată în curând dar deocamdată vă voi povesti despre această eroare).

Atunci când se apelează recursiv o funcţie, ar trebui ca variabilele date ca parametru să nu fie afectate. Totuşi nu se întâmplă aşa ceva în Flash (pentru exemple mici s-ar putea ca această stivă s

xistă o metodă totuşi de a simula această stivă şi MovieClip şi salvarea dateloare execuţie a unui

iabile-membru ale MovieClip-ului).

n prim exempl

În cel de-al doilea exemplu vom construi curba dragonului.

Curba dragonului porneşte de la o linie. Contează dacă linia este trasată de la stânga la dreapta sau invers (deci am putea considera că avem de-a face cu vectori). Linia trasată va fi ipotenuză pentru un triunghi dreptungic isoscel cu vârful aflat în stânga vectorului. Catetele vor forma şi ele vectori orientaţi din vârful triunghiului dreptunghic către cele două unghiuri ascuţite (de 450). Catetele astfel construite vor fi vectorii de pornir

otenuzele) pentru noile triunghiuri dreptunghice Procesul este reprezentat în imaginea următoare:

Page 139: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

Figure 5 – Primele trei iteratii din constructia dragonului

pă ce au fost efectua

Procesul poate continua la nesfârşit, dar, noi ne vom opri duţi un număr de paşi (număr care va fi dat ca parametru către funcţia

recursivă).

În final (după 14 iteraţii) imaginea va arăta astfel:

Figure 6 - Dragon dupa 14 iteratii

La fiecare apel al funcţiei vom crea un nou MovieClip. Pentru a diferenţia noul MovieClip de restul, în numele acestuia vom include parametrii de intrare ai funcţiei. Parametrii de intrare nu pot fi niciodată la fel deoarece de fiecare dată trimitem de fapt coordonatele între care vrem să co ne putem da seama că niciodată două linii nu se vor suprapune (deci nu vor exista două MovieClipuri cu construi decât dacă nu am epuizt vor decrementa pe baza apelului recursiv rsivitate de care vorbeam mai î

După crearea noului jumătatea segmentului prim ă segmente reprezentând catetele di

Liniile pe numai pentru MovieClipurile care au .

nstruim noua linie. Din algoritmul de construire,

acelaşi nume). MovieClipurile nu se vor încă numărul de paşi stabiliţi (care se

– de fapt asta este condiţia din recunainte).

MovieClip vom stabili care esteit ca parametru şi apoi vom construi cele dou

n explicaţiile date mai înainte.

care ne propunem să le desenăm vor fi pasul mai mic decât 1 (adică 0)

137

Page 140: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

138

Scriptul (pe care îl vom explica şi pe parcurs este următorul:

// vom scrie functia ca făcând parte din clasa MC: MovieClip.prototype.dragon = function( x1:Number, y1:Number, x2:Number, y2:Number, pas:Number) { // aici începe funcţia // daca pasul este mai mare ca 0, vom calcula poziţia // vârfului şi vom reapela funcţia: if (pas>0) { // creăm noul MovieClip: this.createEmptyMovieClip(

y2].a =

y1+y2)/2);

i: this["mc_"+x1+"_"+y1+"_"+"_"+x2+"_"+y2].c=

+x2+"_"+y2].dragon "+"_"+x2+"_"+y2].d,

} 1:

"mc_"+x1+"_"+y1+"_"+"_"+x2+"_"+y2, _root.getNextHighestDepth()); // mijlocul segmentului trimis ca paramentru: this["mc_"+x1+"_"+y1+"_"+"_"+x2+"_"+ ((x1+x2)/2); this["mc_"+x1+"_"+y1+"_"+"_"+x2+"_"+y2].b = (( // calculăm poziţia vârfului triunghiulu

this["mc_"+x1+"_"+y1+"_"+"_"+x2+"_"+y2].a+ this["mc_"+x1+"_"+y1+"_"+"_"+x2+"_"+y2].b-x2; this["mc_"+x1+"_"+y1+"_"+"_"+x2+"_"+y2].d=

"+y1+"_"+"_"+x2+"_"+y2].a+y2- this["mc_"+x1+"_ this["mc_"+x1+"_"+y1+"_"+"_"+x2+"_"+y2].b;

drepte: // apelăm apoi funcţia pentru noile // pentru prima dreaptă: this["mc_"+x1+"_"+y1+"_"+"_" (this["mc_"+x1+"_"+y1+"_ this["mc_"+x1+"_"+y1+"_"+"_"+x2+"_"+y2].c, x1, y1, pas-1); // şi pentru a doua: this["mc_"+x1+"_"+y1+"_"+"_"+x2+"_"+y2].dragon (this["mc_"+x1+"_"+y1+"_"+"_"+x2+"_"+y2].d, this["mc_"+x1+"_"+y1+"_"+"_"+x2+"_"+y2].c, x2, y2, pas-1); // desenam doar dacă pasul este mai mic decât // desenul se va face mereu în root: if (pas<1) { _root.moveTo(x1, y1); _root.lineTo(x2, y2); } }

Page 141: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

139

// stabilim tipul liniei cu care se va desena: _root.lineStyle(0,0); // apelăm funcţia având ca parametri prima dreaptă // şi numărul de paşi(14): _root.dragon(150, 250, 300, 250, 14);

C e la sfârşit fără nici un fel de animaţie. Ma emora pozcod

u acest algoritm imaginea apari interesant ar fi dacă în loc să trasaţi liniile toate deodată aţi miţiile lor şi să le desenaţi în final într-o funcţie de tip onEnterFrame. La ul anterior puteţi să adăugaţi ca primă linie:

var numere:Array = new Array();

D

1)

upă care if-ul în care se făcea desenarea va deveni:

if (pas< { _root umere.push(x1, y1, x2, y2);.n

k = 0; // pentru a sti cand desenam

_root. }

Şi în final vom construi funcţia de desenare:

_root.onEnterFrame = function() { if (k>-1) { moveTo(_root.numere[k], _root.num lineTo(_root.numere[k+2], _root.n

ere[k+1]); umere[k+3]);

if (k<_root.numere.length) { k += 4; } } };

A se realizează automat de către _root.onEnt

pelul se face la fel ca înainte, desenareaerFrame.

Page 142: Flash8 in exemple - Alexandru Ioan Cuza Universityflash/data/Flash8_In_Exemple.pdf · 2008-01-04 · realizarea unui caleidoscop. În primul rând pentru realizarea unui caleidoscop

Flash8 în exemple http://www.infoiasi.ro/~vcosmin Vârlan Nicolae Cosmin http://www.infoiasi.ro/~flash

140

C

1

............................................................... 5 .3 Acumularea pixelilor.................................................................. 8 .4 Efect de lupă .............................................................................. 10

1.5 Schimbarea cursorului mouse-ului ........................................ 13 1.6 Decodificarea textului .............................................................. 15

2 Jocuri în Flash… nimic mai simplu ................................................ 19 2.1 Curbă Bezier cu două puncte de control ............................... 19 2.2 Adăugarea unei funcţii clasei MovieClip.............................. 23 2.3 Construirea unui puzzle .......................................................... 24

3 XML – metoda ideală pentru structurarea datelor ...................... 35 3.1 Construirea unei agende folosind XML ................................ 35 3.2 Realizarea unei cărţi de oaspeţi (GuestBook) ....................... 42 3.3 Album foto – foto SlideShow .................................................. 60 3.4 Managementul fişierelor aflate pe server.............................. 73

4 Comunicarea în timp real ................................................................ 85 4.1 Transmiterea datelor folosind SOCKETURI......................... 85 4.2 Utilizarea socketurilor pentru realizarea desenelor ............ 96

5 Şi câteva exemple “de efect” ......................................................... 100 5.1 Efecte aplicate asupra imaginilor ......................................... 100 5.1 Construirea unui preloader ................................................... 108 5.2 Mişcări “elastice” ale MovieClip-urilor ............................... 113 5.3 Comunicarea între obiectele Flash de pe aceeaşi pagină .. 115 5.4 Crearea unui MP3 player....................................................... 119 5.5 Muzică de fundal pentru viitorul vostru site ..................... 130 5.6 Fractali ...................................................................................... 136

uprins

Guizmos ............................................................................................... 1 1.1 Caleidoscop.................................................................................. 1 1.2 Text în jurul unei sfere11


Recommended