Crea un sistema di testo in stile RPG per il tuo prossimo gioco

In questo tutorial creeremo un sistema di testo simile a quello che vedi in molti giochi di ruolo. La nostra classe mostrerà dinamicamente un'icona per i personaggi mentre parlano e scriverà ogni blocco di testo lettera per lettera.

Anteprima del risultato finale

Ecco un esempio del sistema di testo che creeremo:

Passaggio 1: impostare il file Flash

Crea un nuovo file Flash (Actionscript 3). Le impostazioni del film variano a seconda del gioco. Per questa demo sto configurando il mio film come 500x300, con uno sfondo nero e 30 fps.

Passaggio 2: aggiungi un'immagine di sfondo

Molto probabilmente mostrerai il modulo di testo su un'immagine o un'animazione del tuo gioco. Per questa demo sto solo usando un'immagine che ho buttato insieme ad alcuni dei personaggi dei miei giochi in piedi in un campo di neve.

Metti la tua immagine di sfondo su un livello chiamato "sfondo".

Passaggio 3: creare il RPGText Un filmato

Crea un nuovo MovieClip sullo stage (Inserisci> MovieClip) denominato "RPGText".

In Proprietà simbolo selezionare "Esporta per Actionscript" e impostare il nome della classe su "RPGText". Utilizzeremo questo nome di classe in seguito per collegare il codice a questo MovieClip.

Clicca OK. Se vedi un avviso qui che la definizione della classe non può essere trovata, va bene. Significa solo che non c'è alcun codice per collegarsi a questo simbolo (ancora).

Dai al MovieClip il nome dell'istanza "rpgText." Ricorda, quando parlo di "RPGText" (maiuscolo) mi riferisco alla classe (o MovieClip); "rpgText" (in minuscolo) è il nome di a esempio di quella classe.

Passaggio 4: aggiungere uno sfondo del pannello di testo

Disegna un rettangolo all'interno del tuo nuovo RPGText Un filmato. Questo sarà lo sfondo per le icone dei personaggi e il fumetto. Disegnala come preferisci, ma dovrebbe coprire l'intera larghezza del tuo film ed essere abbastanza breve da non coprire troppo il tuo gioco.

Ho fatto il mio 500px di larghezza (per abbinare il mio film) e 100px di altezza. L'ho riempito con un gradiente da # 666666 a # 999999 (dal grigio scuro al grigio più chiaro).

Consiglio rapido: per disegnare un rettangolo di una dimensione specifica, selezionare lo strumento rettangolo e Alt-clic sul palco. Avrai una finestra di dialogo in cui puoi inserire le dimensioni del tuo rettangolo.

Passaggio 5: l'icona del personaggio MovieClip

Crea un nuovo livello all'interno del RPGText MovieClip chiamato "icona". Crea un nuovo MovieClip su questo livello chiamato "characterIcon" e assegnagli il nome di istanza "characterIcon".

Dentro il characterIcon MovieClip crea due nuovi livelli: "icone" e "etichette". Il livello delle icone conterrà tutte le icone dei personaggi (ciascuna sul proprio fotogramma chiave) e il livello delle etichette conterrà le etichette dei fotogrammi che useremo per visualizzare i caratteri al momento giusto.

Importa (o disegna in Flash) un'icona per ognuno dei personaggi del gioco che parlerà. Per questa demo ho realizzato un JPG 75x75px per ciascuno dei miei personaggi. Aggiungi le icone al icone livello, creando un nuovo fotogramma chiave per ogni carattere. L'ordine in cui appaiono non è importante, ma assicurati che ogni icona sia posizionata su x: 0, y: 0 in modo che non sembrino saltare quando cambi caratteri.

Passaggio 6: aggiungi etichette del telaio

Ora crea un nuovo fotogramma chiave su ciascun fotogramma del tuo etichette strato. Un modo veloce per farlo è selezionare tutti i frame e premere F6.

