Crea un gioco di corse senza un motore 3D

Questo tutorial ti fornirà un'alternativa al 3D per i giochi di corse in ActionScript 3. Non è necessario alcun framework esterno per questo esempio di stile vecchia scuola.


Anteprima del risultato finale

Diamo un'occhiata al risultato finale su cui lavoreremo:


Passaggio 1: impostare il documento FLA

Crea un nuovo set di documenti Flash per ActionScript 3.0. Userò dimensioni di 480x320 px, una frequenza fotogrammi di 30 FPS e uno sfondo blu chiaro. Salva il file con un nome a tua scelta.


Passaggio 2: creare una classe di documenti

Oltre al FLA, abbiamo anche bisogno di creare una classe di documenti. Crea un nuovo file Actionscript e aggiungi questo codice:

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

Salva questo file nella stessa directory del nostro FLA. Nome itяMain.as.


Passaggio 3: collega il Principale Classe con il FLA

Per compilare il codice dal Principale classe, abbiamo bisogno di collegarlo con il FLA. On theProprietà pannello del FLA, vicino aClasse, inserisci il nome della classe del documento, in questo caso, Principale.

Quindi, salva le modifiche sul FLA.


Passaggio 4: traccia una linea stradale

Dobbiamo iniziare con una linea per rappresentare un segmento della strada. stampa R per selezionare il Strumento rettangolo. In questo esempio creerò un rettangolo grigio per la strada stessa, due piccoli rettangoli rossi a ciascun bordo di quello grigio e rettangoli verdi per riempire il resto della linea. Quelli verdi devono essere ancora più larghi del palco, li sto ingrandendo di 1500 pixel. La larghezza della strada può variare a seconda delle tue esigenze, userò uno dei 245 pixel di larghezza. Non è necessario che siano molto alti, poiché utilizzeremo diverse istanze per disegnare l'intera strada sullo schermo. Li farò 10px di altezza.


Passaggio 5: crea un Movie Clip per le linee stradali

Dopo aver disegnato tutti i rettangoli, selezionali tutti (Ctrl + A) e premere F8 per creare un filmato da quei rettangoli che hai appena creato. Chiamalo "Strada", assicurati che il Punto di registrazione è al centro e seleziona la casella di controllo "Esporta per ActionScript".

Finirai con una Road MovieClip nella libreria.

Dipende da te se vuoi disegnare ogni rettangolo su diversi livelli. Sto per mettere quello grigio su un secondo livello. Se si dispone di un'istanza Road sullo stage, eliminarla. Aggiungeremo in seguito Road MovieClip per codice.


Passaggio 6: impostare l'area di gioco

Torniamo al Principale classe. Lo useremo Strada MovieClip per generare l'illusione di una pista da corsa.

Stiamo per determinare la profondità della strada visibile e le dimensioni dell'area di gioco. Inoltre, nella nostra classe, tutto il Strada le istanze che aggiungiamo allo stage saranno accessibili da una matrice. Useremo un'altra matrice (ZMap) per determinare la profondità di ogni linea.

In questo esempio, imposterò una profondità di 150 linee stradali in un'area di gioco di 480x320 (non è necessario avere le stesse dimensioni del palco, ma poiché è tutto ciò che verrà mostrato, userò quei numeri).

 // Profondità della strada visibile private const roadLines: int = 150; // Dimensioni dell'area di gioco. const const privato: int = 480; const privato res: int = 320; // Linea della macchina del giocatore. private const noScaleLine: int = 8; // Tutte le linee stradali saranno accessibili da una matrice. private var zMap: Array = []; linee private var: Array = []; private var halfWidth: Number; private var lineDepth: int; private const widthStep: Number = 1;

Passaggio 7: Visualizza la strada per codice

