Asteroid Game





 
Regalo nell'uovo di Pasqua 😅 che molto probabilmente uscirà dopo Pasqua 🙈
Andremo a realizzare un semplice giochino old style come me e semplice sarà la parola d'ordine. Ho provato a rendere il codice il più semplice possibile anche se questo implica un bel po' di blocchi in più e alcune scelte non proprio raffinate. L'intento è quello di rendere il progetto accessibile a più persone possibili e allo stesso tempo con la seconda parte vedere cosa può essere migliorato grazie all'utilizzo di componenti particolari o un codice più complesso. Sì, nella seconda parte useremo i componenti Any per ottimizzare il più possibile. Partiamo!
P.S. Scritto prima per bontà 😁 se provate da companion il posizionamento degli sprite non funziona perché evidentemente è troppo lento nell'apertura dell'arrangement e posiziona gli sprite quando è ancora non visibile sbagliando il posizionamento, da apk invece nessun problema . Si può ovviare aggiungendo un clock2 che crea un ritardo.   

I finti screen
Ormai dovreste conoscere l'utilizzo dei virtual screen ovvero finti screen che emulano gli stessi facendoci ottimizzare peso dell'app e gestione dei vari dati e database. Qui lo vedremo in forma easy ma l'idea è quella di utilizzare gli arrangement come se fossero i vari screen e simulare il cambio semplicemente settandoli visibile o meno. Questa sarà la nostra home page che come possiamo intuire dal menu laterale altro non è che un vertical arragement (VA_Intro) in cui abbiamo inserito una label per il titolo, un image per la navicella e un button per accedere al gioco. Al click setteremo questo componente non visibile e renderemo visibile quello con all'interno il nostro canvas (VA_Game) che sarà l'area di gioco. Entrambi gli arrangement hanno allineamento centrale e ho disabilitato la visualizzazione della title bar e della status bar per avere più spazio possibile, ho poi forzato l'orientamento landscape, quindi come da immagine.


Nel canvas abbiamo tutti sprite, uno per la navicella, 4 per i meteoriti e 3 per i missili ma voi potrete aggiungerne a piacimento tanto come vedremo il codice è spesso una copia meccanica per ogni elemento una volta individuato quello di base.

Settaggi
Inseriamo quindi tutti gli sprite che ci servono e naturalmente il canvas altrimenti non si fa niente 😊li troviamo tutti in drawing and animation per chi non lo sapesse.
Avremo un abbondanza di variabili proprio per semplificare , per i più bravi cercate di ottimizzare da soli e mi fate sapere. Abbiamo una lista AMICI (poi capiremo) con dentro i componenti relativi ai 3 razzi e la nostra navicella, è l'ultimo blocco di ogni componente, quello senza nessuna specifica a seguire come per esempio testo, colore, visibile etc. Quattro variabili numeriche che accoglieranno le coordinate del centro del canvas (Xc,Yc) e quelle dei missili (Xrocket,Yrocket) questo perché dobbiamo immaginare che il nostro gioco dovrà girare su molti dispositivi differenti che avranno schermi differenti e anche risoluzioni differenti, quindi non possiamo utilizzare dei valori assoluti altrimenti avremo risultati completamente differenti sui vari dispositivi. Alla pressione del pulsante subito facciamo entrare in gioco lo schermo virtuale cambiando la visualizzazione dalla schermata introduttiva a quella di gioco settando visibile e non visibile. Tutti i componenti recipiente come anche il canvas li ho settati fill parent, quindi coprono tutto il display.  