Seleziona ciascun fotogramma chiave etichetta uno per uno e aggiungi un'etichetta del fotogramma che corrisponde al nome del personaggio che appare in quella cornice. Se aggiungi alcuni fotogrammi vuoti (F5) tra i tuoi fotogrammi chiave, renderà più semplice leggere le etichette dei fotogrammi, ma assicurati che il tuo etichette i fotogrammi chiave rimangono allineati al tuo icone i fotogrammi chiave.

Assicurati che ciascuna delle tue etichette abbia un nome univoco. Se hai due personaggi con lo stesso nome, dovrai differenziarli in qualche modo ("John_L" e "John_K" per esempio).

Passaggio 7: Disegna il fumetto

Torna al RPGText MovieClip e crea un nuovo livello chiamato "textBackground".

Disegna una nuvoletta. Ho disegnato una semplice bolla con angoli squadrati, ma puoi far sembrare la tua come vuoi. Renderlo abbastanza grande da riempire la maggior parte del rettangolo di sfondo e si posiziona bene accanto alle icone dei personaggi.

Seleziona il fumetto e convertilo in MovieClip (Modifica> Converti in simbolo). Ora che è un MovieClip possiamo aggiungere un filtro ombra esterna ad esso. Ho impostato il mio nero, il 50% di forza, 5 pixel di sfocatura e 1 pixel di distanza.

Passaggio 8: aggiungere il campo di testo dinamico

Crea un nuovo livello nel RPGText MovieClip chiamato "testo". Usa lo strumento testo per disegnare una casella di testo. Inseriscilo solo all'interno dei bordi della grafica a fumetto.

Rendilo un campo di testo dinamico multilinea con il nome dell'istanza "txt". Ricordati di incorporare il carattere se non stai usando il testo di sistema. Sto usando 13pt Courier.

Passaggio 9: aggiungere il Il prossimo Pulsante

Abbiamo bisogno di un modo per il giocatore di avanzare al blocco di testo successivo quando il giocatore ha finito di leggere. Aggiungiamo un piccolo pulsante "successivo" nell'angolo.

Crea un nuovo livello nel RPGText MovieClip chiamato "pulsante". Aggiungi un nuovo simbolo di pulsante chiamato "b_next". Disegna i quattro stati del tuo bottone come preferisci. Ho usato una piccola freccia verso il basso come simbolo del pulsante perché lo vedo in molti giochi e presumo che i giocatori abbiano familiarità con esso.

Metti il ​​tuo pulsante nell'angolo in basso a destra sopra il fumetto. Non preoccuparti di dargli un nome di istanza. Spiegherò perché dopo.

Passaggio 10: creare la classe del documento

Crea un nuovo file Actionscript chiamato "Main.as" e aggiungi questo codice per creare la shell vuota per la classe:

package import flash.display.MovieClip; public class Main estende MovieClip // CONSTRUCTOR public function Main () 

Imposta Main come Classe documento nel file Flash. Se desideri un rapido aggiornamento sull'utilizzo di una classe Document, questo suggerimento rapido di Michael Williams è una delle migliori spiegazioni che ho visto.

Passaggio 11: aggiungere i blocchi di testo

Se stai usando questo in un gioco, probabilmente sceglierai di metterlo altrove, ma per ora lo aggiungeremo alla Document Class. Aggiungi questo codice alla funzione di costruzione nel file Principale classe:

var textBlocks: Array = new Array (["Kid", "Look, a robot!"], ["Abe", "BLEEP-BLOOP. Io sono un tecnico botanico autonomo. Puoi chiamarmi ABE."], [" Kid "," Ciao Abe, incontra Frosty the Snowman. "], [" Frosty "," Happy Birthday! "], [" Abe "," BEEP-BIP. Hello, Frosty. "], [" Abe "," Questa rana appartiene a te? "], [" Rana "," Ribbit ... "], [" Kid "," No non l'ho mai visto prima. Non sei una rana fredda? "], [" Rana " , "Ribbit ..."]); rpgText.textBlocks = textBlocks; 