Useremo tutte le precedenti variabili e costanti all'interno del Principale funzione. Scaleremo ogni riga in base alla profondità corrispondente.

 funzione pubblica Main () // Popolare la zMap con la profondità delle linee stradali per (var i: int = 0; i < roadLines; i++)  zMap.push(1 / (i - resY / 2));  //We want the line at the bottom to be in front of the rest, //so we'll add every line at the same position, bottom first. lineDepth = numChildren; for (i = 0; i < roadLines; i++)  var line = new Road(); lines.push(line); addChildAt(line, lineDepth); line.x = resX / 2; line.y = resY - i;  //Scaling the road lines according to their position halfWidth = resX / 2; for (i = 0; i < roadLines; i++)  lines[i].scaleX = halfWidth / 60 - 1.2; halfWidth -= widthStep;  

Se tu Pubblicare (Ctrl + Invio) il documento a questo punto avrai una vista di una strada dritta.

Puoi giocare con i calcoli di ridimensionamento per ottenere risultati diversi. Potresti volere una strada più ampia o una distanza di visualizzazione più lunga.


Passaggio 8: crea una seconda grafica stradale

In questo momento la strada sembra così piatta che non saresti in grado di dire se stiamo andando avanti. Abbiamo bisogno di almeno due diversi stili di segmento per distinguere quanto velocemente o quanto lento stiamo muovendo.

Vai al Biblioteca pannello e fare doppio clic su Strada MovieClip per tornare ai rettangoli che hai disegnato. Ora premi F6 per inserire un nuovo Keyframe (se hai più di un layer potresti voler inserire un nuovo Keyframe su ogni layer). Ora, in base al primo fotogramma, puoi modificare i colori dei rettangoli o modificare il loro design in qualche modo. Cambierò il loro colore e aggiungerò alcune linee di corsia al secondo fotogramma.


Passaggio 9: mantenere la linea del lettore da ridimensionamento