Le coordinate
Subito dopo calcoliamo il centro del nostro display andando a dividere per due la grandezza che ci viene fornita dalle proprietà dello screen ma non basta perché andiamo a calcolare anche la posizione della navicella sottraendo al valore del centro una quantità pari a 30 sulle X e 20 sulle Y, valori che grazie Move to ci permettono di spostare la navicella. Ma perché? E perché per i razzi andiamo a sottrarre 5 e 10?
Iniziamo col dire che ho impostato la grandezza della navicella come 40px in altezza e 60px di lunghezza , sì l'immagine è orizzontale e saranno tutte così per trovarsi allineate con i valori di orientamento che utilizza appinventor per gli sprite. La direzione su cui viaggiano gli sprite qui denominata heading ci permette con valori da 0 a 360 di impostare anche il verso . Per capirci 0 gradi e 180 hanno la stessa direzione ma verso opposto con 0 gradi posizionato a destra in orizzontale (ore 3 per capirci) e 90 in alto in verticale (ore 12) e così a seguire per 180 (ore 9) e 270 (ore 6). Sì ma la sottrazione ?
 

Le coordinate del canvas vengono calcolate dall'angolo in alto a sinistra dove abbiamo l'origine degli assi (0,0) e aumentano verso il basso e verso destra. Anche le coordinate degli sprite sono calcolate allo stesso modo, quindi non nel centro figura ma nell'angolo alto a sinistra. Nell'esempio se la X rossa è il centro dello screen (il nostro Xc,Yc) se posizioniamo lo sprite in quelle coordinate lo vedremo come in figura quindi con l'angolo in alto a  sinistra sulla X rossa. Capirete che così facendo non avremo una navicella centrata nel canvas. Ecco che dobbiamo spostare verso sinistra e poi verso l'alto la nostra navicella affinché la X rossa coincida con la X nera, cioè il centro della navicella. Per fare ciò ci dobbiamo spostare esattamente di 30 px e 20px che sono la metà delle relative dimensioni della navicella. Quindi se il vostro sprite ha dimensione differente dovrete rimodulare lo spostamento ma sempre della metà per ogni lato. Viene facile immaginare che i nostri rocket hanno dimensione 10x20 da qui lo spostamento di 5 e 10 per centrarli nel canvas ma anche sulla navicella creando in seguito l'uscita al centro della punta. Gli sprite di partenza sono settati non visibili. Questa operazione va fatta per tutti gli sprite interessati, nel nostro caso la navicella e i tre rocket, dovrete essere dei cecchini e non sprecare munizioni.
Subito dopo attiviamo un clock e puliamo il canvas , ah dimenticavo abbiamo anche inizializzato una variabile POINTS a zero che parla da sola.

Il tocco del canvas 
Avrei potuto utilizzare molti modi , da più semplici a più complessi ma credo che questo sia allo stesso tempo intuitivo e pratico anche in game.
I primi tre blocchi si leggono da soli e si capiranno alla fine , molto semplicemente se l'orologio è disabilitato (vi anticipo che coincide con la fine del gioco) ci fa tornare alla schermata introduttiva per iniziare una nuova partita. Pulizia del canvas va di pari passo con la scrittura sullo stesso di un testo, il punteggio, posizionato secondo le coordinate X,Y. Se non puliamo tutto ciò che si scrive si sovrappone quindi risulta illeggibile. Veniamo a noi. Questo codice gestisce il puntamento della nostra navicella e il conseguente lancio dei missili.
Point in direction ci permette di ruotare velocemente la navicella dirigendola nella direzione del nostro tocco sullo schermo. Quindi se ho un meteorite a destra e clicco nella sua direzione la navicella si posiziona di conseguenza.


Lo stesso blocco Point in direction lo useremo anche con i razzi e servirà per dirigere correttamente gli sprite che una volta settati visibili e impostata la velocità a 5 partiranno per distruggere i meteoriti, fin qui tutto semplice, ma perché questo controllo a catena per verificate se i missili non sono visibili?
Molto semplicemente ho pensato che se sono visibili vuol dire che sono stati già lanciati e quindi non utilizzabili, c'è sempre una soluzione possibile con il codice e io adoro trovare modi differenti di risoluzione, e voi ? 
Al momento del tocco sullo schermo viene controllato se rocket1 è disponibile e allora si spara altrimenti si passa alla verifica successiva per vedere se il razzo2 è disponibile e così via. Alla fine, ultimo ma non ultimo se non abbiamo più munizioni scriviamo a video NO ROCKETS, la posizione a vostro piacimento. Quindi puntamento, verifica e sparo 😁 

