Tratto da: Game Maker Tutorial – Creating Platform Games – Written by Mark Overmars – Copyright © 2007-2009 YoYo Games Ltd – www.yoyogames.com/…/platform.zip
I giochi di piattaforma sono molto diffusi, in particolare sui dispositivi portatili.
In un gioco di piattaforma si guarda la scena da un lato.
Il giocatore controlla normalmente un personaggio che si muove per il mondo.
Il mondo consiste di piattaforme.
Il giocatore può camminare su queste piattaforme, saltare o spostarsi da una piattaforma all’altra, usare scale o corde per spostarsi, ecc.
Sulle piattaforme ci sono
- oggetti da raccogliere,
- nemici da evitare o uccidere (spesso sparandogli oppure saltandogli sopra),
- interruttori da azionare per aprire dei passaggi,
- …
Inoltre il giocatore deve saper saltare su aree pericolose.
In alcuni giochi di piattaforma è visibile l’intero livello, ma nella maggior parte si vede solo una parte nelle vicinanze del personaggio.
In questi casi trovare la strada giusta intorno è un’ulteriore sfida.
Realizzare un buon gioco di piattaforma non è banale, anche con GameMaker.
Ci sono 3 aspetti importanti da tenere in conto
- creare un movimento naturale per il personaggio
- creare abbastanza varianti dei mostri, degli sfondi, …
- progettare accuratamente livelli piacevoli da giocare e con difficoltà crescente.
In questo tutorial imparerai a realizzare un semplice gioco di piattaforma con GameMaker.
Lo faremo per passi.
I diversi passi sono disponibili come giochi modificabili nella cartella Examples.
Troverai un solo livello dimostrativo degli aspetti più importanti.
Puoi utilizzarlo come base per i tuoi giochi di piattaforma.
Le basi
Iniziamo con il gioco di piattaforma più semplice.
In ogni gioco di piattaforma ci sono due oggetti:
- il protagonista controllato dal giocatore,
- e un oggetto blocco utilizzato per i pavimenti (piattaforme) dove il giocatore può camminare.
Lo stesso blocco è spesso utilizzato anche per i muri che il giocatore non può attraversare.
Sono necessarie le risorse
TIPO | NOME | FILE | |
---|---|---|---|
Sprite | spr_block | block.png | |
spr_ball | ball.png | ||
Object | obj_block | spr_block | |
obj_ball | spr_ball | ||
Room | room_0 |
Cioè
- 2 sprite: una per il protagonista e una per il blocco
- il blocco (è semplicemente un oggetto solido senza eventi e azioni: semplicemente sta lì)
- il protagonista (è un oggetto un po’ più complicato)
- un livello
Movimento
L’aspetto cruciale che trattiamo in questa prima sezione è come definire il movimento del protagonista.
Il problema è che il protagonista deve camminare sopra i pavimenti.
Non deve attraversare i pavimenti.
Se il protagonista salta o cade da un piano deve atterrare correttamente sul piano più vicino.
Il protagonista può camminare, saltare, cadere in diversi modi.
Giochi di piattaforma diversi utilizzano modalità diverse.
Normalmente utilizziamo appena tre tasti per controllare il movimento
- Freccia sinistra dovrebbe muovere il protagonista a sinistra,
- Freccia destra dovrebbe muovere il protagonista a destra,
- Freccia su o Spazio che lo fanno saltare.
Consideriamo il movimento orizzontale, destra-sinistra.
- La prima scelta da fare è se il giocatore può cambiare direzione soltanto quando è sul piano oppure anche quando è in aria (quando sta saltando o cadendo).
Sebbene la seconda scelta non sia naturale (è piuttosto difficile iniziare un movimento mentre si cade) la prendiamo come valida, quindi permettiamo al personaggio il movimento orizzontale in qualunque posto si trovi.
Questo rende il gioco più intuitivo ed è più facile da implementare. - La seconda scelta da fare è se il movimento ha velocità costante o se accelera quando mantieni il tasto premuto.
Per semplicità scegliamo la prima possibilità.
Ammettere l’accelerazione produrrebbe un gioco più piacevole: per esempio il giocatore dovrebbe partire da una distanza maggiore per saltare su una grande apertura.
Come dovresti sapere ci sono diversi modi per far muovere il protagonista:
- possiamo impostare una velocità di movimento
- oppure, semplicemente, possiamo muovere il protagonista direttamente.
Nei giochi di piattaforma è più facile che il movimento verticale sia fatto in automatico (come vedremo più avanti) mentre noi gestiamo il movimento orizzontale.
Questo è piuttosto semplice.
Nell’evento della tastiera per il tasto sinistro controlliamo se è libera la posizione realativa (-4,0).
In caso positivo facciamo saltare il protagonista a quella posizione.
<Left>
Jumpo relative to position (-4,0)
End of block
Trattiamo la freccia destra in modo simile
<Right>
Jumpo relative to position (+4,0)
End of block
Saltare
Adesso manca il movimento verticale.
Questo è più difficile.
Per fare in modo che il protagonista cada giù utilizziamo la gravità, gravity.
Ma si deve fermare quando batte sul pavimento.
Inoltre, bisogna stabilire una velocità massima di caduta, altrimenti il protagonista si muoverà troppo velocemente.
Questo, oltre che non essere troppo piacevole, potrebbe provocare problemi nell’implementazione del gioco: il protagonista potrebbe attraversare i pavimenti se si muovesse troppo veloce.
Per risolvere questo problema, nell’evento step del protagonista controlliamo se la posizione appena sotto è libera, collision free.
Se è così, il protagonista è in aria e impostiamo la gravità a un valore positivo.
Altrimenti la impostiamo a 0.
Inoltre controlliamo la variabile vspeed che indica la velocità verticale.
Se è maggiore di 12 la impostiamo di nuovo a 12.
In questo modo limitiamo la velocità verticale a 12.
Step
Set the gravity to 0.5 in direction 270
End of block
Else
Set the gravity to 0 in direction 270
End of block
If vspeed is larger then 12
Set the vertical speed to 12
End of block
La finestra dell’evento dovrebbe apparire così:
Deve succedere quando il protagonista tocca l’oggetto blocco.
Nell’evento collisione dobbiamo impostare la velocità verticale a 0.
Ma questo potrebbe lasciare il protagonista sospeso nell’aria sopra il pavimento.
Il motivo è che il protagonista viene sistemato alla sua posizione precedente alla collisione.
Per questo vogliamo spostare il protagonista al punto esatto dove avviene la collisione.
Con questa azione puoi muovere l’istanza in una certa direzione finché non tocca un oggetto
- se c’è già una collisione alla posizione attuale allora l’istanza non si sposta
- altrimenti, l’istanza si sistema appena prima che avvenga la collisione.
Puoi specificare la direzione e anche la distanza massima alla quale spostarsi.
Puoi anche specificare se deve considerare solo gli oggetti solidi o tutti gli oggetti.
Utilizziamo questa azione
- come direzione indichiamo la variabile direction che rappresenta la direzione attuale di movimento dell’istanza
- come massima distanza specifichiamo 12 (sebbene non sarebbe effettivamente necessario).
obj_block
Set the vertical speed to 0
La finestra dell’evento collisione con il blocco dovrebbe apparire così:
Potresti dedurre che dovremmo utilizzare questa tecnica soltanto quando si colpisce un pavimento.
In realtà l’azione Move to Contact è necessaria anche quando si tocca un muro di lato.
C’è una cosa importante che è spesso causa di problemi: noi assumiamo che il personaggio nella sua posizione precedente non sia comunque in collisione.
Ci aspettiamo questo ma non succede sempre.
L’errore che si commette spesso è che il personaggio ha un’immagine animata e anche la maschera di collisione cambia a ogni passo.
Questo potrebbe significare che la nuova immagine alla posizione precedente causa ancora una collisione.
Meglio essere sicuri che ci sia un’unica maschera di collisione.
Fortunatamente, dalla versione 8.0 in poi, GameMaker imposta di default la stessa maschera di collisione a tutte le sprite animate.
Comunque, quando si cambiano le immagini, il problema potrebbe ripresentarsi.
Infine dobbiamo fare in modo che il personaggio salti quando viene premuta Freccia su.
Ma questo deve succedere solo quando il personaggio è effettivamente sul piano.
Quindi prima controlliamo se la posizione appena sotto provoca una collisione, e se succede, impostiamo la velocità verticale a-10.
Per ottenere il movimento voluto dovrai giocare un po’ con il valore 10 della velocità verticale e con il valore 0.5 per la gravità.
<Up>
Set the vertical speed to -10
End of block
Adesso sono pronte le basi per il gioco di piattaforma.
Realizza un livello con pavimenti e pareti, costruiti con istanze dell’oggetto blocco.
Sistema un’istanza del personaggio nel livello e hai finito.
Miglioramenti grafici
Il gioco di piattaforma che abbiamo creato funziona ma si presenta piuttosto male.
Ci sono due problemi sui quali vogliamo intervenire:
- il modo con cui appare il protagonista
- il modo con cui appare lo sfondo.
Sono necessarie le risorse
TIPO | NOME | FILE | |
---|---|---|---|
Sprite | spr_block | block.png | |
spr_blockh | blockh.png | ||
spr_blockv | blockv.png | ||
spr_left | character_left.png | ||
spr_right | character_right.png | ||
Background | back_sky | sky.png | |
back_tiles | tiles.png | ||
Object | obj_block | spr_block | |
obj_blockh | spr_blockh | ||
obj_blockv | spr_blockv | ||
obj_character | spr_right | ||
Room | room_main |
Le immagini del protagonista
Cominciamo con la grafica del protagonista.
Utilizzeremo due sprite diverse (non animate):
- una per il personaggio girato a sinistra
- e una per il personaggio girato a destra.
Il modo più semplice è aggiungere nell’evento per la freccia sinistra un’azione per cambiare l’immagine con quella con la faccia girata a sinistra
<Left>
If relative position (-4,0) is collision free for Only solid object
Jumpo relative to position (-4,0)
End of block
Similmente per la freccia destra
<Right>
Jumpo relative to position (+4,0)
End of block
È molto importante disabilitare precise collision checking per le due sprite.
Ci sono diversi motivi.
- Prima di tutto, si evita che la sprite si blocchi a metà sul bordo del piano.
- Secondariamente, quando viene cambiata la sprite da lato sinistro a lato destro si dovrebbe utilizzare la stessa maschera di collisione altrimenti il protagonista potrebbe bloccarsi.
- La stessa cosa è persino più importante quando si usano le sprite animate.
Per gli stessi motivi assicurati che il bounding box delle sprite sia lo stesso.
Per questo scopo, modifica la maschera della sprite utilizzando manual bounding box.
Ecco la finestra delle proprietà per le maschere di collisione…
In questo caso hai bisogno anche di una sprite per il protagonista quando non è in movimento.
Inoltre dovresti aggiungere sprite per il protagonista che salta, cade, spara, ecc.
In questo caso dovrai cambiare la sprite in diversi posti negli eventi.
In particolare, nell’evento della tastiera No Key vuoi probabilmente impostare la sprite a quella di non movimento.
Alternativamente, puoi disegnare la sprite giusta nell’evento Draw corrispondente alla situazione.
Per esempio, puoi controllare se xprevious < x per sapere se il protagonista si è mosso verso destra.
Come detto prima, meglio essere sicuri che che tutte le sprite abbiano lo stesso bounding box e no precise collision checking.
Le piattaforme e i muri
La seconda cosa che vogliamo fare e migliorare lo sfondo e le piattaforme.
Utilizziamo una tecnica standard.
Piuttosto che utilizzare oggetti per tutti gli elementi del muro e del pavimento, utilizziamo le tessere.
Le tessere sono pezzi delle immagi di sfondo che sono disegnate in particolari posti del livello.
Non hanno eventi associati e non provocano collisioni.
L’aspetto positivo è che sono veloci e utilizzano poca memoria.
Quindi puoi creare livelli estesi senza bisogno di immagini grandi.
Per aggiungere le tessere ai tuoi livelli hai prima bisogno di un’immagine di sfondo che contenga le tessere.
Le tessere nell’immagine di sfondo dovrebbero avere una dimensione fissa e un piccolo bordo (un pixel) tra loro in modo che possano essere facilmente separate.
Nella cartella delle risorse del tutorial c’è una piccola immagine con tessere.
La aggiungiamo come risorsa di sfondo trasparente con il nome spr_tiles.
Quando la aggiungi al gioco, nella finestra delle proprietà specifica che sarà utilizzata come insieme di tessere, Use as tile set, e compila correttamente le proprietà, Tile properties
Adesso, quando stai realizzando un livello, puoi selezionare la scheda delle tessere, tiles.
Seleziona l’insieme di tessere (che è la risorsa di sfondo appropriata).
Ora puoi disegnare le tessere selezionandole con il mouse e poi sistemandole nel livello, come faresti con gli oggetti.
Il tasto destro elimina le tessere.
Sfrutta la tua immaginazione per realizzare livelli sorprendenti.
Osserva che che puoi sistemare le tessere su livelli diversi aggiungendo i livelli, layers.
Per esempio, puoi realizzare un livello che sta davanti ai personaggi in movimento.
Non li useremo qui ma sono grandi per dare un migliore effetto 3D.
È rimasto ancora un problema.
Come detto prima, le tessere sono soltanto immagini piacevoli.
Non generano eventi o collisioni.
Quindi il protagonista ci passerà attraverso.
Per evitare questo abbiamo bisogno ancora dei blocchi.
Sistemiamo i blocchi nei posti giusti sopra i muri e i piani che abbiamo realizzato sullo sfondo con le tessere.
Adesso, rendendo invisibili gli oggetti blocco non vedrai più i rettangoli neri ma le belle tessere.
Ma gli oggetti blocco sono ancora al loro posto, quindi il personaggio non può passare attraverso i muri e atterrerà sui piani.
C’è ancora un ultimo problema.
I blocchi 16×16 sono troppo grandi per coprire bene lo sfondo.
Quindi realizziamo altri due blocchi di dimensioni 16×8 e 8×16.
Ancora li rendiamo solidi.
Per evitare di specificare gli eventi collisione utilizziamo il meccanismo dell’ereditarietà, parent.
Questo è un meccanismo molto potente che dovresti imparare a usare.
Se un oggetto A è un padre, parent, di B, allora B si comporta come un caso speciale di A.
B eredita tutti i comportamenti di A (a meno che non li sovrascrivi con altri comportamenti).
Inoltre, le collisioni con B saranno trattate allo stesso modo di quelle con A.
Quindi per i blocchi più piccoli dobbiamo impostare la proprietà parent al blocco più grande.
In questo modo saranno trattati allo stesso modo del blocco più grande.
Sfide e traguardi
Saltare soltanto in giro per le piattaforme è piuttosto noioso.
Hai sicuramente bisogno di sfide e traguardi.
In questa sezione ne trattiamo alcuni.
Sono necessarie le risorse aggiuntive
TIPO | NOME | FILE | |
---|---|---|---|
Sprite | spr_death | death.png | |
spr_marker | marker.png | ||
spr_monsterl | monsterl.png | ||
spr_monsterr | monsterr.png | ||
spr_monsterflat | monsterflat.png | ||
spr_flyingl | flyingl.png | ||
spr_flyingr | flyingr.png | ||
spr_mushroom | mushroom_strip10.png | ||
spr_level | level.png | ||
Sound | snd_killmonster | killmonster.wav | |
snd_killcharacter | killcharacter.wav | ||
snd_getmushroom | mushroom.wav | ||
snd_finishlevel | level.wav | ||
Object | obj_death | spr_death | |
obj_marker | spr_marker | ||
obj_monster | spr_monsterr | ||
obj_monster_dead | spr_monsterflat | ||
obj_flyer | spr_flyingr | ||
obj_mushroom | spr_mushroom | … | |
obj_levelexit | spr_level |
Mostri
Aggiungiamo dei mostri.
Realizzeremo mostri di due tipi
- uno che si muove a destra e a sinistra su una piattaforma
- e l’altro che vola a destra e a sinistra nel cielo.
Saltare sopra il mostro significa schiacciarlo se è del primo tipo mentre quelli del secondo tipo devono essere sempre evitati!
Cominciamo con il mostro che si muove sulle piattaforme.
Sono necessarie due sprite, una per il mostro girato a sinistra e l’altra per il mostro girato a destra.
Di nuovo, meglio non usare precise collision checking per gli stessi motivi indicati prima e pick some relevant bounding box.
Adesso creiamo l’oggetto mostro.
Nell’evento Create lo facciamo muovere a destra con una certa velocità.
Ogni volta che colpisce un muro inverte la sua velocità orizzontale.
Per impostare la sprite corretta del mostro utilizziamo l’evento End Step.
Questo evento avviene proprio prima che le istanze vengano disegnate.
In esso impostiamo la sprite corretta basata sul valore della variabile hspeed che indica la velocità orizzontale.
Se è minore o uguale a 0 facciamo girare la faccia del mostro a sinistra e altrimenti a destra.
Se hai la Standard Edition di GameMaker puoi anche utilizzare l’azione che riflette l’immagine.
In questo caso ti serve una sola sprite.
Per evitare che i mostri cadano dalle piattaforme, introduciamo un altro oggetto, che chiameremo obj_marker, segnaposto.
Questo segnaposto sarà un blocco blu ma invisibile.
Ogni volta che un mostro tocca il segnaposto cambia la sua direzione del movimento.
Avere segnaposto invisibili è un buon trucco generico per far fare alle istanze certe azioni in posti particolari del livello.
Oltre che per cambiare direzione puoi usare i segnaposto per sparare, lanciare bombe, ecc.
Quando il protagonista tocca un mostro, il protagonista deve morire.
Ma adesso, come nella maggior parte dei giochi di piattaforma ci piace rendere possibile al protagonista di saltare sopra il mostro e schiacciarlo.
Quindi nell’evento collisione del protagonista con il mostro dobbiamo controllare se il mostro viene colpito dall’alto per distruggerlo.
Per controllare eseguimo il test seguente:
vspeed > 0 && y < other.y+8
Sarà vero se vspeed > 0, quindi il protagonista si muove verso il basso, e il protagonista è vicino al mostro quindi lo sta colpendo dall’alto.
In questo caso il mostro deve essere distrutto.
Nell’esempio trasformiamo il mostro in un mostro morto piatto, che si auto distrugge dopo un po’.
Questo gli dà un effetto grafico carino.
In questo semplice gioco di piattaforma , morire per il protagonista corrisponde a far ripartire il livello, che può essere ottenuto con semplici azioni.
Il mostro volante è ancora più semplice.
Procediamo allo stesso modo.
Ma nell’evento collisione del personaggio con il mostro volante, non è necessario alcun test perché non si possono schiacciare i mostri volanti.
obj_flyer
Sleep 1000 milliseconds; redwrawing the screen: true
Restart the current room
Potresti voler aggiungere più mostri, cioè con velocità diverse, per rendere le cose più difficili.
Puoi anche realizzare un mostro o una roccia che si muove su e giù.
Utilizza la tua immaginazione…
Trappole
Molti giochi di piattaforma richiedono precisione nei tempi dei salti per evitare di cadere dentro delle trappole, normalmente delle buche.
In genere, cadere in una buca porta alla morte del protagonista.
Per questo aggiungiamo un nuovo oggetto mortale, obj_death.
Questo oggetto è un blocco rosso e di nuovo non è visibile.
Puoi sistemarlo sul fondo della buca.
Puoi metterci anche i chiodi disponibili tra le tessere dello sfondo…
Nell’evento collisione del protagonista con l’oggetto mortale dovrebbe succedere che viene emesso un suono, si aspetta per un po’ e poi riparte il livello.
obj_death
Sleep 1000 milliseconds; redwrawing the screen: true
Restart the current room
Puoi prevedere anche che la buca sia senza fine.
Allora devi aggiungere le stesse azioni nell’evento Outside Room del protagonista, possibilmente aggiungendo un test y > room_height per essere sicuro che il protagonista sia caduto giù piuttosto che saltato di nuovo nel livello di gioco.
Outside Room
Play sound snd_killcharacter; looping: false
Sleep 1000 milliseconds; redwrawing the screen: true
Restart the current room
End of block
Raccogliere punti
Molti giochi di piattaforma prevedono un meccanismo con il quale il giocatore può raccogliere punti.
Normalmente devi raccogliere certi oggetti o catturare qualcosa.
Nel nostro esempio il giocatore può raccogliere funghi.
Quindi realizziamo un oggetto fungo, obj_mushroom.
Per dare un po’ di variazione, il fungo contiene 10 sotto-immagini diverse.
L’oggetto fungo prende un’immagine a caso alla creazione tramite l’azione Change Sprite
Impostiamo la sotto-immagine a random(10).
Si tratta di una chiamata di funzione che restituisce un numero casuale minore dell’argomento dato (quindi minore di 10 in questo caso).
Impostiamo speed=0 per evitare il ciclo continuo delle sotto-immagini.
Create
Nell’evento collisione del protagonista con un fungo
- viene emesso un suono
- distrutto l’altro oggetto (il fungo)
- e aggiunti 10 punti al punteggio.
obj_mushroom
Set the score relative to 10
For other object: destroy the instance
In alcuni giochi di piattaforma raccogliere oggetti ha una funzione più importante che razziare punti.
Per esempio, potresti ottenere una vita extra quando raccogli abbastanza oggetti.
Ancora, ci potrebbero essere oggetti che ripristinano la salute (assumendo che ci siano mostri che non ti uccidono ma semplicemente ti indeboliscono), che ti fanno muovere più velocemente, saltare più in alto, ecc.
Queste cose possono essere aggiunte facilmente.
Prossimo livello
Naturalmente ci deve essere un modo per finire un livello in modo che il giocatore possa passare al prossimo livello.
Per questo creiamo un oggetto di uscita dal livello, obj_levelexit.
Quando il protagonista lo raggiunge sarai promosso al prossimo livello.
Nell’esempio questo è stato fatto in modo piuttosto semplice.
Aggiungiamo un’azione che controlla se esiste il prossimo livello.
Se il controllo ha successo ci muoviamo al prossimo livello.
Altrimenti viene visualizzato il pannello dei punteggi e fatto ripartire il gioco.
obj_levelexit
Sleep 1000 milliseconds; redwrawing the screen: true
If next room exists
Go to next room
End of block
Else
Show the highscore table
Restart the game
End of block
Puoi decidere di fare in modo che l’uscita dal livello appaia soltanto quando per esempio tutti i funghi sono stati raccolti.
Per questo, nell’evento Create dell’oggetto, muovilo alla posizione (–100,-100), quindi fuori dallo schermo.
Poi, nell’evento Step dell’oggetto controlliamo se il numero di oggetti fungo è uguale a 0 (c’è un’azione per questo) e , se è così, sposta l’oggetto alla sua posizione iniziale (di nuovo c’è un’azione per questo).
Tutto molto semplice.
Più movimento
Il nostro attuale gioco di piattaforma ha poche possibilità di movimento.
Il personaggio sa muoversi a sinistra e a destra e sa saltare.
Per rendere le cose più interessanti aggiungiamo delle possibilità.
TIPO | NOME | FILE | |
---|---|---|---|
Sprite | spr_ladder | ladder.png | |
spr_climbing | character_climbing.png | ||
Object | obj_ladder | spr_ladder |
Rampe di scale
Sarebbe carino se il giocatore potesse salire le rampe di scale.
Le scende automaticamente perché cade…
Per questo, dobbiamo sostituire il codice per l’evento del tasto freccia sinistra.
Ci mettiamo questo:
- Piuttosto che controllare soltanto se la posizione a sinistra è libera controlliamo anche se la posizione 8 pixel sopra è libera.
- Se è così muoviamo lì il protagonista utilizzando l’azione di atterraggio per muoverlo giù alla posizione di contatto.
L’evento apparirà come segue:
Il tasto della freccia destra viene gestito allo stesso modo.
Arrampicate
A tutti piace che nei giochi di piattaforma ci siano delle arrampicate con cui il protagonista passa da una piattaforma all’altra.
Ci vuole un po’ d’impegno.
Un’arrampicata sarà rappresentata da un blocco verticale sottile invisibile (la pianta o qualche altra cosa che si utilizza per arrampicarsi viene disegnata di nuovo utilizzando le tessere) e non solido.
Quando il protagonista non è in contatto con l’arrampicata il movimento dovrebbe rimanere come prima.
Ma quando è in contatto con l’arrampicata le cose devono andare in modo diverso.
Prima di tutto il protagonista non deve cadere.
Quindi nell’evento Step dobbiamo fare una modifica aggiungendo delle azioni che impostano la velocità verticale e la gravità a0 quando è in contatto con l’arrampicata.
Inoltre cambiamo la sprite.
La seconda cosa che bisogna modificare è l’evento per il tasto <Up>.
Quando il protagonista è sull’arrampicata il tasto <Up> deve farlo salire piuttosto che saltare.
Di nuovo sono necessarie delle azioni aggiuntive per questo.
Controlliamo se il protagonista è in contatto con un’arrampicata e se è vero lo spostiamo su di un po’.
Utilizziamo azioni simili per il tasto <Down>.
Utilizzare una vista
Finora abbiamo sempre visualizzato l’intero livello.
Per molti giochi di piattaforma non è questo quello che vogliamo.
Piuttosto vogliamo vedere soltanto una parte del livello, intorno al personaggio che controlliamo.
Questo rende il gioco più intrigante perché il giocatore deve tentare di individuare il percorso tra le piattaforme.
Puoi anche nascondere i premi in posti difficili da raggiungere nel livello.
Per fortuna è estremamente semplice realizzarlo in Game Maker.
Quando stai realizzando un livello clicca la scheda views.
Abilita il controllo Enable the use of Views per cominciare a utilizzare le viste.
Seleziona la prima vista e abilita Visible when room starts per assicurarti che sia visibile.
Imposta width a 300 e height a 200 (o come preferisci).
Siccome stiamo per fare in modo che la vista segua il protagonista non c’è bisogno di specificare i valori left e top della vista nel livello.
Inoltre siccome utilizziamo una sola vista non dobbiamo specificare le posizioni x e y della porta sullo schermo.
In fondo specifichiamo quale oggetto seguire.
Qui scegliamo il protagonista.
Adesso la vista si muoverà automaticamente per mantenere il fuoco sul protagonista.
Non vogliamo che il protagonista si avvicini troppo al bordo.
Allora impostiamo i valori Hbor e Vbor a 64.
Adesso ci sarà sempre un’area visibile di 64 bit intorno al protagonista.
Infine, per aver un movimento della vista graduale impostiamo la velocità massima, Hsp e Vsp, a 4.
Questo ci darà anche un’piacevole effetto alla partenza del livello perché il protagonista scenderà lentamente nella vista.
Le impostazioni avranno l’aspetto seguente:
Avere la vista è carino ma rende la finestra in cui succedono le cose piuttosto piccola.
Per evitarlo, in Global Game Settingsindichiamo una scala del 200%.
Chiaramente puoi giocare con questi valori per ottenere l’effetto desiderato.
Ulteriori ritocchi
Il prossimo passo è permettere al giocatore di sparare ai mostri, mantenere un certo numero di munizioni, salute, vite…
Sono necessarie le risorse aggiuntive
TIPO | NOME | FILE | |
---|---|---|---|
Sprite | spr_bullet | bullet.png | |
spr_ammunition | ammunition.png | ||
spr_bonus | bonus.png | ||
spr_life | life.png | ||
Object | obj_bullet | spr_bullet | |
obj_ammunition | spr_ammunition | ||
obj_bonus | spr_bonus | ||
obj_controller |
Sparare ai mostri
Munizioni
Per rendere le cose più interessanti, il giocatore deve trovare delle munizioni prima di poter sparare.
Per questo introduciamo una variabile ammo che specifica quante munizioni ha il giocatore.
Nell’evento Create del protagonista la impostiamo a 0 utilizzando l’azione Set variable to .
L’oggetto obj_ammunition possiede solo una sprite e non fa niente.
Aspetta soltanto di essere raccolto dal giocatore.
Quando il protagonista viene a contatto con obj_ammunition aggiungiamo 10 alla variabile ammo e distruggiamo la sua istanza.
Proiettili
Adesso abbiamo bisogno di un oggetto proiettile, obj_bullet.
Quando il giocatore preme il tasto Space, nell’ipotesi che ci siano munizioni, deve essere creata un’istanza di questo oggetto e il valore della variabile ammo decrementato di 1.
C’è ancora un aspetto importante.
Vogliamo che il proiettile si diriga nella direzione del protagonista.
Per questo controlliamo il valore della variabile sprite_index.
Questa variabile contiene l’indice della sprite del protagonista.
In funzione di essa creiamo un proiettile con la corretta direzione del movimento.
Mentre si salta non si può creare il proiettile.
Non è permesso sparare quando si salta.
L’evento Space sarà:
Rimane da distruggere il proiettile quando colpisce un muro o quando esce dal livello e uccidere il mostro quando un proiettile lo colpisce.
Un pannello del punteggio
Adesso un giocatore ha un punteggio e delle munizioni.
Stiamo per dargli anche delle vite.
Toccare un mostro oppure cadere in una trappola costerà una vita.
In GameMaker c’è un meccanismo delle vite facile.
Realizziamo un oggetto speciale, obj_controller.
Non ha bisogno della sprite.
Nel suo evento Create (Game Start) imposta a 3 il numero di vite.
Ogni volta che il giocatore muore abbassiamo il numero di vite.
Nell’evento No More Lives del controllore visualizziamo i punteggi e facciamo ripartire il gioco.
Sarebbe più bello se potessimo vedere il numero di vite, il punteggio, le munizioni, ecc.
Per questo realizziamo un piccolo pannello con queste informazioni.
Lo disegniamo nell’evento Draw dell’oggetto controllore.
Si pone un problema.
Dove lo disegniamo?
Non possiamo disegnarlo in una posizione nel livello perché la vista cambia e vogliamo che il pannello sia sempre visibile.
Per fortuna possiamo chiedere la posizione alla vista.
Questa è specificata dalle due variabili view_xview e view_yview che indicano l’angolo in alto a sinistra della vista.
Quindi possiamo disegnare il pannello con queste informazioni per la sua posizione.
Ecco come dovrebbe apparire l’eventoDraw di obj_controller
Osserva che disegniamo anche un’immagine per indicare se il giocatore può sparare.
Il risultato nel gioco è quello nell’immagine
E adesso?
In queste pagine hai visto quali sono le basi per la realizzazione di giochi di piattaforma.
Ora tocca a te.
Dovrai utilizzare queste tecniche e qualche idea in più di tuo per realizzare un gioco di piattaforma veramente piacevole.
Ricordati che la parte più importante dei giochi di piattaforma sono i livelli.
Inizia a realizzarli uno per uno.
Provali finché ti soddisfano.
Ogni volta che ne hai voglia, introduci aspetti nuovi nel gioco, ecco alcune idee aggiuntive che puoi utilizzare:
Ecco alcune idee aggiuntive che puoi utilizzare
- mostri diversi, palle che rimbalzano, mostri che sparano
- chiavi da trovare, necessarie per aprire delle porte
- bombe che puoi spostare e che esplodono quando un mostro, o il personaggio, ci passa sopra
- acqua nella quale nuotare (questo cambierà completamente le regole: nessuna gravità, oppure una leggera gravità finché non raggiungi la superfice, tempo limitato prima di esaurire l’aria, bolle d’aria da raccogliere, …)
- muri e pavimenti che si possono distruggere, per esempio colpendoli o saltandoci sopra con forza
- trampolini che permettono di saltare più alto
- piattaforme che appaiono e scompaiono
- strade a senso unico
- piattaforme mobili (non è facile!)
- …
Buon divertimento.