Realizzare Snake Game [parte 1]

Se vi è piaciuto Snake Game e volete imparare a realizzare una cosa simile, siete nel posto giusto.

Questo è il primo di una serie di Tutorial che segue la realizzazione da zero di quel giochino.

Prima di cominciare, assicuriamoci di avere tutto quello che serve:

  1. Un editor di testo (in questi giorni sto utilizzando Komodo Edit, è gratuito e disponibile per tutte le piattaforme, ma andrà bene anche il Blocco Note)
  2. Un compilatore ActionScript (io utilizzo Flash CS4, esistono molti modi per compilare un SWF ma chi possiede Flash non ha ragione di cercare altro)

Adesso possiamo iniziare ad impostare il nostro progetto.

La cartella principale del progetto.

Create una cartella nuova e chiamatela SnakeGame, sarà il contenitore per tutti i file che creeremo da questo momento in poi.

Dentro la cartella SnakeGame create una nuova cartella, chiamatela snake.

La cartella snake sarà il Package principale del progetto, dentro questa cartella creeremo tutti i file .as che ci servono.

Un Package è un raccoglitore che serve a mantenere ordinate le Classi che fanno parte di un Progetto e raggruppare quelle che hanno attinenza tra loro. Le Classi che fanno parte di uno stesso Package possono condividere Metodi e Proprietà.

Per questo progetto realizzeremo un numero limitato di Classi, quindi possiamo inserirle tutte quante dentro un unico contenitore, la nostra cartella snake. È molto importante ricordare il nome di questa cartella: dovremo scriverlo dentro tutti i file ActionScript che fanno parte di questo Package.

Creiamo la nostra prima Classe

Ogni Classe del nostro progetto è rappresentata da un singolo file, con estensione .as.

È necessario che il nome del file .as sia identico al nome della Classe stessa, facendo attenzione anche alle lettere maiuscole e minuscole (case sensitive).

La Classe più semplice di questo Progetto si occuperà di disegnare un quadrato: ci serviranno dei quadrati per disegnare il riquadro, per disegnare il serpente e anche le “ciliege”. Definendo una singola Classe che fa questo semplice lavoro potremo utilizzarla continuamente.

Creiamo un nuovo documento di testo e salviamolo dentro la cartella snake con il nome Square.as.

A questo punto la struttura dei file sul nostro disco sarà simile a questa:

Struttura file

Dichiarazione del Package

Cominciamo a scrivere il codice ActionScript che ci serve. La prima cosa da dire è che questo file appartiene ad un Package:

package snake {
}

La direttiva package indica che questo file fa effettivamente parte di un Package, la parola successiva è il nome del Package stesso. Tutto il codice di questa Classe va inserito all’interno delle parentesi graffe.

Importazione delle Classi di supporto

Se abbiamo la necessità di utilizzare dei Metodi o delle Proprietà che appartengono ad altre Classe, è necessario importare tutte queste Classi come prima cosa, si fa così:

//package snake {
    import flash.display.Sprite;
//}

La direttiva import indica che stiamo richiedendo l’importazione di una Classe, nello specifico ci serve la Classe Sprite che si trova dentro al Package flash.display.

La Classe Sprite è una delle più utilizzate in ActionScript 3, per maggiori informazioni potete consultare la pagina della Classe Sprite della Guida di Riferimento Adobe.

Definizione della Classe

Adesso che abbiamo definito il Package e abbiamo importato le Classi che ci servono, possiamo passare alla definizione vera e propria della Classe, in questo modo:

//package snake {
//    import flash.display.Sprite;
    public class Square extends Sprite {
    }
//}

La direttiva public indica che la nostra Classe è Pubblica, ovvero è accessibile dall’esterno (da altre Classi). Non è obbligatorio specificarlo, dal momento che ActionScript 3 supporta solamente Classi Pubbliche.

La direttiva class indica la definizione dela Classe vera e propria, la parola successiva è il nome della Classe. È indispensabile che questo nome sia identico al nome del file, così come il nome del Package deve essere identico al nome della cartella in cui il file si trova. La nostra Classe si chiama Square e il file si chiama Square.as (con la S maiuscola).

La parte più interessante è data dalla parola extends. Per scrivere una Classe non dobbiamo necessariamente partire da zero: possiamo utilizzare una Classe che esiste già e aggiungere Metodi e Proprietà nuovi. In questo momento stiamo estendendo la Classe Sprite, in questo modo la nostra Classe Square ha già tutti i Metodi e le Proprietà di uno Sprite.