Missili fotonici
Ma che fine fanno i missili una volta lanciati? Beh sicuramente dobbiamo verificare se colpiscono i meteoriti e se raggiungono il bordo quindi la galassia sconfinata. A dirla tutta dobbiamo fare anche in modo che non scoppino urtandosi tra di loro e qui ci verranno in aiuto gli amici.
Partiamo dal codice più semplice , il raggiungimento del bordo, c'è fortunatamente un evento bello pronto che ci risolve in secondo. Li metto tutti nell'immagine ma una volta scritto il primo basta fare click di destra sul blocco when Edge Reached e poi duplica, vi mostrerà giustamente il warning di duplicato ma poi andremo a cliccare sui vari triangoli per selezionare al menu a discesa il numero corretto sia dell'evento sia degli altri parametri.



Quindi una volta toccato uno qualsiasi dei bordi imposteremo la visibilità su falso, porteremo la velocità a zero e le coordinate a quelle iniziali. Ehi tu , lo so , non chiedermi perché non ho usato Move to risparmiando un blocco per sprite, è quasi mezzanotte e si dorme poco ultimamente 😂.


Anche qui ne inserisco solo due per farti notare i cambiamenti ma puoi facilmente fare copia e incolla come prima e cambiare il nome dello sprite.
Se prima abbiamo gestito la collisione con i bordi adesso vediamo le collisioni con gli altri sprite (Move to come sopra, non chiedere 😴). Mentre l'evento precedente ci restituiva edge questo ci segnala other ovvero uno sprite o una ball attivi con cui siamo entrati in contatto. Tutto il nostro codice è avvolto da una condizione che verifica se other , quindi lo sprite con cui siamo in collisione, non è nella lista amici, quindi sarà un nostro nemico, quindi un meteorite. Negazione e costrutto a parte mi era sembrato il modo più semplice per selezionare solo il tocco con i meteoriti. Tu come avresti fatto? In questo modo se due missili entrano in collisione , per esempio un lancio ravvicinato a tal punto che si sovrappongono, oppure toccano la navicella il codice si sarebbe attivato. Se pensiamo a come abbiamo impostato il gioco i nostri missili sono sempre in collisione con la navicella che li lancia quindi il codice sarebbe stato sempre attivo bloccando il lancio.


Quindi nel momento in cui abbiamo una collisione e l'elemento toccato non è un nostro amico allora per forza di cose sarà un meteorite e andremo a nascondere lo sprite, azzerare la velocità, riposizionare e aumentare il nostro punteggio di 5, puliamo la vecchia scritta e aggiorniamo il punteggio a video. Bene click di destra , duplica e cambia il nome del componente e il gioco è fatto anche se ai 100 rocket 🙊

Meteoriti
I poveri meteoriti verranno spazzati via con facilità, quasi quanto è facile il loro codice ma perché da buoni scansafatiche delegano all'orologio.
Omologamente ai missili avremo un evento di collisione con i bordi e quelli con gli altri sprite, partiamo dal primo ed è sempre valido il trucco del copia e incolla.


Raggiunto il bordo li rendiamo invisibili e azzeriamo la loro velocità, quasi mi vergogno a commentarli.



I poveri sassolini non avendo amici e venendo dalla galassia sperduta non hanno bisogno di tanti controlli se non la verifica della collisone con la navicella visto che questo segnerà la fine della partita. Quindi ad ogni collisione nascondiamo , azzeriamo la velocità e se abbiamo raggiunto la navicella , quindi other=navicella, fermiamo il clock e scriviamo a caratteri cubitali GAME OVER. Il famoso orologio attivato all'inizio e che indica la fine della partita, da adesso in poi un tocco sul canvas porta alla home. Duplicate senza pietà.

