Tratto da: Game Maker Tutorial – A Scrolling Shooter – Written by Mark Overmars – Copyright © 2007-2009 YoYo Games Ltd
shooter.zip
Sviluppato ulteriormente nel libro ufficiale.
I giochi del tipo scrolling shooter sono molto popolari e sono piuttosto semplici da realizzare con un ambiente di sviluppo come GameMaker.
In questo tutorial realizzeremo un gioco simile e, durante le varie fasi, impareremo alcuni aspetti di GameMaker, in particolare l’uso delle variabili.
Scrolling shooter
In uno scrolling shooter il giocatore controlla un oggetto (aeroplano, navicella spaziale, auto) che si muove su uno sfondo in movimento.
Sullo sfondo appaiono degli ostacoli che devono essere evitati e dei nemici ai quali bisogna sparare.
Spesso appaiono degli oggetti che devono essere raccolti per ottenere dei vantaggi aggiuntivi.
Durante il gioco i nemici aumentano di numero, tipo, pericolosità rendendo sempre più difficile sopravvivere.
In questo tutorial creeremo uno scrolling shooter di nome 1945, nel quale il giocatore vola con un aereo sul mare e degli aerei nemici cercano di distruggerlo.
Tratteremo diversi aspetti del gioco su come
- dare l’illusione del movimento tramite uno sfondo scorrevole
- controllare il volo di un aeroplano
- realizzare nemici e proiettili
- trattare il punteggio, le vite, e i danni all’aereo.
Variabili e proprietà
Prima di passare realmente alla creazione del gioco dobbiamo trattare per un po’ un argomento molto importante di GameMaker: l’uso delle variabili.
Questo semplice concetto ti fornirà un meccanismo molto potente per dare una giocabilità molto più attraente.
Che cos’è una variabile?
Puo essere vista semplicemente come una proprietà di un’istanza di un oggetto.
Come dovresti sapere, ci sono alcune proprietà che possiamo indicare quando definiamo un oggetto.
Per esempio possiamo impostare se è visibile, se è solido.
Ci sono anche azioni che modificano certe proprietà.
Per esempio ci sono azioni per cambiare la posizione o la velocità di un’istanza.
Ogni istanza ha un certo numero di proprietà e ci sono anche delle proprietà globali, come il punteggio, che non sono collegate alla singola istanza.
Tutte le proprietà sono memorizzate in variabili e hanno un nome.
Ecco alcune delle variabili / proprietà che ogni istanza ha:
x | la coordinata x |
y | la coordinata y |
hspeed | la velocità orizzontale (in pixel per passo) |
vspeed | la velocità verticale (in pixel per passo) |
direction | la direzione del movimento in gradi (0–360; 0 è orizzontale verso destra) |
speed | la velocità in quella direzione |
visible | se l’oggetto è visibile (1) o invisibile (0) |
solid | se l’oggetto è solido (1) o non solido (0) |
Ed ecco alcune variabili globali:
score | il valore attuale del punteggio |
lives | il numero attuale di vite |
mouse_x | la posizione x del mouse |
mouse_y | la posizione y del mouse |
room_speed | la velocità del livello (in passi al secondo) |
room_caption | il titolo della finestra |
room_width | larghezza del livello in pixel |
room_height | altezza del livello in pixel |
Ci sono molte altre variabili sia locali alle istanze che globali.
Si possono tutte ritrovare nella documentazione di GameMaker.
Ci sono azioni che modificano i valori di certe variabili ma, come vedremo, puoi anche trattarle direttamente.
E ancora meglio, puoi definire le tue variabili e utilizzarle come preferisci.
Per esempio, come vedremo più avanti, vogliamo che il nostro aereo possa sparare solo una volta ogni 5 passi del gioco.
Allora l’aereo ha bisogno di una proprietà che indichi se può o meno sparare.
Utilizziamo una variabile di nome can_shoot.
Il nome di una variabile deve essere composto solamente di lettere e del simbolo underscore.
I nomi delle variabili sono case-sensitive, quindi Can_shoot non è la stessa variabile can_shoot.
Nell’evento di creazione impostiamo questa variabile a 1 (utilizziamo 1 per indicare true).
Quando il giocatore vuole sparare controlliamo il valore della variabile per vedere se ha il permesso.
Ogni volta che viene sparato un colpo la proprietà viene impostata a 0 (indicando che lo sparo è temporaneamente disabilitato).
Poi usiamo un evento allarme per impostare la proprietà di nuovo a 1 dopo 5 passi.
Più avanti descriveremo tutto con maggior dettaglio.
Allo stesso modo possiamo usare le variabili per indicare se l’aereo ha uno scudo attivo, un’arma speciale, …
Ci sono 2 azioni importanti che trattano direttamente le variabili e che si trovano nella scheda Control:
Set the value of a variable
Questa può essere sia una delle variabile predefinite che una delle tue.
Specifica il nome della variabile e il nuovo valore.
Quando attivi la scelta Relative il valore dato è aggiunto al valore attuale della variabile.
Questo si può fare se la variabile ha già un valore assegnato!
Piuttosto che fornire alla variabile un semplice valore puoi anche assegnarle un’espressione.
Per esempio per raddoppiare il valore del punteggio potresti assegnare alla variabile score il valore 2*score.
If a variable has a value
Se il valore della variabile è uguale al numero dato, la domanda restituisce true e viene eseguita la prossima azione o blocco di azioni.
Se non è uguale, la prossima azione, o blocco di azioni, non viene eseguita.
Puoi anche specificare che il controllo sia se la variabile è minore del valore dato o maggiore del valore dato.
Non sei vincolato all’uso di variabili ma puoi controllare qualsiasi espressione.
Più avanti vedremo un certo numero di esempi sull’uso di queste azioni.
C’è un’altra cosa che devi sapere sulle variabili.
Come indicato prima ci sono variabili locali che appartengono a una istanza e ci sono variabili globali.
Quando usi le tue variabili queste sono sempre locali, che esistono solo per la istanza delle azioni in cui le usi.
Se vuoi usare le tue variabili globali devi aggiungere al loro nome il prefisso global. .
Quindi, per esempio, puoi usare la variabile global.bonus per indicare il numero di punti bonus raccolti dal giocatore.
Abbi cura di usare nomi di variabile che non esistano già e che siano diversi dai nomi delle sprite, suoni, ecc.
Un modo per riuscirci e far iniziare sempre i nomi delle tue variabili con var_, per esempio.
1945
Passiamo adesso al gioco che vogliamo creare.
Prima di creare un gioco abbiamo bisogno di stendere un documento di progetto.
Siccome il gioco che stiamo per sviluppare è abbastanza complesso, un documento di progetto completo richiederebbe almeno 2 pagine.
Per evitare di farla troppo lunga diamo una breve descrizione
1945 – Design Document
Description
In this game you control a plane flying over a sea.
You encounter an increasing number of enemy planes that try to destroy you.
You should avoid these or shoot them.
The goal is to stay alive as long as you can and to destroy as many enemy planes as you can.Game objects
The background is formed by a scrolling sea with some islands.
The player’s plane flies over this sea.
You can shoot bullets that destroy enemy planes.
There are four types of enemy planes: a plane that you encounter and should be destroyed, a plane that fires bullets downwards, a plane that fires bullets towards the player’s plane, and a fast enemy plane that comes from behind rather than from the front.Sounds
There are some explosion sounds and there is some background music.
Controls
The player controls the game with the arrow keys.
With the space key you fire a bullet.
Only one bullet can be fired every five steps.Game flow
The player immediately jumps into the game.
The player has three lives.
When all lives are gone a high-score table is shown.
Pressing the F1 (help) key will give a brief explanation.
Pressing the Esc key will end the game.Levels
There is just one level, but more and more enemy planes will arrive: first only the easy type but later the more difficult types.
Ecco come apparirà il gioco:
Il giocatore controlla il grosso aereo giallo che vola in avanti.
Nell’immagine si vedono i 4 tipi di aereo nemico: grigio, rosso, verde, blu.
In basso sono rappresentati il punteggio, il numero di vite rimaste, e i danni (sotto forma di barretta verde).
L’illusione del movimento
Un gioco scrolling shooter deve il suo nome al fatto che il mondo del gioco scorre sullo schermo, normalmentedall’alto verso il basso o da destra verso sinistra.
Questo dà l’idea del movimento.
Nel gioco 1945 il mondo si muove verticalmente.
Sebbene l’aereo controllato dal giocatore rimanga fermo sullo schermo hai l’impressione che voli sullo sfondo scorrevole.
Puoi controllarela posizione dell’aereo muovendolo in giro per lo schermo.
Questo dà l’impressione che l’aereo acceleri, quando si muove in avanti, e che rallenti quando si muove indietro.
È fondamentale che quando l’areo si muove indietro non lo faccia più velocemente dello sfondo scorrevole, altrimenti darebbe l’illusione di volare all’indietro, che è impossibile.
Allora, come si realizza uno sfondo scorrevole in GameMaker?
Ci sono due possibilità
- La prima possibilità è la più semplice: utilizzare una piccola immagine di fondo che si ripete e che si muove verso la parte bassa del livello.
- La seconda è più complicata e prevede di creare un’immagine molto grande per il livello e di renderne visibile solo una piccola parte, una vista.
La vista si sposta lentamente verso la parte alta del livello.
Cominceremo utilizzando uno sfondo in movimento.
Dopo discuteremo brevemente anche la seconda possibilità.
Siccome il nostro gioco si svolge sul mare abbiamo bisogno di uno sfondo che assomigli al mare visto dall’alto.
Aggiungiamo la piccola immagine seguente come risorsa background e le diamo il nome back_water:
Riempiendo lo sfondo con essa si avrà un’accettabile impressione del mare.
Per creare un livello con lo sfondo in movimento aggiungi un livello al gioco nel solito modo.
Clicca a sinistra sulla scheda backgrounds.
Bisogna cambiare tre impostazioni.
- Siccome stiamo per riempire tutto il livello con l’immagine non serve colorarlo con un colore di fondo, quindi disabilita la scelta Draw background color.
- Seleziona il menu in mezzo e scegli l’immagine di sfondo back_water.
L’impostazione di default è di riempire, Tile, l’intero livello e questo è quello che vogliamo. - Vogliamo che lo sfondo si muova, in basso imposta Vert. Speed a 2.
La finestra dovrebbe apparire così
Lancia il gioco per verificare che effettivamente abbiamo uno sfondo scorrevole che dà l’illusione del movimento.
Un sistema semplice sarebbe creare un’ampia immagine di sfondo e aggiungerci sopra le isole.
Lo svantaggio sarebbe che le isole apparirebbero in modo ripetitivo e il giocatore se ne accorgerebbe.
Forse lo hai notato pure tu che in alcuni cartoni animati c’è uno sfondo scorrevole che si ripete dietro al personaggio che corre.
Quindi scegliamo un approccio leggermente più complicato e aggiungiamo le isole come oggetti.
Creiamo 3 sprite con le immagini segeuenti (con sfondo trasparente, di default)
Siccome non controlleremo mai le loro collisioni è meglio che disabiliti la scelta Precise collision checking.
Creiamo un oggetto per ogni isola.
Nell’evento di creazione dell’oggetto diamo come velocità verticale la stessa dello sfondo in movimento.
In questo modo le isole appariranno come parte dello sfondo perchè rimarranno nella stessa posizione rispetto al mare in movimento.
Per assicurarci che tutti gli altri oggetti passeranno sopra le isole daremo alla proprietà Depth degli oggetti isole il valore10000.
Per poterlo fare devi lanciare GameMaker in Advanced Mode!
Le istanze degli oggetti vengono disegnate in ordine di profondità, depth.
Le istanze con il valore più grande sono disegnate per prime.
Le istanze con il valore più piccolo sono disegnate sopra tutte le altre.
Quindi, dando alle isole un valore alto esse saranno disegnate sempre per prime e si posizioneranno sotto gli altri oggetti.
Bisogna fare ancora un’altra cosa.
Quando le isole scompaiono nella parte bassa del livello vogliamo che riappaiano in alto.
Per questo controlleremo, nell’evento Step dell’isola, se l’isola è scomparsa al di sotto della schermata e se è vero la facciamo riapparire in alto.
Osserva che la variabile y indica la posizione verticale della istanza.
Il valore 0 corrisponde al punto più alto del livello!
La variabile room_height specifica l’altezza del livello.
Quindi l’sola scompare in basso se y è maggiore di room_height.
Possiamo usare l’azione per il controllo di una variabile per verificare se l’isola si trova al di sotto del livello:
Come vedi, come valore puoi usare il nome di un’altra variabile.
Puoi anche scriverci un’espressione.
Per spostarla in cima al livello utilizziamo l’azione Jump to a position.
Preferiamo saltare a una posizione casuale piuttosto che sempre alla stessa.
Utilizzando una posizione casuale le isole appariranno in modo meno regolare.
E quindi il giocatore non avrà l’impressione che appaiano sempre le stesse isole.
Come possiamo dare un valore casuale?
C’è una funzione random() per questo!
Cosa possiamo chiedere a una funzione?
Una funzione calcola un valore (o esegue un’azione) a partire dai valori di certi argomenti.
Gli argomenti si scrivono tra le parentesi dopo il nome della funzione.
Dove puoi scrivere un valore puoi anche utilizzare funzioni e variabili (ed espressioni che le coinvolgono).
Ci sono molte funzioni in GameMaker.
Per adesso ci serve soltanto la funzione random().
Nell’azione di jump utilizziamo random(room_width) come coordinata x.
Questo produrrà un valore casuale tra 0 e la larghezza del livello, come volevamo.
Ecco l’azione di jump come apparirà:
Utilizziamo –65 per la posizione y per essere sicuri che l’isola parta completamente al di sopra del livello.
Per la sua velocità verticale si porterà presto alla vista.
Facciamo la stessa cosa per i 3 oggetti isola.
Ci rimane di posizionare 3 isole nel livello ad altezze diverse e abbiamo finito con il nostro sfondo scorrevole.
Anche se le isole riappaiono a intervalli regolari, il giocatore non noterà che sono le stesse perché la posizione è diversa.
Potresti aggiungere una maggiore irregolarità quando le isole appaiono impostando un valore casuale (negativo) per la coordinata y.
L’aereo principale
Adesso che il nostro sfondo scorrevole è pronto, è il momento di realizzare l’aereo che l’utente controllerà.
È abbastanza semplice.
Prima di tutto abbiamo bisogno di una sprite per l’aereo.
Utilizzeremo un aereo a eliche.
Per dare l’illusione della rotazione delle eliche utilizziamo una sprite con 3 immagini che sono identiche eccetto che per le eliche:
Queste sprite animate si trovano in file con il nome che termina con _stripXX, dove XX indica il numero di sottoimmagini.
L’aereo dell’esempio si trova nella cartella Resources e si chiama myplane_strip3.png.
Quando creimo la sprite faccimao una cosa importante.
Impostiamo Origin X e Origin Y a 32.
Questo significa che l’origine della sprite è al centro dell’aereo.
In questo modo, quando in seguito sposteremo l’aereo o controlleremo dove si trova intenderemo sempre il centro dell’aereo e non l’angolo in alto a sinistra, che è usato normalmente come origine.
Questo è importante, per esempio, per far partire i proiettili dal centro piuttosto che dal lato sinistro.
Adesso aggiungiamo l’oggetto obj_myplane.
Come sprite scegliamo la sprite dell’aereo che abbiamo appena creato.
Assegnamo –100 a depth in modo che stia sopra i proiettili e tutto quello che aggiungeremo in seguito.
La proprietà depth risulterà determinante per molti giochi, quindi è bene che tu capisca subito come usarla.
Per il momento abbiamo bisogno di specificare soltanto il movimento dell’aereo.
Quando l’utente non fa nulla l’aereo non si muove.
Ricordati che lo sfondo si muove, non l’aereo!
Se il giocatore preme una delle 4 frecce, l’aereo si dovrebbe muovere nella direzione appropriata.
Il nostro impegno principale adesso è evitare che l’aereo esca dal livello.
Per questo controlleremo il movimento stesso piuttosto che assegnare all’aereo una velocità.
Si fa nel modo seguente.
Analizziamo il movimento corrispondente alla freccia sinistra.
Aggiungi un evento Keyboard e scegli <Left>.
Dobbiamo prima controllare di non essere troppo a sinistra.
Per questo utilizziamo l’azione per controllare che la variabile x sia maggiore di 40, come abbiamo fatto sopra quando abbiamo controllato la coordinata y dell’isola.
Se il controllo restituisce true allora spostiamo l’aereo di un piccolo passo a sinistra rispetto alla posizione attuale.
Utilizziamo l’azione Jump to a position con Relative attivato e –4 per x e 0 per y.
Facciamo la stessa cosa per la freccia destra.
Controlliamo se x è minore di room_width-40 e se è così facciamo un salto relativo con 4 per x e 0 per y.
Analogamente per il movimento verticale ma con passo verticale –2 e 2.
Ricordati che non possiamo muoverci più velocemente dello sfondo.
Inoltre, non dimenticare che le y crescono verso il basso quindi per salire bisogna sottrarre 2 alla coordinata y.
Per la parte bassa della schermata ci prendiamo un margine di 120.
Lo spazio rimasto sarà utilizzato più avanti per sistemarci il pannello con le informazioni del gioco.
Il nostro aereo adesso vola.
Posiziona un’istanza dell’aereo nel livello e lancia il gioco.
Dovresti avere l’illusione di volare sopra il mare.
Nemici e armi
Ma cos’è uno scrolling shooter se non puoi sparare e non ci sono nemici?
Amplieremo il nostro gioco con degli aerei nemici e aggiungeremo un cannoncino al nostro aereo in modo che possa sparare.
Iniziamo con il cannoncino.
Serve una sprite per il proiettile.
Impostiamo la sua origine al centro come abbiamo fatto per l’aereo.
Per renderlo più appariscente abbiamo realizzato un proiettile piuttosto grande: .
Le cose esagerate sono spesso importanti nei giochi.
Creiamo un oggetto con questa sprite.
Assegniamogli 0 per depth in modo tale che apparirà sotto l’aereo ma sopra le isole.
L’oggetto ha un comportamento piuttosto semplice.
Nell’evento Create aggiungiamo l’azione Speed Vertical e diamo -8 per farlo muovere verso l’alto.
Per evitare che i proiettili vaghino intorno dobbiamo distruggerli quando lasciano il livello.
Si può fare facilmente.
Nell’evento Step controlliamo se la variabile x è minore di –16.
Dovresti già sapere come si fa.
Se è così distruggiamo l’oggetto con l’azione appropriata .
Potresti anche usare l’evento Outside room che si trova negli eventi Other .
Il proiettile deve essere sparato quando l’utente preme la barra spaziatrice.
Come in molti giochi simili l’aereo dovrebbe sparare per tutto il tempo che il tasto è premuto.
Ma noi non vogliamo che ci siano troppi proiettili contemporaneamente.
Questo renderebbe il gioco troppo facile.
Permettiamo al giocatore di sparare solo 2 proiettili al secondo, cioè, uno ogni 15 passi.
Per ottenere questo utilizziamo la variabile can_shoot della quale abbiamo già parlato.
Nell’evento Create dell’aereo principale impostiamo la variabile a 1, indicando che si può sparare un proiettile.
Nell’evento del tasto <Space> controlliamo se la variabile can_shoot è uguale a 1.
Se è così creiamo un proiettile davanti all’aereo, Relative e alla posizione (0, -16) .
Inoltre impostiamo la variabile can_shoot a 0 indicando che non possiamo più sparare e impostiamo Alarm 0 a 15.
Ricorda che l’allarme scende di un passo alla volta fino a 0 e quando lo raggiunge si verifica un evento Alarm.
Nell’evento Alarm 0 impostiamo di nuovo la variabile a can_shoot a 1, indicando che possiamo sparare di nuovo.
Quindi l’evento <Space> dovrebbe essere simile a
Puoi cambiare la velocità con cui si può sparare cambiando il valore dell’allarme.
In altri giochi, se vorrai, potrai sparare più velocemente premendo la barra spaziatrice.
Si ottiene utilizzando le stesse azioni ma senza il controllo della variabile.
Si tratta di un piccolo aereo che semplicemente vola verso il basso.
Non spara ma se colpisce l’aereo principale il gioco finisce.
Nell’evento Create impostiamo la velocità verticale a 4 per farlo volare verso il basso.
Quando l’aereo raggiunge il fondo del livello lo facciamo riapparire in alto in posizione casuale, esattamente come abbiamo fatto per le isole.
Dovresti saperlo fare.
Dobbiamo definire due importanti eventi di collisione per l’aereo nemico:
- l’evento di collisione con il proiettile, che dovrebbe distruggere l’aereo nemico
- l’evento di collisione con l’aereo principale, che dovrebbe distruggere l’aereo principale e far finire il gioco.
Iniziamo con l’evento di collisione con il proiettile.
Sono necessarie un certo numero di azioni.
Prima di tutto abbiamo bisogno di un suono per una piccola esplosione e una sprite che indica l’esplosione.
Per creare un suono, premi Add sound e carica un suono piacevole per un’esplosione.
Per l’esplosione è necessaria una piccola sprite.
Impostiamo l’origine a (16, 16) come per l’aereo nemico.
Inoltre creiamo un oggetto esplosione e gli assegniamo la sprite dell’esplosione.
Non fa niente tranne che quando l’animazione dell’esplosione è finita si deve distruggere.
C’è un evento apposito Animation end tra gli eventi Other.
Quando sono pronti gli oggetti per il suono e per l’esplosione possiamo inserirli nell’evento collisione dell’aereo nemico con il proiettile.
Le azioni seguenti sono necessarie.
- Prima di tutto facciamo sentire l’esplosione.
- Poi distruggiamo il proiettile.
Per questo usa l’azione Destroy an instance ma, in alto, indica che deve essere applicato all’istanza Other, che in questo caso è il proiettile. - Poi creiamo l’oggetto esplosione, con posizione (0,0) Relative, cioè, nello stesso posto dell’aereo nemico.
Non distruggiamo l’aereo nemico!
Invece lo spostiamo in alto in posizione casuale per dare l’impressione che stia arrivando un altro aereo nemico. - Infine, impostiamo il punteggio a 5, Relative (vogliamo aggiungere 5 punti al punteggio, non ripartire da 5 punti).
Quindi l’evento dovrebbe essere simile a
Abbiamo bisogno di nuovo di un’immagine (più grande) e di un suono per l’esplosione (più potente).
Aggiungiamo il suono al gioco e realizziamo la sprite per l’esplosione.
Di nuovo creiamo un oggetto esplosione, ma questo oggetto è un po’ più complicato dell’altro oggetto esplosione perché dovrà gestire anche la fine del gioco.
Nel suo evento Animation end facciamo alcune cose.
Prima distruggiamo l’istanza per farlo scomparire.
Poi aspettiamo un po’ per essere sicuri che è finito il suono dell’esplosione.
L’azione successiva visualizza la classifica dei punteggi, in modo che il giocatore possa scrivere il suo nome se ha raggiunto un punteggio alto.
Tuccio ciò avviene automaticamente in GameMaker.
Puoi anche specificare come dovrebbe apparire il tabellone (colore di sfondo, caratteri, …)
Fai un po’ di esperimenti con queste cose.
Infine facciamo ripartire il gioco.
Quindi l’evento appare simile a
Nell’evento collisione dell’aereo nemico con l’aereo principale, trasformiamo l’aereo principale in un’altra istanza, un’esplosione.
Inoltre emettiamo il suono dell’esplosione e distruggiamo l’aereo nemico.
Ci rimane da posizionare l’aereo nemico nel livello ma lo faremo in modo leggermente diverso.
Un buon gioco diventa sempre più difficile.
Allora iniziamo con un solo aereo nemico e aggiungiamone altri nel tempo.
Per questo motivo creiamo un nuovo oggetto che chiameremo controller_enemy.
Esso controlla la creazione di aerei nemici.
Lo rendiamo invisibile deselezionando la casella di scelta Visible.
Non è richiesta la sprite.
Nel suo evento Create creiamo un aereo nemico in posizione casuale appena sopra il livello.
Questo sarà il primo nemico.
Inoltre impostiamo l’allarme a 200.
Nell’evento per quest’allarme creiamo un altro aereo nemico e impostiamo l’allarme ma questa volta a 500.
Ecco tutto.
Il risultato è che all’inizio del gioco c’è un solo aereo nemico.
Dopo 200 passi, circa 7 secondi, appare un secondo aereo nemico.
Dopo circa 15 secondi appare un terzo aereo, ecc.
Il motivo perché il secondo aereo appare prima è perché il gioco con un solo aereo è troppo noioso.
Posiziona una copia dell’oggetto controllore nel livello e abbiamo finito.
Con questo la seconda versione di 1945 è finita.
Abbiamo un gioco giocabile con un nemico.
Punteggio, vite e danni
È piuttosto deludente che il gioco finisca ogni volta che sei colpito.
Per rendere il gioco un po’ più interessante faremo in modo che i nemici provochino dei danni.
Soltanto quando l’aereo ha subito troppi danni allora sarà distrutto.
Inoltre introdurremo vite multiple e creeremo un piacevole pannello che visualizza queste informazioni, più il punteggio.
Fortunatamente tutto questo sarà molto semplice perché GameMaker ha un meccanismo predefinito per gestire punti, vite esalute (l’opposto di danni).
Per realizzare tutto questo creiamo un nuovo oggetto di nome controller_life.
Non ha bisogno di una sprite perché controlleremo il suo disegno tramite l’evento Draw .
Come sai, a ogni passo la sprite associata a un oggetto viene normalmente disegnata alla posizione corretta nel livello.
Se invece sistemiamo delle azioni nell’evento Draw questo non succederà più.
Adesso le azioni determineranno cosa deve essere disegnato.
È disponibile un’intera collezione di azioni solo per disegnare.
La maggior parte di esse si trovano nella scheda Draw.
Ma puoi usare anche altre azioni per questo.
Le azioni di disegno hanno senso solo nell’evento Draw.
In un altro posto saranno praticamente ignorate.
Per cominciare creiamo una grande sprite che funzioni da pannello delle informazioni.
Eccola
Mostrerà i punti, i danni (l’area nera a sinistra), e il numero di aerei rimasti, cioè il numero di vite.
Nell’evento Draw di controller_life disegniamo la sprite di questo pannello alla posizione corretta utilizzando l’azione Draw Sprite
Compiliamo i parametri come segue
In questo modo la sprite sarà posizionata correttamente in fondo allo schermo.
Utilizzare –1 per subimage significa che viene disegnata la subimage attuale.
Siccome c’è una sola sottoimmagine nella sprite non dovremmo preoccuparcene, ma se una sprite consistesse di immagini multiple allora potresti indicare quale immagine vuoi vedere.
Pe essere sicuri che il pannello si trovi sopra qualsiasi altra cosa diamo alla proprietàdepth di controller_life il valore –10000.
Nel suo evento Create, l’oggetto controller_life imposta score a 0, il numero di vite a 3, e health a 100.
Ci sono azioni specifiche per questo nella scheda Score.
Per disegnare i punti utilizziamo l’azione specifica nella scheda Score.
Prima impostiamo il colore di disegno a giallo.
Nell’azione per disegnare il punteggio compiliamo come segue i parametri (nessuna etichetta perché si trova già sullo sfondo)
C’è un’azione specifica nella scheda Score
Siccome ci occupiamo noi di mostrare i punti e le vite allora non vogliamo che vengano visualizzati nella barra del titolo della finestra.
C’è un’azione nella scheda Score per specificare cosa deve essere visualizzato nella barra del titolo.
Posiziona questa azione nell’evento Create dell’oggetto e specifica che nulla deve essere visualizzato, don’t show.
Anche per visualizzare la salute c’è un’azione specifica .
La salute è visualizzata sotto forma di barretta orizzontale.
Puoi specificare la posizione, la dimensione e lo schema di colore.
Compiliamo così i parametri
Dobbiamo ancora controllare la salute e le vite.
Prima dobbiamo fare alcune modifiche all’evento collisione tra l’aereo nemico e l’aereo principale.
Non dovrebbe più distruggere l’aereo principale ma soltanto distruggere se stesso (trasformandosi in un’esplosione) e diminuire la salute, impostandola a -30, Relative (così scende di 3 tacche).
L’oggetto controller_life controllerà quando la salute diventerà minore di 0.
C’è un evento per questo sotto gli altri eventi.
In questo evento facciamo scoppiare l’aereo trasformandolo in una grande esplosione.
Inoltre reimpostiamo la salute e facciamo emettere il suono corretto.
L’evento sarà impostato come
L’oggetto obj_explosion2, nel suo evento Animation End, distrugge se stesso.
Aspetta per un po’, per far finire il suono, crea un nuovo aereo principale alla posizione corrente, cioè in (0, 0) Relative, ) e riduce il numero di vite, cioè imposta a –1, Relative.
Infine, dobbiamo controllare quando siamo rimasti senza vite.
Fortunatamente, c’è un evento anche per questo.
In questo evento, tramite l’oggetto controller_life, visualizziamo la classifica e facciamo ripartire il gioco.
Con questo è finita la terza versione del gioco.
Ci puoi giocare e adesso risulta abbastanza piacevole.
Ma il gioco diventa presto noioso.
Dobbiamo migliorarlo ancora un po’ e aggiungere delle variazioni.
Più aerei nemici
In questa sezione aggiungeremo al nostro gioco 3 nuovi tipi di aereo nemico.
- Uno sparerà proiettili verso il basso.
- Un altro sparerà proiettili verso l’aereo principale.
- L’ultimo non sparerà proiettili ma partirà dal basso del livello e sarà più difficile da evitare o colpire.
Faremo in modo che appaiano più avanti nel livello durante il gioco.
Per creare il primo nuovo tipo di aereo nemico dobbiamo realizzare una nuova sprite per esso, simile alla sprite del primo aereo ma di colore diverso.
Poi è necessario un nuovo oggetto.
Siccome il comportamento sarà simile a quello del primo aereo nemico facciamo una copia di questo oggetto (pulsante destro e poi Duplicate).
fai doppio clic sul nuovo oggetto per modificarlo.
Dagli un nuovo nome e imposta la sprite corretta.
Siccome si tratta di un aereo più pericoloso il giocatore otterrà un punteggio maggiore quando lo colpirà.
Quindi nell’evento collisione con il proiettile modifichiamo score a 10.
Per fare in modo che l’aereo nemico spari, abbiamo bisogno di una sprite per il proiettile e di un oggetto proiettile.
Questo oggetto, nell’evento Create, acquista una velocità verticale verso il basso.
Nell’evento Step curiamo che l’oggetto si distrugga quando finisce in basso fuori dal livello.
Nell’evento di collisione di questo proiettile con l’aereo principale impostiamo health a -5, Relative, distruggiamo il proiettile, e emettiamo un suono.
Adesso dobbiamo fare in modo che l’aereo nemico spari proiettili di tanto in tanto.
Lo facciamo nell’evento Step dell’aereo.
Utilizziamo l’azione per lanciare un dado e come parametro impostiamo 30.
Questo significa che la prossima azione sarà eseguita in media una volta ogni 30 passi.
In questa prossima azione creiamo il proiettile nemico.
Infine dobbiamo assicurarci che a un certo punto il secondo tipo di aereo nemico inizi ad apparire.
Per questo utilizziamo di nuovo un oggetto controller_enemy.
Nell’evento Create impostiamo Alarm 1 al valore 1000.
In questo evento allarme creiamo il secondo aereo nemico e impostiamo di nuovo Alarm 1 ma a 500 per creare un altro aereo un po’ più tardi.
Quindi il primo aereo di questo tipo apparirà dopo circa 30 secondi e i successivi appariranno circa ogni 15 secondi.
Per il nuovo tipo di aereo nemico abbiamo di nuovo bisogno di una sprite e di un oggetto proiettile.
Facciamo una copia del secondo aereo nemico e, come prima, nell’evento di collisione con il proiettile normale cambiamo il punteggio perché aumenti di 20.
Creiamo anche un oggetto per un secondo proiettile nemico.
L’aereo nemico crea questo nuovo tipo di proiettile nel suo evento Step.
Di nuovo utilizziamo l’azione dado ma adesso creiamo un proiettile ogni 80 passi, perché il nuovo tipo di proiettile è più difficile da evitare.
Il nuovo tipo di proiettile funziona così.
Nel suo evento di creazione utilizziamo l’azione Move Towards
Quale posizione utilizziamo?
Bene, vogliamo sparare verso la posizione dell’aereo principale.
Quindi abbiamo bisogno di conoscere le coordinate x e y dell’istanza di questo oggetto.
Questo si può fare facilmente Game Maker.
Per ottenere il valore di una variabile di un’altra istanza precediamo il nome della variabile con il nome dell’oggetto.
Quindi utilizziamo obj_myplane.x per indicare il valore della coordinata x dell’aereo.
Se ci sono istanze multiple di questo oggetto otteniamo il valore della variabile della prima istanza.
Se non ci fosse nessuna istanza dell’oggetto otterremmo un messaggio di errore.
Questo potrebbe essere un problema quando l’aereo è distrutto e quindi non c’è nessun aereo.
Quindi è meglio se prima controlliamo se l’aereo c’è.
Esiste un’azione che conta il numero di istanze di un particolare oggetto.
La utilizziamo per controllare quando l’aereo principale è presente o meno, e se c’è dirigiamo il proiettile verso l’aereo.
Alltrimenti il proiettile si dirigerà verso il basso.
L’evento Create dovrebbe apparire così
L’azione per muoversi verso un certo punto assume i seguenti parametri
Ma ecco che c’è un evento speciale per questo, l’evento Outside.
In questo evento inseriamo semplicemente un’azione per distruggere l’oggetto.
Infine dobbiamo gestire la creazione del nuovo tipo di aerei.
Come detto prima utilizzeremo l’oggetto controller_enemy per questo.
Nell’evento Create impostiamo Alarm 2 a 2000.
Nell’evento di questo allarme creiamo il nuovo tipo di aereo nemico e impostiamo di nuovo Alarm 2 a 1000 per crearne un altro qualche tempo dopo.
Con questo termina l’operazione di aggiungere il nuovo tipo di aereo.
Rimane da aggiungere che gli aerei arrivino dal basso.
Questo si fa esattamente allo stesso modo del primo aereo nemico, eccetto che l’aereo parte dal basso del livello e si muove verso l’alto piuttosto che verso il basso.
L’oggetto controller_enemy di nuovo li crea utilizzando adesso Alarm 3.
Dovresti ormai sapere come si fa…
Questo termina la nostra quarta versione di 1945.
Adesso è diventato un gioco piacevole da giocare che diventa sempre più difficile nel tempo.
Adesso c’è del divertimento nel giocarci e nel cercare di ottenere il punteggio più alto.
Finire il gioco
Abbiamo appena realizzato uno scrolling shooter con diversi aerei nemici.
È diventato un gioco piacevole con difficoltà crescente e ci si diverte nel giocarci e nel tentare di ottenere il punteggio più alto.
Ma perché diventi un vero gioco sono necessarie ancora delle rifiniture.
Abbiamo bisogno di
una musica di sottofondo | … |
un’immagine iniziale | |
un’icona migliore |
Ho aggiunto anche un ritardo negli aerei per farli riapparire quando sono colpiti, rendendo più importante per il giocatore cercare di colpirli piuttosto che semplicemente evitarli.
Infine c’è uno sparo aggiuntivo se il giocatore ha raggiunto i 400 di score e un ulteriore sparo se ha raggiunto i 1000.
Puoi usare questo gioco come una base per ulteriori sviluppi.
Ecco alcune idee su che cosa potresti aggiungere
- Sono piuttosto diffusi nei giochi scrolling shooter oggetti che, se raccolti dal giocatore, danno extra punti, extra potenza, riparano i danni, …
Questi oggetti dovrebbere apparire quando il giocatore riesce a colpire un aereo nemico oppure semplicemente durante il volo. - Potresti aggiungere nuovi tipi di aereo, per esempio che volano di lato oppure che lanciano missili più potenti.
Ti lascio a lavorare su questi nuovi impegni e a realizzare il tuo scrolling shooter.
Nel file Resources/1945_sprites.bmp puoi trovare un’ampia collezione di immagini, create da Ari Feldman, che sono particolarmente adatte a questo gioco.
Per estrarre le singole immagini da questo file
- crea una sprite
- clicca il pulsante Edit sprite
- seleziona la voce di menu File > Create from Strip
- seleziona l’immagine che ti interessa
Consulta l’help per maggiori dettagli.
Il gioco con timeline
In questa sezione e nella successiva tratteremo due ulteriori caratteristiche di GameMaker che molto utili nella realizzazione di scrolling shooter più complessi:
- i temporizzatori
- le viste.
Nel gioco che abbiamo appena realizzato la comparsa dei nemici era controllata dall’oggetto controller_enemy che di tanto in tanto aggiungeva un aereo nemico al gioco.
Inoltre gli aerei nemici non venivano mai realmente distrutti, infatti riapparivano.
Il risultato era un gioco che diventava sempre più difficile per il numero sempre più grandi di aerei.
Sebbene questo renda il gioco ragionevole ha anche delle controindicazioni
- Gli aerei appaiono in posizioni casuali che il progettista del gioco non può controllare.
Di conseguenza gli aerei possono apparire uno sull’altro oppure troppo vicini ai bordi e questo non è piacevole. - C’è poca sorpresa nel gioco.
I nemici arrivano in modo casuale e il giocatore per tutto il tempo spara e cerca di evitarli.
Pe avere un gioco più interessante il progettista del gioco dovrebbe avere più controllo sulla posizione dove appaiono gli aerei e in quale momento.
Questo ti permette di creare degli aerei nemici che arrivano in formazione, creando delle sfide (come un gruppo numeroso di aerei semplici che conviene evitare oppure un gruppi eseguo ma che è meglio colpire) e delle variazioni.
Inoltre il giocatore potrebbe imparare a giocare facendo esperienza e ricordandosi le cose importanti.
Tutti i buoni giochi controllano piuttosto precisamente i nemici per i motivi descritti sopra.
Semplicemente, diventa più interessante giocarci.
Quindi vogliamo avere maggiore controllo sull’apparizione dei nemici.
Per questo utilizzeremo le risorse time line, temporizzatori.
Ma prima dobbiamo fare alcune modifiche al gioco.
Non facciamo più riapparire gli aerei nemici quando vengono colpiti o escono dallo schermo.
Semplicemente li distruggiamo.
Cioè quando un aereo scompare, lo fa per sempre.
L’oggetto temporizzatore controllerà la creazione dei nemici.
Una risorsa temporizzatore funziona come segue.
In essa specifichi un certo numero di istanti di tempo (misurati in step del gioco) e per ciascuno di essi specifichi le azioni che devono essere eseguite in quel momento.
Siccome utilizzeremo il temporizzatore per generare gli aerei nemici allora utilizzeremo solo azioni Create ma in generale puoi usare qualsiasi azione.
Realizziamo il nostro temporizzatore.
- Scegli Resources > Create time line.
Apparirà una finestra simile a quella per un oggetto.
A sinistra indichi il nome della risorsa e ci sono dei pulsanti Add, Delete, …
Al centro puoi vedere la lista Moments dei momenti definiti.
E subito dopo la lista Actions delle azioni per il momento attualmente selezionato.
A destra ci sono le schede con le azioni da scegliere. - Al momento Step 0 vogliamo creare un aereo nemico.
Clicca il pulsante Add.
Come moment indica il valore 0.
Il momento è stato aggiunto alla lista.
Adesso, tramite drag an drop, aggiungi l’azione per creare un aereo nemico. - Siccome un aereo nemico impiega circa 100 step per attraversare il livello, aggiungiamo un secondo momento allo step 100.
Qui creiamo 2 aerei nemici vicini. - Continuiamo in questo modo.
Aggiungiamo momenti e aggiungiamo azioni di creazione per aerei nemici.
Creando gli aerei ad altezze diverse possiamo realizzare delle piacevoli formazioni.
Dopo l’aggiunta di un certo numero di momenti la finestra diventa:
Al momento 400 selezionato, creiamo una linea di 9 aerei nemici, 2 dei quali sparano proiettili!
Dovresti aver capito il meccanismo.
Aggiungi momenti con sempre più aerei in formazioni interessanti e a intervalli di tempo sempre più vicini.
Ci vorrà un po’ di lavoro per realizzare una sequenza che renda il livello del gioco avvincente.
In un gioco completo utilizzerai un temporizzatore per ogni livello.
Alla fine della sequenza hai bisogno di un momento che chiude il livello oppure il gioco.
In questo punto visualizzerai probabilmente un messaggio di fine livello oppure, meglio, una piacevole sequenza finale, come un aircraft carrier appearing on which your plane lands.
Non abbiamo ancora finito.
Il temporizzatore non esegue automaticamente le azioni!
Devi assegnare un temporizzatore a un oggetto e poi le azioni saranno eseguite per quell’oggetto.
Utilizziamo di nuovo l’oggetto controller_enemy.
Serve soltanto un’azione nel suo evento Create che imposta il temporizzatore appropriato.
Questo è tutto.
Come noterai, utilizzare un temporizzatore richiede un certo lavoro perché è necessario specificare tutti gli aerei nemici che dovranno apparire ma ti offre tanta flessibilità per rendere il gioco un po’ più interessante.
Si possono fare molte cose con i temporizzatori.
Noi qui li abbiamo utilizzati per controllare il flusso globale del gioco ma potresti utilizzarli anche per controllare il comportamento di oggetti del gioco nel tempo.
Ci sono molte altre tecniche che puoi utilizzare
- Per fermare un temporizzatore per un po’, aggiungi un momento nel quale controlli qualche condizione e di conseguenza imposti la posizione a -1, Realative.
In questo modo lo stesso momento accadrà di nuovo e la condizione controllata di nuovo.
Il temporizzatore non avanzerà finché la condizione è falsa.
C’è anche un’azione per mettere in pausa un temporizzatore. - Le istanze possono anche cambiare temporizzatore in base a certi eventi.
- Puoi anche controllare la velocità di un temporizzatore.
In conclusione si tratta di una risorsa molto potente.
Il gioco non è completo.
È solo una base di partenza, devi estenderlo ancora per trasformarlo in un gioco interessante.
Il gioco con vista
Finora abbiamo ingannato il giocatore nel senso che non stavamo veramente volando nel gioco ma era lo sfondo che stava scorrendo.
Questo ha un certo numero di svantaggi.
In particolare, lo sfondo non può cambiare facilmente.
Per esempio è difficile volare a mezza altezza.
Inoltre, anche se utilizzi le linee del tempo è più difficile far apparire azioni diverse nel tempo.
In questa parte finale indicheremo brevemente un modo diverso per realizzare uno scrolling shooter/.
In questo approccio c’è un grande livello attraverso il quale l’aereo si muove veramente.
Utilizziamo le viste in modo che il giocatore veda in ogni istante solo una parte del livello.
Per ottenere questo dobbiamo effettuare un certo numero di modifiche al gioco.
Le tratteremo velocemente.
Realizziamo il livello di base.
- Diamo al livello una larghezza di 640, come prima ma adesso gli diamo un’altezza di 4800!.
- L’immagine dello sfondo non ha più una velocità.
- Sistemiamo le isole in diversi punti del livello.
- Gli oggetti nel livello non hanno più una velocità e quindi possiamo rimuovere l’evento Step.
Adesso sono oggetti completamente statici. - Sistemiamo l’aereo in fondo al livello e gli diamo, nell’evento Create, una velocità verticale di -2 per assicurarci che voli con qualche velocità se l’utente non fa nulla.
Infine definiamo la vista
- Seleziona la scheda views nella finestra del livello.
- Attiva Enable the use of Views.
- Definisci la prima vista, View 0, e attiva Visible when room starts.
- Imposta View in room, y=4320, cioè la vista sarà alla base del livello.
Ecco le impostazioni della vista
Dobbiamo assicurarci che la vista si muova con velocità costante.
Per questo utilizzeremo (?) l’evento Step dell’oggetto controller_life.
Ci aggiungiamo l’azione per impostare una variabile e assegnamo -2, Relative, a view_yview.
La variabile view_yview indica la posizione in alto della prima vista nel livello.
Se ci fossero viste multiple allora dovresti utilizzare view_yview[0].
Quindi a ogni passo la posizione della vista si muove di 2 pixel in su creando lo scorrimento.
Ci sono moltre altre variabili collegate alle viste ma non ci servono in questo momento.
Dobbiamo anche controllare se la variabile view_yview è maggiore di 0*.
Se diventa 0* allora la vista ha raggiunto la cima e dovremo fermare il gioco.
Osserva che avevamo stabilito che l’aereo principale non potesse uscire dalla vista.
Controllavamo se la posizione dell’aereo era troppo alta o troppo bassa.
Adesso dobbiamo utilizzare la variabile view_yview nel confronto per essere sicuri che l’aereo stia nella vista.
Abbiamo un problema simile con la posizione del pannello informativo e tutto il suo contenuto.
Lo avevamo posizionato in fondo al livello, ma ora dobbiamo disegnarlo alla posizione corretta relativa a view_yview per assicurarci che si visibile.
Dobbiamo anche aumentare la velocità dei proiettili che spara l’aereo per compensare il movimento della vista.
Inoltre dobbiamo distruggerli quando escono dalla vista.
Rimangono da trattare gli aerei nemici.
Non usiamo più il temporizzatore o l’oggetto controller_enemy.
Sistemeremo gli aerei nemici già nel livello, ma senza farli muovere finché non diventano visibili.
Quindi non impostiamo la loro velocità iniziale e nell’evento Step controlliamo se sono in vista.
Se lo sono li facciamo muovere.
Inoltre, li faremo sparare solo se sono in vista.
Per esempio per il 3° aereo nemico l’evento Step assomiglia a
Osserva che dobbiamo usare una velocità verticale più piccola di prima.
Inoltre, sia per gli aerei nemici che per i proiettili dobbiamo cambiare le regole per quando devono essere distrutti.
L’aereo nemico più complicato è il 4°.
Deve arrivare da dietro.
Il trucco è il seguente.
Lo inseriamo dall’inizio nel livello ma lo rendiamo invisibile.
Inoltre finché è invisibile non reagisce alle collisioni con i proiettili e con l’aereo principale.
Quando si trova nella vista lo rendiamo visibile e lo facciamo muovere (con una velocità più alta).
Guarda il gioco d’esempio per vedere come questo è stato ottenuto.
Adesso costruiamo il livello.
Posizioniamo diversi aerei nemici nel livello in posti strategici.
Di nuovo, è facile creare delle formazioni e sfide divertenti.
Come vedi, utilizzando le viste puoi creare uno scrolling shooter con relativamente poco lavoro.
Chiaramente il gioco necessita di molto lavoro ancora.
- In un certo senso, è ancora troppo facile finirlo ed è evidentemente troppo corto.
- Inoltre sarebbe grande qualche simpatica sorpresa alla fine.
Utilizza questi consigli come primo passo e vai avanti nella realizzazione.