Qui stiamo creando un array bidimensionale (una matrice che contiene altri array) per contenere lo script per la nostra scena. Prima di cambiare qualcosa, dai un'occhiata a come è strutturato. Ogni array è un blocco di testo separato che contiene due elementi. Il primo è il nome del personaggio e il secondo è il testo che parlerà. I blocchi di testo sono elencati nell'ordine in cui appariranno nella scena.

L'ultima riga invia semplicemente il TextBlocks matrice al rpgText MovieClip (ricorda "rpgText" è il nome dell'istanza di RPGText MovieClip sullo stage). Maggiori informazioni su questo più tardi.

Vai avanti e modifica questa sezione per adattarla alla tua scena. Fai attenzione che i nomi dei personaggi corrispondano esattamente ai nomi che hai usato per le etichette dei fotogrammi nel characterIcon MovieClip.

Passaggio 12: creare la classe RPGText

Siamo finalmente pronti per iniziare a scrivere il codice per la classe RPGText.

Crea un nuovo file Actionscript chiamato "RPGText.as" e aggiungi questo codice:

package import flash.events.Event; import flash.events.MouseEvent; import flash.display.MovieClip; import flash.media.Sound; public class RPGText estende MovieClip private const SPEAKER: int = 0; const privato: int = 1; private var _currentTextBlockIndex: int = 0; private var _currentTextBlock: String; private var _textBlocks: Array; // Funzione pubblica COSTRUTTORE RPGText () 

Questa è solo una shell di base per la classe. Non fa ancora nulla, ma diamo un'occhiata a cosa c'è:

  • Le prime righe stanno solo importando alcune delle classi di cui avremo bisogno.
  • Nella dichiarazione di classe stiamo estendendo la classe MovieClip. Dobbiamo farlo perché questa classe è collegata a RPGText MovieClip nella Libreria (vedere il Passaggio 3).
  • Successivamente, abbiamo due costanti, SPEAKER e TESTO che useremo per ottenere il nome dell'altoparlante e il testo dall'array textBlocks che abbiamo impostato nel passaggio precedente.
  • La variabile _currentTextBlockIndex terrà traccia di quale blocco di testo stiamo attualmente visualizzando.
  • _currentTextBlock manterrà il testo attuale.
  • _textBlocks manterrà l'intera serie di blocchi di testo.
  • Infine, c'è il costruttore di classi vuoto.

(Nota: sto usando il trattino basso nei miei nomi variabili per indicare variabili private).

Step 13: The TextBlocks Funzione setter

Dal nostro _textBlocks variabile è privata avremo bisogno di un modo per accedere a tale variabile dal Principale classe in cui stiamo impostando i blocchi di testo. Lo faremo creando una funzione "setter". Aggiungi questo alla classe RPGText appena sotto la funzione di costruzione:

funzione pubblica imposta textBlocks (txt: Array): void _textBlocks = txt;  

La cosa interessante dei setter in Flash è che possiamo accedere a questa funzione come se fosse una proprietà pubblica della classe RPGText. Che è esattamente ciò che abbiamo fatto sulla linea 21 della classe Main nel passaggio 11:

rpgText.textBlocks = textBlocks; 

Passaggio 14: aggiungere il UPDATETEXT Funzione

Aggiungi questa funzione alla classe RPGText:

funzione privata 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();   

Questa è la funzionalità principale della classe, dove avviene la tipizzazione lettera per lettera. Diamo uno sguardo più da vicino a ciò che sta accadendo qui:

  • Riga 27: questa funzione accetta un evento come parametro perché lo chiameremo utilizzando un evento ENTER_FRAME.
  • Riga 28: Confrontiamo la lunghezza (numero di caratteri) attualmente nel testo campo di testo al numero di caratteri nella _currentTextBlock Stringa.
  • Riga 29: Se ci sono meno caratteri nel campo di testo, usiamo il substr metodo per ottenere tutti i personaggi dall'inizio di _currentTextBlock fino a un numero in più rispetto al numero di caratteri attualmente nel campo di testo. Inseriamo tutti questi caratteri nel campo di testo, che ha l'effetto di aggiungere un altro carattere alla fine del testo nel campo di testo.
  • Riga 31: Se ci sono lo stesso numero di caratteri nel campo di testo come nel _currentTextBlock Stringa, rimuovere l'evento ENTER_FRAME che chiama questa funzione.
  • Riga 32: chiama il fillText funzione. Scriveremo questa funzione nel prossimo passaggio.

