Ci sono molti giochi là fuori con movimenti a scatti e irrealistici e che possono fare solo una cosa per il tuo prodotto: renderlo poco attraente per il pubblico. Ma non è difficile ottenere un movimento fluido - mettiamoci al lavoro!
Diamo un'occhiata al risultato finale su cui lavoreremo:
Questo è un tutorial semplice, quindi l'impostazione sarà anche semplice.
Creare un nuovo progetto Flash ActionScript 3.0. Le dimensioni e il colore dello stage non contano, basta usare ciò con cui ti senti a tuo agio.
Io uso FlashDevelop per la codifica, ma anche questo potrebbe essere fatto in qualsiasi editor AS, come Flash Pro (o qualsiasi editor di testo, magari Notepad;)). Quindi, crea un file di classe, assicurati che il tuo codice sia simile al mio; vedi sotto. Ho chiamato il mio "Movimento". (Se utilizzi Flash Pro, consulta questa guida per creare una classe.)
pacchetto import flash.display.Sprite; Movimento di classe pubblica estende Sprite public function Movement (): void
Al termine, assicurati che la tua Classe sia collegata al progetto Flash come Main Class.
Quindi, dopo aver collegato la classe di movimento al tuo documento, definisci le variabili come ho fatto di seguito
pacchetto import flash.display.Sprite; import flash.events.Event; Movimento di classe pubblica estende Sprite // L'oggetto che si sposterà in privato var square: Sprite; // La velocità massima private var _max: Number = 10; // Le variabili che verranno applicate per spostare il quadrato privato var dx: Number = 0; private var dy: Number = 0; public function Movement (): void // Listen per aggiunto all'evento stage addEventListener (Event.ADDED_TO_STAGE, init); funzione privata init (e: Event): void removeEventListener (Event.ADDED_TO_STAGE, init); // Creare un nuovo Sprite e disegnare all'interno di un quadrato quadrato = new Sprite (); square.graphics.beginFill (0x333333); square.graphics.drawRect (0, 0, 30, 30); square.x = stage.stageWidth / 2 - square.width / 2; square.y = stage.stageHeight / 2 - square.height / 2; addChild (quadrato);
Questo è praticamente tutto ciò che faremo per creare l'oggetto. Puoi usare il tuo oggetto ma per questo semplice tutorial sul movimento ho usato questo semplice quadrato.
Ciao ragazzi, questa è la classe Input.as; Input.as Class questi sono i ragazzi di cui ti ho parlato - sii gentile con loro! :)
Allora, di cosa parla questa classe, potresti chiederti. Fondamentalmente fa il tuo lavoro di gestione delle chiavi per te. Aggiunge un ascoltatore agli eventi ENTER_FRAME - con priorità bassa - e un listener di chiavi che riempie alcuni dizionari privati. Inoltre usa un'altra classe per i codici chiave. Puoi dare un'occhiata dentro e vedere di persona come funziona.
Nota: la classe Input.as non mi appartiene. È stato creato da Matthew Bush, che ha portato Box2D in Flash.
// Esempio di Input.as Uso della classe // Devi sempre inizializzarlo come questo con il parametro stage Input.initialize (stage); // Dopo l'inizializzazione, puoi usare i metodi kd (), kp () o ku (), che // restituiscono un valore booleano se le condizioni sono soddisfatte. // Questi metodi accettano più argomenti, // quindi per un evento è possibile utilizzare più chiavi. // Questo rende molto più facile dare una spinta di accessibilità alla tua app. //e.g Vedi sotto mentre uso una chiamata per rilevare la freccia UP o W per salire. Input.kd ("UP", "W");
Quindi, ora che conosci la classe Input.as, la importeremo nella nostra classe di movimento e inizializzeremo.
pacchetto import flash.display.Sprite; import flash.events.Event; input di importazione; Movimento di classe pubblica estende Sprite // L'oggetto che si sposterà in privato var square: Sprite; // La velocità massima private var _max: Number = 10; // Le variabili che verranno applicate per spostare il quadrato privato var dx: Number = 0; private var dy: Number = 0; public function Movement (): void // Listen per aggiunto all'evento stage addEventListener (Event.ADDED_TO_STAGE, init); funzione privata init (e: Event): void removeEventListener (Event.ADDED_TO_STAGE, init); // Creare un nuovo Sprite e disegnare all'interno di un quadrato quadrato = new Sprite (); square.graphics.beginFill (0x333333); square.graphics.drawRect (0, 0, 30, 30); square.x = stage.stageWidth / 2 - square.width / 2; square.y = stage.stageHeight / 2 - square.height / 2; addChild (quadrato); // Inizializza la classe Input.as con il gestore sullo stage Input.initialize (stage); // Aggiungi il ciclo di aggiornamento addEventListener (Event.ENTER_FRAME, refresh); aggiornamento funzione privata (e: Event): void
Io uso un loop basato su ENTER_FRAME per rilevare gli input chiave; di seguito è il ricaricare()
metodo che è la funzione di gestore per questo evento.
refresh della funzione privata (e: Event): void // Key Handler if (Input.kd ("A", "LEFT")) // Sposta a sinistra if (Input.kd ("D", "RIGHT ")) // Sposta a destra if (! Input.kd (" A "," LEFT "," D "," RIGHT ")) // Se non viene premuto left / right if (Input .kd ("W", "UP")) // Move up if (Input.kd ("S", "DOWN")) // Move down if (! Input.kd ("W", "SU", "S", "GIÙ")) // Se non ci sono azioni su / giù
Questo è piuttosto semplice. Rileva se uno qualsiasi dei tasti è premuto, quindi agisci di conseguenza.
Io uso molto l'operatore ternario: valore = condizione? vero falso;
Questa è fondamentalmente un'istruzione if che è stata condensata su una singola riga.
Per ogni rilevamento di chiavi, utilizzo questo metodo: se il valore è maggiore di _max
quindi impostalo uguale a _max
; altrimenti, incrementare o decrementare quel particolare valore come appropriato. In questo modo, è mantenuto entro certi limiti. Semplice, giusto?
Di seguito puoi studiare le condizioni:
refresh della funzione privata (e: Event): void // Key Handler if (Input.kd ("A", "LEFT")) // Sposta a sinistra dx = dx < 0.5 - _max ? _max * -1 : dx - 0.5; if (Input.kd("D", "RIGHT")) //Move to the right dx = dx > _max - 0.5? _max: dx + 0.5; if (! Input.kd ("A", "LEFT", "D", "RIGHT")) // Se non viene premuto left / right if (dx> 0.5) dx = dx < 0.5 ? 0 : dx - 0.5; else dx = dx > -0,5? 0: dx + 0,5; if (Input.kd ("W", "UP")) // Sposta su dy = dy < 0.5 - _max ? _max * -1 : dy - 0.5; if (Input.kd("S", "DOWN")) //Move down dy = dy > _max - 0.5? _max: dy + 0.5; if (! Input.kd ("W", "UP", "S", "DOWN")) // Se non c'è azione su / giù se (dy> 0.5) dy = dy < 0.5 ? 0 : dy - 0.5; else dy = dy > -0,5? 0: dy + 0,5; // Dopo tutto ciò, applicate questi all'oggetto square.x + = dx; square.y + = dy;
Se non conosci l'operatore ternario, prendi un pezzo di carta e una penna e scrivi alcuni di essi nel formato if ... else; è un ottimo esercizio per fare i conti con quello che sta succedendo.
Tieni presente che manipolo il dx
e dy
variabili, e solo impostare i valori attuali x e y alla fine. Questo ci aiuta a rendere fluido il movimento; non è un sussulto, poiché alteriamo i loro valori direttamente attraverso la funzione ...
Vai avanti, provalo! Guarda come si sta muovendo?
Va bene. Tutto è giusto, muovendosi fluidamente - ma fuori dal palco! Di seguito ho aggiunto le condizioni di rilevamento delle collisioni.
refresh della funzione privata (e: Event): void // Key Handler if (Input.kd ("A", "LEFT")) // Sposta a sinistra dx = dx < 0.5 - _max ? _max * -1 : dx - 0.5; if (Input.kd("D", "RIGHT")) //Move to the right dx = dx > _max - 0.5? _max: dx + 0.5; if (! Input.kd ("A", "LEFT", "D", "RIGHT")) // Se non viene premuto left / right if (dx> 0.5) dx = dx < 0.5 ? 0 : dx - 0.5; else dx = dx > -0,5? 0: dx + 0,5; if (Input.kd ("W", "UP")) // Sposta su dy = dy < 0.5 - _max ? _max * -1 : dy - 0.5; if (Input.kd("S", "DOWN")) //Move down dy = dy > _max - 0.5? _max: dy + 0.5; if (! Input.kd ("W", "UP", "S", "DOWN")) // Se non c'è azione su / giù se (dy> 0.5) dy = dy < 0.5 ? 0 : dy - 0.5; else dy = dy > -0,5? 0: dy + 0,5; // Rilevamento del confine if (square.x - dx < 0 || square.x + dx + square.width > stage.stageWidth) // rilevamento dell'asse x if (square.y - dy < 0 || square.y + dy + square.height > stage.stageHeight) // y rilevamento asse // Dopo tutto ciò, applicate questi all'oggetto square.x + = dx; square.y + = dy;
Sta cercando i confini in modo più preciso, controllando se i bordi del quadrato colpiscono i confini (prima di questo, era solo controllando il centro del quadrato contro i confini).
Grande. Ora dobbiamo aggiungere il codice per far rimbalzare il quadrato dai confini. Quello che faccio per questo è moltiplicare per -1 il valore dell'asse dx
o dy
. Ma non è abbastanza! Se la velocità è abbastanza veloce, il quadrato supererà i margini o impazzirà. Quindi, prima di moltiplicare, è necessario impostare la xey dell'oggetto per essere uguale al limite che incontra.
Quindi se x object.x = 0; e quindi moltiplica il dx
di -1.
// Rilevamento del margine se (square.x - dx < -dx || square.x + dx + square.width > stage.stageWidth) // rilevamento dell'asse x square.x = square.x - dx < -dx ? 0 : stage.stageWidth - square.width; dx *= -1; if (square.y - dy < -dy || square.y + dy + square.height > stage.stageHeight) // y detection axis square.y = square.y - dy < -dy ? 0 : stage.stageHeight - square.height; dy *= -1;
Provalo subito! Bouncy giusto? :)
Per renderlo ancora migliore, continua a sperimentare valori diversi: come invece di moltiplicare per -1, prova -0.7 e guarda i risultati.
Quindi hai incontrato la classe Input.as, hai imparato come lavorarci e hai fatto un bel movimento fluido in pochi minuti. Penso che questo sia un grande momento!
Si prega di lasciare i vostri commenti qui sotto e qualsiasi altra domanda, sarò lieto di rispondere.
Ma se incontri qualche problema controlla due volte il tuo codice, confrontalo con il file sorgente e poi se non riesci a farlo funzionare, sentiti libero di postare una domanda.