Orologio matto 


Per completezza ma ormai siete master of variabili non c'è bisogno che vi spieghi altro. L'orologio vedremo , ho cercato di semplificare e ho lasciato lo stesso metodo del touch per selezionare il meteorite disponibile così da non appesantire e anche perché sembra funzionale al suo dovere.
La prima parte, nonché quella nuova serve per creare un pò di casualità e impostare la posizione di partenza dei meteoriti. Dimenticavo l'evento scatenante è il when Clock timer ovvero il tic dell'orologio che ho impostato ad un intervallo di 1500 millisecondi quindi 1,5 secondi, volendo potete aumentare o addirittura provare ad implementare un aumento di velocità magari dopo un certo punteggio. Prendete il diario e scrivete l'assegno 😂 lo stesso potete provare per l'introduzione di più livelli.
Quindi ogni 1,5 secondi questo codice si attiva , sceglierà prima di tutto la coordinata del meteorite , la salveremo in una variabile, per poi spostarci il meteorite e attivare la corsa verso la navicella.
La prima sfida è stata selezionare un punto a caso ma doveva avere delle specifiche particolari perché non deve essere un punto nel centro ma periferico, deve essere casuale e non deve far toccare il meteorite con il bordo altrimenti si autodistrugge. Ho pensato di dividere in due parti. Una prevede la seleziona prima della coordinata X che può spaziare su tutta la distanza ovvero un numero casuale tra 35 e tutto il display - 35 così facendo evito il bordo destro e sinistro visto che il mio sprite è 30px. Selezionata la posizione X devo scegliere se mi trovo nella parte alta dello schermo (Y=35) o in quella bassa (altezza screen -35) , anche qui il 35 della formula evita il bordo e la dimensione presa direttamente dal parametro dello screen mi permette di generalizzare a tutti i display.
L'altra ,in opposizione, prevede la selezione prima della coordinata Y impostandola casualmente con un numero compreso tra 35 e l'altezza dello schermo -35, in questo caso l'escursione avviene in verticale considerando sempre la banda laterale per evitare il tocco del bordo.
Deciso a che altezza dovrà apparire devo solo decidere se a sinistra (X=35) oppure a destra (lunghezza screen-35) dello schermo.
La scelta casuale l'ho lasciata ad una semplice condizione , sia per scelta della prima coordinata che per la scelta del lato.
Se un numero casuale tra 1 e 2 è proprio 1 allora partirà la prima parte del codice altrimenti la seconda, idem per il lato se il numero casuale è 1 selezionerà un lato altrimenti l'altro. SpeedRock imposta una velocità casuale tra 4 e 8 ad ogni giro di orologio.


 Come in precedenza un controllo a catena verifica se il meteorite in questione è disponibile attivandolo altrimenti passa al successivo, se sono tutti occupati in questo caso non ho previsto effetti speciali.
Move to mi permette di posizionare il meteorite nella coordinata casuale calcolata all'inizio passando i parametri direttamente con la variabile apposita (Xrock,Yrock), Point Towards mi permette facilmente di impostare la direzione e il verso in cui punterà il meteorite passando come target la navicella, rendiamo visibile e attiviamo la velocità passando la variabile SpeedRock che cambia ad ogni giro.

Scusate per eventuali errori ma volevo portare questo gioco il prima possibile, segnalateli nei commenti come anche eventuali cambiamenti che apporterete al gioco. Appena possibile proverò a scrivere il codice con i blocchi AnyComponent per vedere le differenze. Metti mi piace sul social che preferisci se vuoi che metta il link del download del file aia.
Ti è piaciuto? Cosa cambieresti ? Aggiunte ?

Supportatemi con like e messaggi per far crescere il blog e il canale. 
👉 Link 👈 al download
    Buona Pasqua a tutti
         Raffaele