Passaggio 15: aggiungere il fillText Funzione

Aggiungi questa funzione alla classe RPGText:

funzione privata fillText (e: MouseEvent = null): void txt.text = _currentTextBlock; if (_currentTextBlockIndex < _textBlocks.length-1) addEventListener(MouseEvent.CLICK, nextTextBlock);   

Lo scopo principale di questa funzione è riempire il testo campo di testo con il testo dal _currentTextBlock (linea 37). Se lasciamo passare l'animazione, il UPDATETEXT la funzione dovrebbe occuparsene, ma è bene assicurarsi che nulla sia andato storto. Possiamo anche agganciare questa funzione al nostro pulsante "next" per consentire ai giocatori di saltare l'animazione del testo e riempire immediatamente il campo di testo con l'intero blocco di testo.

Si noti che questa funzione accetta un oggetto MouseEvent come argomento, ma impostiamo il valore predefinito su null. Questo ci permette di utilizzare questa funzione con un listener MouseEvent, poiché accetterà l'evento. Dato che forniamo un valore predefinito all'evento, possiamo anche chiamare la funzione senza inviare un evento come facciamo alla fine del UPDATETEXT funzione.

Dopo aver riempito il campo di testo, facciamo un controllo per vedere se questo è l'ultimo blocco di testo nella matrice (se il _currentBlockIndex è inferiore al numero di elementi nel _textBlock array). In caso contrario, aggiungiamo un listener CLICK per attivare una funzione chiamata nextTextBlock che scriverò dopo.

Passaggio 16: Informazioni su Listener di clic

Ricorda quando abbiamo creato il pulsante "next" e ho detto di non preoccuparti di dargli un nome di istanza? Hai notato nell'ultimo passaggio come abbiamo collegato il listener CLICK all'intero RPGText MovieClip invece del pulsante? In questo modo il giocatore può fare clic in qualsiasi punto del MovieClip per far avanzare il testo. In realtà non abbiamo nemmeno bisogno del pulsante, ma mi piace inserirne uno in modo che ci sia qualche indicazione che fai clic per far avanzare il testo.

Naturalmente questa è solo una mia preferenza personale. Se si desidera, è possibile assegnare al pulsante un nome di istanza e collegare invece il listener CLICK al pulsante. Ho appena trovato l'area più grande per essere più facile da usare.

Passaggio 17: aggiungere il nextTextBlock Funzione

Ritornare agli Affari. Aggiungi questa funzione alla classe RPGText:

funzione privata nextTextBlock (e: MouseEvent): void removeEventListener (MouseEvent.CLICK, nextTextBlock); txt.text = ""; // cancella il testo _currentTextBlockIndex ++; _currentTextBlock = _textBlocks [_currentTextBlockIndex] [TEXT]; // imposta il testo characterIcon.gotoAndStop (_textBlocks [_currentTextBlockIndex] [SPEAKER]); // imposta l'icona del carattere addEventListener (Event.ENTER_FRAME, updateText); // avvia l'aggiornamento del testo addEventListener (MouseEvent.CLICK, fillText);  

Le prime tre linee sono piuttosto semplici. Rimuovere il listener MouseEvent, cancellare il campo di testo e incrementare il file _currentTextBlockIndex var per puntare al prossimo blocco di testo.

La linea 47 sta usando il TESTO costante per ottenere la stringa di testo corrente dal _textBlocks array e assegnarlo a _currentTextBlock.

Quindi usiamo il SPEAKER costante per ottenere il nome del personaggio. Poiché i nomi dei personaggi corrispondono alle etichette dei fotogrammi nel nostro characterIcon MovieClip che possiamo usare gotoAndStop inviare il characterIcon MovieClip alla cornice che mostra l'icona di quel personaggio.