Definiremo una nuova variabile nel Principale classe per mantenere la coerenza sulla linea del giocatore (supponendo che ci sarà un'auto nel gioco, continueremo a ridimensionare a 1 su quella linea)

 private var playerZ: Number;

Successivamente, modificheremo il Principale funzione.


Passaggio 10: aggiungere linee alternate alla strada

Questa variabile sarà usata nel Principale funzione. Ora il Strada le linee saranno segmentate, alcune mostreranno il secondo frame e il resto mostrerà il primo frame, migliorando l'illusione di una pista da corsa.

 funzione pubblica Main () for (var i: int = 0; i < roadLines; i++)  zMap.push(1 / (i - resY / 2));  playerZ = 100 / zMap[noScaleLine]; for (i = 0; i < roadLines; i++)  zMap[i] *= playerZ;  lineDepth = numChildren; for (i = 0; i < roadLines; i++)  var line = new Road(); lines.push(line); addChildAt(line, lineDepth); line.x = resX / 2; line.y = resY - i;  halfWidth = resX / 2; for (i = 0; i < roadLines; i++)  if (zMap[i] % 100 > 50) righe [i] .gotoAndStop (1); altre linee [i] .gotoAndStop (2); lines [i] .scaleX = halfWidth / 60 - 1.2; halfWidth - = widthStep; 

Potrebbe non essere necessario moltiplicare per 100 per ottenere correttamente i segmenti, ma questi sono i numeri che userò in questo esempio, sei libero di modificare i numeri secondo i tuoi gusti (e se fai un errore, hai questo come riferimento).


Passaggio 11: impostare una velocità e un offset

Iniziamo a far muovere le cose. Stiamo per impostare una variabile per la velocità. Questo indicherà la profondità che avanzeremo per fotogramma. Ho intenzione di iniziare a una velocità di 20, è possibile utilizzare qualsiasi numero desiderato.

Abbiamo anche bisogno di un indicatore per i segmenti stradali, che cambierà in base alla velocità.

 velocità var privata: int = 20; private var texOffset: int = 100;

Passaggio 12: Inizia lo spostamento in avanti

Prima di poter fare qualsiasi cosa con queste variabili, dobbiamo importare un nuovo evento in questa classe. Potremmo usare un Timer o un EnterFrame. In questo esempio userò l'evento EnterFrame.

 import flash.events.Event;

Quindi, stiamo andando a tagliare l'ultimo condizionale nel Principale() funzione e spostalo in una nuova funzione che stiamo creando. Questa nuova funzione verrà attivata dall'evento EnterFrame, quindi otterremo un movimento continuo sulla strada. Chiamiamolo gara().

 funzione pubblica Main () for (var i: int = 0; i < roadLines; i++)  zMap.push(1 / (i - resY / 2));  playerZ = 100 / zMap[noScaleLine]; for (i = 0; i < roadLines; i++)  zMap[i] *= playerZ;  lineDepth = numChildren; for (i = 0; i < roadLines; i++)  var line = new Road(); lines.push(line); addChildAt(line, lineDepth); line.x = resX / 2; line.y = resY - i;  halfWidth = resX / 2; for (i = 0; i < roadLines; i++)  lines[i].scaleX = halfWidth / 60 - 1.2; halfWidth -= widthStep;  addEventListener(Event.ENTER_FRAME, race); 

Passaggio 13: definire una funzione di gara

Ora riportiamo il condizionale che è stato tagliato alla nuova funzione in modo da ottenere movimento. Il texOffset punterà la posizione della strada per mantenere un'accurata illusione di movimento.

 race di funzione privata (event: Event): void for (var i: int = 0; i < roadLines; i++)  if ((zMap[i] + texOffset) % 100 > 50) righe [i] .gotoAndStop (1); altre linee [i] .gotoAndStop (2);  texOffset = texOffset + velocità; while (texOffset> = 100) texOffset - = 100; 

Se tu Pubblicare questo ora, dovresti avere una strada animata.


Step 14: Sterzo

Le strade perennemente dritte sono noiose e ci sono migliaia di modi per far avanzare una prospettiva solo in avanti. Ora aggiungiamo alcune nuove variabili per occuparci delle curve mentre sei in movimento.

In questo esempio, alternerò le curve a destra con sezioni diritte. La strada da percorrere sarà conservata nel nextStretch variabile. Inoltre, sposteremo le linee ' X posizione alle curve.

 private var rx: Number; // Posizione x di ogni riga private var dx: Number; // Quantità di curve per segmento private var ddx: Number = 0.02; // Ammontare della curva per linea segmento var privatoY: int = roadLines; private var nextStretch = "Diritto";

Passaggio 15: aggiunta di curve alla strada

Il rx variabile memorizzerà il X posizione di ogni linea, quindi vorremmo che iniziasse al centro e prendesse le curve da lì. Anche, DDX controlla la nitidezza delle curve. In questo esempio lo avrò a 0.02; potresti voler variare il suo valore tra le curve. Questo è come il nuovo gara() la funzione sarà:

 gara di funzione privata (evento: Evento): void rx = resX / 2; dx = 0; per (var i: int = 0; i < roadLines; i++)  if ((zMap[i] + texOffset) % 100 > 50) righe [i] .gotoAndStop (1); altre linee [i] .gotoAndStop (2); righe [i] .x = rx; if (nextStretch == "Straight") if (i> = segmentY) dx + = ddx; altrimenti dx - = ddx / 64; // Ripristina uniformemente da una curva a una parte diritta.  else if (nextStretch == "Curved") if (i <= segmentY) dx += ddx; else dx -= ddx / 64;  rx += dx;  texOffset = texOffset + speed; while (texOffset >= 100) texOffset - = 100;  segmentY - = 1; while (segmentY < 0)  segmentY += roadLines; if (nextStretch == "Curved") nextStretch = "Straight"; else nextStretch = "Curved";  

Questa volta non toccheremo il Principale funzione. Se tu Pubblicare ora dovresti ottenere qualcosa del genere:

Potresti voler cambiare il valore della curva per sinistra e destra e modificare i valori di governo. A questo punto dovresti già essere in grado di aggiungere una macchina alla scena e controllare la velocità manualmente.


Step 16: Hills, Slopes

Ricorda che i rettangoli per la strada sono alti più di 1 pixel? Questo potrebbe aiutarci ad allungare la vista della strada nel caso in cui vogliamo colline nel nostro gioco.

C'è un metodo per rendere le colline molto simili alle curve. Potrebbero esserci molti metodi diversi, ma questo è quello che userò qui. Per semplicità, riciccherò tutto il codice che abbiamo già e aggiungerò poche righe per questo nuovo effetto. Come al solito, se i risultati non ti piacciono, puoi modificare i valori a piacere.

Abbiamo appena creato delle variabili per il X posizioni delle linee stradali, ora facciamo quelle per il y posizioni pure.

 private var: Number; private var dy: Number; private var ddy: Number = 0.01; // Un po 'meno ripido delle curve.

Step 17: Downhill, in salita

Per semplicità, in questo esempio userò gli stessi segmenti retti sia per un effetto dritto in salita, sia per le curve sia per una curva che per un effetto in discesa.

 gara di funzione privata (evento: Evento): void rx = resX / 2; ry = resY; dx = 0; dy = 0; per (var i: int = 0; i < roadLines; i++)  if ((zMap[i] + texOffset) % 100 > 50) righe [i] .gotoAndStop (1); altre linee [i] .gotoAndStop (2); righe [i] .x = rx; righe [i] .y = ry; if (nextStretch == "Straight") if (i> = segmentY) dx + = ddx; dy = = ddy;  else dx - = ddx / 64; dy + = ddy;  else if (nextStretch == "Curved") if (i <= segmentY)  dx += ddx; dy -= ddy;  else  dx -= ddx / 64; dy += ddy;   rx += dx; ry += dy - 1;  texOffset = texOffset + speed; while (texOffset >= 100) texOffset - = 100;  segmentY - = 1; while (segmentY < 0)  segmentY += roadLines; if (nextStretch == "Curved") nextStretch = "Straight"; else nextStretch = "Curved";  

Nel tuo gioco dovresti separare le curve dalle colline e fare due diversi algoritmi, ma questo esempio mostra come possono essere simili.


Step 18: Migliora l'estetica della strada

I giochi della vecchia scuola non hanno potuto sfruttare Flash, ma possiamo farlo. Qualcosa di semplice come aggiungere un gradiente alle linee stradali farà una bella differenza. Se lo desideri, puoi utilizzare qualsiasi filtro e trame che ti piace, ma in questo esempio sto solo aggiungendo alcune sfumature semplici, quindi torniamo al Strada Un filmato.

Sul fotogramma 1, selezionare il rettangolo grigio, quindi andare al pannello Colore e scegliere Gradiente lineare dal menu a discesa, quindi scegliere Rifletti il ​​colore come Flusso, quindi il gradiente continuerà avanti e indietro dal primo all'ultimo colore. Non ti sto dicendo di scegliere gli stessi colori di me, ma userò # 666666 e # 999999 qui. Se è necessario ruotare il gradiente, premere F per passare allo strumento Trasformazione sfumatura, che ti consente di spostare, ruotare e ridimensionare la sfumatura. In questo caso sto spostando il gradiente su un quarto del rettangolo e ridimensionandolo a metà della dimensione del rettangolo, quindi il centro sarà più chiaro ei bordi saranno più scuri. Io uso una dimensione simile per la parte verde, quindi cambierà da verde scuro (# 006600) a verde chiaro (# 009900) continuamente.

Ora vai al fotogramma 2 e crea nuovi gradienti con colori diversi. Per il rettangolo grigio, ho mantenuto il colore più chiaro e ho modificato solo il colore più scuro con # 777777. Nella parte verde, ho cambiato la dimensione della sfumatura per cercare di evitare un aspetto a scacchiera, e il cambio di colore era molto sottile (# 007700 e # 008800).

Forse ora ti consigliamo di aggiungere uno sfondo piacevole all'orizzonte o un grafico per il cielo.


Conclusione

Indipendentemente dal fatto che tu sia a corto di risorse per i framework 3D o vuoi semplicemente andare a scuola, ora hai un semplice esempio di come creare un'illusione di profondità per un gioco di corse. Ora tocca a te se sarà un Gran Premio motociclistico, o una gara su strada su un'autostrada piena di traffico, o forse qualcosa di estraneo alle corse.

Spero che tu abbia trovato utile questo tutorial. Grazie per aver letto!