👉 Link 👈al download della versione Pro

Ho caricato anche la versione aggiornata con l'esplosione dei meteoriti e la visualizzazione dell' HIGH SCORE e relativo salvataggio nel tiny per chi fosse curioso. Rimane sempre la mia promessa di tutorial anche di questa versione se ci saranno un po' di richieste nei commenti o un po' di like a sostegno del blog e dei vari social 💪 Dovete lavorare anche un po' voi 😆

Edit : 
Partendo da un commento sotto il tutorial aggiungo un'informazione che potrebbe essere utile per migliorare i nostri progetti con il Canvas.
Ringraziamo Glak per il suggerimento 💪🏻
Molto probabilmente quando utilizziamo il componente canvas siamo alle prese con qualche giochino o simile e molto probabilmente abbiamo settato tutte le misure in fill parent per avere più spazio di gioco possibile. Ci potrebbero essere dei casi in cui , come anche nel nostro caso, gli Sprite compaiono dai bordi della zona di gioco e quindi potrebbe essere utile avere spazio extra. Nel nostro caso abbiamo reso invisibili i meteoriti per farli comparire casualmente dal bordo ma sicuramente i più attenti avranno notato , specie con i meteoriti più veloci, che l'effetto estetico non è dei migliori . Alcune volte addirittura i meteoriti sembrano comparire dal canvas e non dal bordo. Nell'ottica di creare un effetto di entrata nel canvas o per nascondere dei componenti senza renderli invisibili e poi visibili possiamo ampliare le dimensioni del canvas stesso . Da settings si potrebbe inserire manualmente il valore sapendo per esempio quanto è la risoluzione del nostro display ma è un metodo alquanto inefficace visto che ci sono molti displaying commercio. Sfortunatamente non si può nemmeno settare un valore maggiore del 100% . Quindi come fare ? Vi dico la mia poi voi potrete trovare la vostra strada o quella più consona al progetto in atto. I miei meteoriti sono più grandi dei razzi e la navicella è sempre fissa quindi nel mio caso il target di riferimento sarà il meteorite, immaginiamo 30px per lato. Per nascondere il meteorite basterà una fascia laterale di almeno 30px, facciamo 40 per sicurezza. Trovato il valore basterà impostare la grandezza del canvas come grandezza screen+(2x40) , due volte il valore di riferimento perché per ogni dimensione avremo sempre due fasce da ricreare , due per la larghezza e due per l'altezza , andando a creare una fascia perimetrale esterna all'area visibile di gioco. Ricordiamoci però che spostando all'esterno il bordo se abbiamo codice che si attiva al tocco del bordo dovremo aspettare più tempo affinché si attivi visto che lo Sprite dovrà percorrere uno spazio più o meno lungo nascosto dalla visuale. Per il nostro gioco è ininfluente o quasi ma se dobbiamo creare un effetto rimbalzo oppure attivare del codice appena lo Sprite tocca il bordo dobbiamo considerare questo ritardo tra quello che vediamo e quello che accade. Ovviamente se non vogliamo legarci a delle misure fisse ma impostare una percentuale ci pasterà utilizzare grandezza screen x (1.1) per esempio per ingrandire del 10% .
Ringraziando ancora Glak per il suggerimento spero che questo aggiornamento possa esservi utile in qualche progetto 👍🏻


Hai apprezzato il mio lavoro?Se ti va puoi offrirmi un bel caffè 😍

Commenti

  1. Ottimo tutorial...bravo... Se posso darti un consiglio...io avrei inhrandito il Canvas....

    RispondiElimina
  2. Tutti i consigli sono utili 💪🏻 grazie

    RispondiElimina

Posta un commento

Ciao, spero ti piaccia il blog. Se ti fa piacere qui puoi offrirmi un caffè!

Post popolari in questo blog

GOOGLE SCRIPT & KODULAR READ, WRITE, UPDATE, DELETE

Tu lo conosci THUNKABLE?