Infine, aggiungiamo un listener di eventi per iniziare a digitare sulla nuova stringa di testo e quindi aggiungere un listener CLICK per l'esecuzione fillText quando viene cliccato il MovieClip.

Passaggio 18: aggiungere il startText Funzione

Abbiamo quasi finito, abbiamo solo bisogno di aggiungere una funzione che farà iniziare tutto. Lo faremo con una funzione pubblica chiamata "startText". Dato che questa è una funzione pubblica, mettiamola vicino alla parte superiore della classe RPGText, appena sotto il TextBlocks setter:

public function startText (): void _currentTextBlock = _textBlocks [_currentTextBlockIndex] [TEXT]; characterIcon.gotoAndStop (_textBlocks [_currentTextBlockIndex] [DIFFUSORI]); addEventListener (Event.ENTER_FRAME, updateText); addEventListener (MouseEvent.CLICK, fillText);  

Sembra familiare? Questo codice fa quasi la stessa identica cosa del nextTextBlock funzione. Imposta l'icona di testo e carattere corrente e aggiunge i listener di eventi per UPDATETEXT e fillText. Poiché questa funzione viene eseguita solo all'avvio del testo, non è necessario preoccuparsi di cancellare il campo di testo o di incrementare il campo _currentTextBlockIndex come abbiamo fatto nextTextBlock.

Passaggio 19: richiama il startText Funzione

Ora abbiamo un modo pubblicamente accessibile per iniziare il testo. Mettiamolo per usarlo.

Aggiungi questa riga alla fine della funzione di costruzione della classe Main:

rpgText.startText (); 

Questo è solo chiamando la funzione startText all'interno della classe RPGText. Dovrebbe andare tutto bene.

Passaggio 20: aggiungi suono

Dovresti essere in grado di testare il tuo film ora e vedere tutto funziona. Manca solo una cosa: il suono.

Trova (o crea) un suono da riprodurre mentre il testo sta scrivendo. Quando scegli un suono per questo, tienilo molto breve, dal momento che questo suono verrà riprodotto più e più volte mentre il testo viene digitato. Un piccolo "boop" o un clic del tasto funziona meglio per questo effetto.

Importa il suono nella Libreria nel tuo file Flash, seleziona "Esporta per Actionscript" e assegnagli il nome della classe "TypingSound".

Per riprodurre questo suono, dobbiamo solo aggiungere due righe alla classe RPGText. Per prima cosa dobbiamo istanziare il suono. Aggiungi questa riga nella parte superiore della classe sotto le altre tre variabili private:

private var _typingSound: Sound = new TypingSound (); 

Ora salta alla funzione updateText e aggiungi una linea che riprodurrà effettivamente il suono ogni volta che il testo si aggiorna (la riga 38 è nuova):

funzione privata 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();   

Passo 21: portarlo oltre

Questo è tutto per la demo. Tutto dovrebbe funzionare a questo punto, ma se vuoi integrarlo in un gioco, hai ancora del lavoro davanti a te.

Innanzitutto, a seconda di come è impostato il gioco, probabilmente vorrai estrarre i blocchi di testo dalla classe del documento. Potresti avere una classe Scene che usi per impostare le singole conversazioni che si verificano nel tuo gioco, o una classe String che contiene tutto il testo per ogni conversazione.

In secondo luogo, vorrai pensare a come e quando il modulo di testo apparirà nel tuo gioco. Potresti voler aggiungere un'animazione di interpolazione che lo faccia scivolare dentro e fuori dal basso quando una conversazione inizia e finisce. Avrai anche bisogno di ascoltare quando la conversazione è finita, per nascondere il modulo di testo o avviare la conversazione successiva.

Dal momento che stiamo già controllando per vedere se l'ultimo blocco di testo è stato raggiunto nel fillText funzione, si potrebbe facilmente aggiungere qualcosa che gestisce la fine della conversazione.

Non includo questi argomenti nel tutorial perché il modo in cui svolgi queste cose sarà molto specifico per il tuo gioco. Questo dovrebbe essere sufficiente per iniziare.

Spero ti sia piaciuto! Pubblica un commento e fammi sapere cosa ne pensi.