Oltre a quello che scriveremo noi possiamo sempre contare sul fatto che tutti i quadrati che creeremo utilizzando questa Classe avranno anche una posizione X, una posizione Y, un’altezza e tutto quello che è disponibile nella Classe Sprite.

Variabili private

Aggiungiamo tre righe all’interno delle parentesi graffe di public class Square extends Sprite:

//package snake {
//    import flash.display.Sprite;
//    public class Square extends Sprite {
        private var _w:uint;
        private var _h:uint;
        private var _c:uint;
//    }
//}

Le tre righe aggiunte inizializzano tre variabili Private. In ActionScript 3 non è possibile utilizzare una variabile se non la si è prima dichiarata.

La direttiva private indica che queste variabili possono essere utilizzare soltanto all’interno di questa Classe e non saranno accessibili dall’esterno.

È una buona prassi definire, oltre al nome della variabile, anche il Tipo. Se una variabile è tipizzata, ovvero è stata inizializzata definendo anche il Tipo, non sarà  possibile assegnarle un valore diverso da quello previsto, in questo modo si evitano un po’ di errori nel codice successivo. Il tipo che ho scelto per queste variabili è uint. La Classe uint definisce un numero intero senza segno e può rappresentare valori compresi tra 0 e 4.294.967.295.

Metodo Costruttore

Oltre ad avere delle variabili, la nostra Classe ha anche delle Funzioni (o Metodi). La principale importante funzione di una Classe ha lo stesso nome della Classe stessa ed è chiamata Costruttore:

//package snake {
//    import flash.display.Sprite;
//    public class Square extends Sprite {
//        private var _w:uint;
//        private var _h:uint;
//        private var _c:uint;
        public function Square(color:uint = 0x000000, size:uint = 10) {
            _w = _h = size;
            _c = color;
            drawSquare();
        }
//    }
//}

Al momento in cui scrivo questo articolo ActionScript non supporta ancora i Costruttori Privati, come altri linguaggi, quindi il Metodo Costruttore deve necessariamente essere dichiarato come Pubblico.

Il Metodo che abbiamo appena scritto accetta fino a due parametri, chiamati color e size. Questi due parametri non sono obbligatori, questo perché abbiamo definito un valore di Default (0x000000 per color e 10 per size). Quando richiameremo la Classe Square potremo anche fare a meno di inviare dei parametri. Se invieremo dei valori per uno dei due parametri verranno usati quelli personalizzati.

Il contenuto della Funzione è breve:

  • Imposta le variabili _w e _h con il valore del parametro size.
  • Imposta la variabile _c con il valore del parametro color.
  • Richiama il metodo drawSquare, che appartiene a questa stessa Classe (anche se non lo abbiamo ancora scritto).

Metodo Privato

Il Metodo Costruttore viene eseguito ogni volta che instanziamo la nostra Classe. Avremmo potuto mettere al suo il codice che disegna effettivamente il quadrato, anziché creare un Metodo separato, ma così non avrei potuto raccontarvi cos’è un Metodo Privato, eccolo:

//package snake {
//    import flash.display.Sprite;
//    public class Square extends Sprite {
//    private var _w:uint;
//    private var _h:uint;
//    private var _c:uint;
//    public function Square(color:uint = 0x000000, size:uint = 10) {
//        _w = _h = size;
//        _c = color;
//        drawSquare();
//    }
    private function drawSquare():void {
        this.graphics.beginFill(_c);
        this.graphics.drawRect(1,1,_w-2,_h-2);
        this.graphics.endFill();
    }
//}

Come è facile intuire, un Metodo è Privato quano può essere richiamato soltanto dalla Classe cui appartiene.

Il compito di questo metodo è quello di disegnare il quadrato, per fare questo utilizza la proprietà  graphics dello Sprite (Square estende Sprite, per questo possiamo utilizzare i suoi Metodi e le sue Proprietà , ricordate?).

La proprietà  graphics degli Sprite è un Oggetto di tipo Graphics (Classe flash.display.Graphics) e possiede diversi Metodi di disegno, noi ne abbiamo utilizzati tre:

  • beginFill inizia le operazioni di disegno e imposta il colore di riempimento. Come colore abbiamo utilizzato il valore della variabile _c che di Default è 0 (0x000000 in esadecimale).
  • drawRect disegna un rettangolo utilizzando quattro parametri: x, y, width, height. Ho intenzione di lasciare un bordo vuoto tutto intorno al quadrato, per questo inserisco un valore di 1 per x e y e un valore di width e height inferiore di 2 rispetto al valore di _w e _h (vedi immagine sotto).
  • endFill termina l’operazione di disegno.

