În acest tutorial vom crea un sistem de text similar cu ceea ce vedeți într-o mulțime de jocuri de rol. Clasa noastră va afișa în mod dinamic o pictogramă pentru caractere în timp ce vorbește și va tasta fiecare literă cu litera.
Iată un exemplu de sistem de text pe care îl vom crea:
Creați un nou fișier Flash (Actionscript 3). Setările filmului dvs. vor varia în funcție de joc. Pentru aceasta demonstratie imi fac filmul ca 500x300, cu fundal negru si 30 fps.
Veți afișa cel mai probabil modulul text peste o imagine sau animație din joc. Pentru acest demo folosesc doar o imagine pe care am aruncat-o impreuna cu cateva din personajele din jocurile mele care stau intr-un camp de zapada.
Puneți imaginea de fundal pe un strat numit "fundal".
Creați un nou film MovieClip pe scenă (Insert> MovieClip) numit "RPGText".
În Proprietățile simbolului bifați "Exportați pentru acțiuni" și setați numele clasei la "RPGText". Vom folosi mai târziu acest nume de clasă pentru a conecta codul la acest film.
Faceți clic pe OK. Dacă vedeți aici un avertisment că definiția clasei nu a putut fi găsită, este bine. Aceasta inseamna doar ca nu exista nici un cod care sa se lege de acest simbol (inca).
Dă-ți filmului numele de instanță "rpgText". Amintiți-vă, când vorbesc despre "RPGText" (majusculă) mă refer la clasă (sau MovieClip); "rpgText" (cu litere mici) este numele unui instanță din acea clasă.
Desenați un dreptunghi în interiorul noului dvs. RPGText MovieClip. Acesta va fi fundalul pentru pictogramele de caractere și bule de vorbire. Proiectați-vă cu toate acestea vă place, dar ar trebui să se întindă pe întreaga lățime a filmului dvs. și să fie suficient de scurt încât să nu acopere prea mult din joc.
Mi-am făcut aria mea de 500px lățime (pentru a se potrivi cu filmul meu) și 100px înălțime. L-am umplut cu un gradient de la # 666666 la # 999999 (gri închis la gri mai deschis).
Sfat rapid: pentru a desena un dreptunghi de o anumită dimensiune, selectați instrumentul dreptunghi și Alt-clic pe scenă. Veți primi o casetă de dialog unde puteți introduce dimensiunile dreptunghiului.
Creați un nou strat în interiorul RPGText MovieClip numit "pictogramă". Creați un nou videoclipClip pe acest strat numit "characterIcon" și dați-i numele de instanță "characterIcon".
În interiorul characterIcon MovieClip creează două straturi noi: "pictograme" și "etichete". Stratul de pictograme va conține toate pictogramele caracterului dvs. (fiecare pe propriul cadru cheie), iar stratul de etichete va conține etichete de cadre pe care le vom folosi pentru a afișa caracterele la momentul potrivit.
Importați (sau atrageți Flash) o pictogramă pentru fiecare dintre personajele din jocul dvs. care vor vorbi. Pentru acest demo am făcut un 75x75 px JPG pentru fiecare dintre personajele mele. Adăugați pictogramele la icoane layer, făcând un nou keyframe pentru fiecare caracter. Ordinea în care apar acestea nu este importantă, dar asigurați-vă că fiecare pictogramă este plasată la x: 0, y: 0, astfel încât acestea nu par să sară în jur când comutați între caractere.
Acum creați un nou cadru cheie pe fiecare cadru al dvs. etichete strat. O modalitate rapidă de a face acest lucru este să selectați toate cadrele și să atingeți F6.
Selectați fiecare cheie cheie etichetă unul câte unul și adăugați o etichetă de cadru care corespunde cu numele caracterului care apare în acel cadru. Dacă adăugați câteva cadre goale (F5) între cadrele cheie, va fi mai ușor să citiți etichetele de cadre, etichete cadrele cheie stau aliniate cu dvs. icoane keyframes.
Asigurați-vă că fiecare dintre etichetele dvs. are un nume unic. Dacă aveți două caractere cu același nume, va trebui să le diferențiați cumva ("John_L" și "John_K" de exemplu).
Întoarceți-vă la RPGText MovieClip și creați un nou strat numit "textBackground".
Desenați un balon de vorbire. Am tras un simplu bule cu colțuri pătrată, dar poți să-ți faci aspectul așa cum vrei tu. Asigurați-l suficient de mare încât să umple cea mai mare parte a dreptunghiului de fundal și să stea frumos lângă pictogramele caracterului tău.
Selectați balonul de expresie și convertiți-l la un clip video (Modificați> Conversie la simbol). Acum că este un filmClip, putem adăuga un filtru de umbră. Am setat a mea la negru, puterea de 50%, distanța de 5px și distanța de 1px.
Creați un nou strat în RPGText MovieClip numit "text". Utilizați instrumentul de text pentru a desena o casetă de text. Faceți-o să se potrivească doar în interiorul marginilor graficului cu bule de vorbire.
Faceți un câmp de text dinamic multiplu cu numele de instanță "txt". Nu uitați să încorporați fontul dacă nu utilizați textul sistemului. Folosesc Courier 13pt.
Avem nevoie de o modalitate pentru jucător să avanseze la următorul bloc de text atunci când playerul a terminat de citit. Să adăugăm un mic buton "în urmă" în colț.
Creați un nou strat în RPGText MovieClip numit "buton". Adăugați un nou simbol al butonului numit "b_next". Proiectați cele patru stări ale butonului dvs., oricum doriți. Am folosit o săgeată mică în jos ca simbol pentru buton, deoarece văd că într-o mulțime de jocuri și presupun că jucătorii sunt familiarizați cu asta.
Puneți butonul în colțul din dreapta jos, deasupra balonului dvs. de vorbire. Nu vă faceți griji că ați dat un nume de instanță. Voi explica de ce mai târziu.
Creați un nou fișier Actionscript numit "Main.as" și adăugați acest cod pentru a crea shell-ul gol pentru clasă:
pachet import flash.display.MovieClip; public class Main extinde MovieClip // CONSTRUCTOR public function Main ()
Setați Main ca clasă de documente în fișierul dvs. Flash. Dacă doriți o reîmprospătare rapidă în utilizarea unei clase de documente, acest sfat rapid de la Michael Williams este una dintre cele mai bune explicații pe care le-am văzut.
Dacă utilizați acest lucru într-un joc, probabil veți alege să îl puneți în altă parte, dar pentru moment îl vom adăuga la Clasa de documente. Adăugați acest cod la funcția constructor din Principal clasă:
var textBlocks: Array = Array nou (["Kid", "Uite, un robot!"], ["Abe", "BLEEP-BLOOP.Sunt un inginer botanic autonom.You can call me ABE. Kid "," Hi Abe, Meet Frosty the Snowman ", [" Frosty "," Happy Birthday! "]," Abe "," Frosty " Aceasta broasca iti apartine? "," Frog "," Ribbit ... "," Kid "," Nu l-am vazut niciodata inainte, nu esti broasca rece? ", , "Ribbit ..."]); rpgText.textBlocks = textBlocks;
Aici creăm o matrice bidimensională (o matrice care conține alte matrice) pentru a ține scenariul pentru scenă. Înainte de a schimba ceva, aruncați o privire la modul în care este structurat. Fiecare matrice este un bloc de text separat care conține două elemente. Primul este numele personajului, iar al doilea este textul pe care îl va vorbi. Blocurile de text sunt listate în ordinea în care vor apărea în scenă.
Ultima linie trimite doar textBlocks array la rpgText MovieClip (amintiți-vă că "rpgText" este numele de instanță al RPGText MovieClip pe scenă). Mai multe despre asta mai târziu.
Continuați și editați această secțiune pentru a se potrivi scenei dvs. Acordați o atenție deosebită faptului că numele de caractere corespund exact denumirilor pe care le-ați utilizat pentru etichetele de cadre din characterIcon MovieClip.
Suntem gata în sfârșit să scriem codul pentru clasa RPGText.
Creați un nou fișier Actionscript numit "RPGText.as" și adăugați acest cod:
pachet import flash.events.Event; importul flash.events.MouseEvent; import flash.display.MovieClip; import flash.media.Sound; clasa publică RPGText extinde MovieClip private const SPEAKER: int = 0; private const TEXT: int = 1; privat var _currentTextBlockIndex: int = 0; privat var _currentTextBlock: String; private var _textBlocks: Array; // funcția publică CONSTRUCTOR RPGText ()
Aceasta este doar o coajă de bază pentru clasă. Nu face nimic încă, dar să aruncăm o privire la ceea ce există:
(Notă: Folosesc sublinierea în numele variabilelor pentru a indica variabilele private.)
De la noi _textBlocks variabilă este privată, vom avea nevoie de o modalitate de a accesa acea variabilă din Principal clasa în cazul în care suntem de configurare a blocurilor de text. O vom face prin crearea unei funcții "setter". Adăugați acest lucru la clasa RPGText chiar sub funcția constructorului:
funcție publică set TextBlocks (txt: Array): void _textBlocks = txt;
Lucrul interesant pentru setterii în Flash este că putem accesa această funcție ca și cum ar fi o proprietate publică a clasei RPGText. Ceea ce am făcut exact pe linia 21 a clasei principale din pasul 11:
rpgText.textBlocks = textBlocks;
Adăugați această funcție la clasa RPGText:
funcția privată updateText (e: Event): void if (txt.text.length < _currentTextBlock.length) txt.text = _currentTextBlock.substr(0, txt.text.length+1); else removeEventListener(Event.ENTER_FRAME, updateText); fillText();
Aceasta este funcția de bază a clasei, în care are loc scrierea scrisă cu literă. Să aruncăm o privire mai atentă la ceea ce se întâmplă aici:
Adăugați această funcție la clasa RPGText:
funcția privată fillText (e: MouseEvent = null): void txt.text = _currentTextBlock; în cazul în care (_currentTextBlockIndex < _textBlocks.length-1) addEventListener(MouseEvent.CLICK, nextTextBlock);
Scopul principal al acestei funcții este umplerea txt câmp text cu textul din _currentTextBlock (linia 37). Dacă lăsăm animația să se joace, updateText funcția ar trebui să aibă grijă de asta, dar este bine să vă asigurați că nimic nu a mers prost. De asemenea, putem conecta această funcție la butonul "următor" pentru a permite jucătorilor să sări peste animația textului și să umple imediat câmpul de text cu întregul bloc text.
Observați că această funcție acceptă un argument MouseEvent, dar am setat valoarea sa implicită la null. Acest lucru ne permite să folosim această funcție cu un ascultător MouseEvent, deoarece va accepta evenimentul. Deoarece oferim evenimentului o valoare implicită, putem apela și funcția fără a trimite un eveniment așa cum facem la sfârșitul updateText funcţie.
După ce umplem câmpul de text, facem un cec pentru a vedea dacă acesta este ultimul bloc de text din matrice (dacă _currentBlockIndex este mai mică decât numărul elementelor din _textBlock array). Dacă nu, adăugăm un CLICK listener pentru a declanșa o funcție numită nextTextBlock pe care o vom scrie în continuare.
Amintiți-vă când am creat butonul "următor" și am spus să nu vă faceți griji că ați dat un nume de instanță? Ați observat în ultima etapă cum am atașat CLICK listener la întregul RPGText MovieClip în locul butonului? Acest lucru face ca jucătorul să poată face clic oriunde pe MovieClip pentru a avansa textul. Chiar nu avem nevoie de buton, dar îmi place să pun unul în așa, încât există un indiciu că faceți clic pentru a avansa textul.
Desigur, aceasta este doar o preferință personală a mea. Dacă doriți, puteți da butonului un nume de instanță și, în schimb, atașați butonul CLICK. Pur și simplu găsesc zona mai mare de lovit pentru a fi mai ușor de utilizat.
Înapoi la afaceri. Adăugați această funcție la clasa RPGText:
funcția privată nextTextBlock (e: MouseEvent): void removeEventListener (MouseEvent.CLICK, nextTextBlock); txt.text = ""; // ștergeți textul _currentTextBlockIndex ++; _currentTextBlock = _textBlocks [_currentTextBlockIndex] [TEXT]; // setați textul characterIcon.gotoAndStop (_textBlocks [_currentTextBlockIndex] [SPEAKER]); // setați pictograma de caractere addEventListener (Event.ENTER_FRAME, updateText); // începe actualizarea textului addEventListener (MouseEvent.CLICK, fillText);
Primele trei linii sunt destul de simple. Scoateți ascultătorul MouseEvent, ștergeți câmpul de text și incrementați _currentTextBlockIndex var pentru a indica următorul bloc de text.
Linia 47 folosește funcția TEXT constant pentru a obține șirul de text curent din _textBlocks și alocați-o _currentTextBlock.
Apoi vom folosi VORBITOR constant pentru a obține numele personajului. Deoarece numele caracterelor se potrivesc cu etichetele de cadre din secțiunea noastră characterIcon MovieClip putem folosi gotoAndStop pentru a trimite mesajul characterIcon MovieClip în cadrul care afișează pictograma pentru caractere.
În cele din urmă, adăugăm un ascultător al evenimentului pentru a începe să tastați pe noul șir de text și apoi să adăugați un CLICK listener pentru a rula fillText când se face clic pe MovieClip.
Aproape că am terminat, trebuie să adăugăm o funcție care va face totul începută. O vom face cu o funcție publică numită "startText". Deoarece aceasta este o funcție publică, lăsați-o aproape de vârful clasei RPGText, chiar sub limbajul textBlocks setter:
funcția publică startText (): void _currentTextBlock = _textBlocks [_currentTextBlockIndex] [TEXT]; characterIcon.gotoAndStop (_textBlocks [_currentTextBlockIndex] [DIFUZOR]); addEventListener (Event.ENTER_FRAME, updateText); addEventListener (MouseEvent.CLICK, fillText);
Arată cunoscut? Acest cod are exact același lucru ca și codul nextTextBlock funcţie. Setează pictograma textului și caracterului curent și adaugă ascultătorii evenimentului updateText și fillText. Din moment ce această funcție rulează numai atunci când textul începe mai întâi, nu trebuie să vă faceți griji cu privire la ștergerea câmpului de text sau la incrementarea acestuia _currentTextBlockIndex ca și noi nextTextBlock.
Acum avem o modalitate accesibilă publicului pentru a începe textul. Să o folosim.
Adăugați această linie în partea de jos a funcției Constructor de clasă principală:
rpgText.startText ();
Aceasta este doar apelarea funcției startText în cadrul clasei RPGText. Asta ar trebui să facă totul.
Ar trebui să vă puteți testa acum filmul și să vedeți tot ce funcționează. Există doar un singur lucru care lipsește: sunetul.
Găsiți (sau creați) un sunet de redat pe măsură ce scrieți textul. Atunci când alegeți un sunet pentru acest lucru păstrați-l foarte scurt, deoarece acest sunet va juca peste si peste, ca tipurile de text pe. Un clic mic sau un buton funcționează cel mai bine pentru acest efect.
Importați sunetul în bibliotecă în fișierul dvs. Flash, bifați "Exportați pentru acțiuni" și dați-i numele de clasă "TypingSound".
Pentru a reda acest sunet trebuie doar să adăugăm două linii la clasa RPGText. Mai întâi trebuie să instanțiăm sunetul. Adăugați această linie în partea de sus a clasei sub celelalte trei variabile private:
privat var _typingSound: Sunet = New TypingSound ();
Acum, treceți la funcția updateText și adăugați o linie care va reda efectiv sunetul de fiecare dată când textul se actualizează (linia 38 este nouă):
funcția privată updateText (e: Event): void if (txt.text.length < _currentTextBlock.length) txt.text = _currentTextBlock.substr(0, txt.text.length+1); _typingSound.play(); else removeEventListener(Event.ENTER_FRAME, updateText); fillText();
Asta e pentru demo. Totul ar trebui să funcționeze în acest moment, dar dacă vrei să integrezi acest lucru într-un joc, încă mai ai de lucru înainte.
În primul rând, în funcție de configurarea jocului, probabil că doriți să scoateți blocurile de text din clasa de documente. S-ar putea să aveți o clasă Scene pe care o utilizați pentru a configura conversațiile individuale care apar în joc sau o clasă Strings care să conțină întregul text pentru fiecare conversație.
În al doilea rând, veți dori să vă gândiți cum și când modulul de text va apărea în jocul dvs. S-ar putea să doriți să adăugați o animație tween care face să alunece și să iasă din partea de jos atunci când o conversație începe și se termină. De asemenea, veți dori să ascultați când conversația sa terminat, fie pentru a ascunde modulul de text, fie pentru a începe următoarea conversație.
Deoarece deja verificăm dacă a fost atins ultimul bloc text fillText , puteți adăuga cu ușurință ceva care se ocupă de sfârșitul conversației.
Nu includ aceste subiecte în tutorial deoarece modul în care faceți aceste lucruri va fi foarte specific pentru jocul dvs. Acest lucru ar trebui să fie suficient pentru a începe să începeți.
Sper ca ti-a placut! Postați un comentariu și spuneți-mi ce credeți.