Un quadrato con un bordo vuoto intorno

Un’altra cosa importante è la parola chiave this, dall’interno di una Classe possiamo sempre riferirci all’istanza corrente utilizzando questa parola.

Getter

Un Getter è un Metodo che restituisce una Proprietà. Quando scriviamo qualcosa di simile a quadrato.altezza noi vogliamo conoscere la Proprietà altezza di un’istanza chiamata quadrato.

Se le Proprietà di una Classe sono Pubbliche (public) è possibile accedere direttamente ad esse, altrimenti è necessario inserire dei Getter:

//package snake {
//    import flash.display.Sprite;
//    public class Square extends Sprite {
//        private var _w:uint;
//        private var _h:uint;
//        private var _c:uint;
//        public function Square(color:uint = 0x000000, size:uint = 10) {
//            _w = _h = size;
//            _c = color;
//            drawSquare();
//        }
//        private function drawSquare():void {
//            this.graphics.beginFill(_c);
//            this.graphics.drawRect(1,1,_w-2,_h-2);
//            this.graphics.endFill();
//        }
        public function get w():Number {
            return _w;
        }
        public function get h():Number {
            return _h;
        }
//    }
//}

I Getter devono essere Pubblici per poter essere raggiunti dall’esterno, ma soprattutto questi Metodi devono sempre restituire un valore, altrimenti non avrebbero nessun senso.

La direttiva return indica il valore che intendiamo restituire. I Metodi appena scritti restituiscono il valore delle variabili private _w e _h. Ci serviranno di certo.

Proviamo la Classe

A questo punto possiamo provare la Classe appena scritta facendola compilare da Flash, in questo modo:

  1. Apriamo Flash
  2. Creiamo un nuovo File chiamato provaSquare.fla
  3. Salviamo il file nella cartella SnakeGame (o in qualunque altro posto si trovi la cartella snake).
  4. Dal Pannello Proprietà  assegnamo la Classe di riferimento, cioé snake.Square.
  5. Esportiamo premendo CTRL (o CMD su Mac) + Invio.

Il risultato è questo:

No flash, please!

Purtroppo Adobe Flash Player non è più benvoluto come una volta, per questo motivo ho disabilitato tutte le applicazioni Flash presenti sul sito. Se vuoi puoi comunque scaricare il file SWF che si trovava qui, clicca qui per far partire il download

Sembra poco, non è vero? Eppure questa Classe è fondamentale per realizzare il gioco finito.

Presto pubblicherò la seconda Classe, così vedremo come utilizzare tante istanze del nostro Square.

Potrebbero interessarti anche...

2 Risposte

  1. luca rivara ha detto:

    ciao, ho provato a seguire la tua lezione, copiando minuziosamente il codice ma a me il quadratino nero non appare. Ho usato la funzione trace(); per vedere fin dove Flash arrivava e arriva solo alle variabili. Poi sembra che non veda più nulla.

    per favore, potresti aiutarmi? Grazie

    package { import flash.display.Sprite;  public class serpent extends Sprite  { private var _w:uint;        private var _h:uint;        private var _c:uint;     public function Square(color:uint = 0x000000, size:uint = 10) {            _w = _h = size;            _c = color;            drawSquare(); trace(“cccoo”);        } private function drawSquare():void {        this.graphics.beginFill(_c);        this.graphics.drawRect(1,1,_w-2,_h-2);        this.graphics.endFill();    }    public function get w():Number  { return _w;}    public function get h():Number  { return _h; }  } }

    • Daniele Alessandra ha detto:

      Ciao Luca,

      la classe che hai scritto si chiama “serpent”: “public class serpent extends Sprite”.
      Contiene due Metodi: Square e drawSquare.

      Quando viene instanziata una Classe viene subito eseguito il codice contenuto all’interno del “Metodo Costruttore”, che non è altro che una funzione che ha lo stesso nome della Classe stessa.

      Nell’esempio del mio articolo la Classe si chiama “Square” (non “serpent”) e quindi viene eseguito il Metodo “Square”.
      Nel codice scritto da te la Classe si chiama “serpent” ma non contiene alcun Metodo che si chiama “serpent”, quindi non viene eseguito nulla.

      Puoi risolvere in due modi:
      1. Cambi nome alla Classe o al Metodo “Square”. Se la Classe e il Metodo hanno lo stesso nome tutto funzionerà.
      2. Aggiungi un Metodo Costruttore chiamato “serpent” che richiama a sua volta il Metodo “Square”, in questo modo:

      public function serpent() {
                  Square();
      }

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.