Category Archives: –GIOCHI–

A scrolling shooter – 1945 – Con vista

1945Questo tutorial è una rielaborazione di: Game Maker Tutorial – A Scrolling Shooter – Written by Mark Overmars – Copyright © 2007-2009 YoYo Games Ltd
www.yoyogames.com/downloads/tutorials/shooter.zip

Questo tutorial tratta direttamente la versione con vista di 1945.

I giochi del tipo scrolling shooter sono molto popolari e sono piuttosto semplici da realizzare con un ambiente di sviluppo come GameMaker.
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 numerotipopericolosità 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.

Ecco come apparirà il gioco:

1945
Il giocatore controlla il grosso aereo giallo che vola in avanti.
Nell’immagine si vedono anche gli aerei nemici.
In basso sono rappresentati il punteggio, il numero di vite rimaste (gli aerei piccoli), e i danni (sotto forma di barretta verde).

 

Il movimento

Allora, come si realizza uno sfondo scorrevole in GameMaker?
Discuteremo la seguente tecnica tra quelle disponibili

  • Creeremo un’immagine molto grande per il livello e ne renderemo visibile solo una piccola parte, una vista.
  • La vista si sposta lentamente verso la parte alta del livello.

Crea le risorse di base

TIPO NOME FILE
Sprite spr_water water.png Water
spr_island1 island1.png Isola 1
spr_island2 island2.png Isola 2
spr_island3 island3.png Isola 3
spr_myplane myplane_strip3.png Aereo
Background back_water spr_water
Object obj_myplane spr_myplane
obj_island1 spr_island1
obj_island2 spr_island2
obj_island3 spr_island3
obj_controller <no sprite>
Room room_game

Isola 1obj_island1

Isola 2obj_island2

Isola 3obj_island3

  • Depth=10000

Le isole sono degli oggetti inanimati, rimangono fissi sullo sfondo.
La profondità, depth, altissima serve a farle stare dietro tutti gli altri oggetti.

room_game

SCHEDA IMPOSTAZIONI COMMENTO
settings Width: 640
Height: 4800 10 schermate in verticale
backgrounds Draw background color no
Visible when room starts
back_water Tramite il pulsantino a destra
Til. Hor. L’immagine dell’acqua è ripetuta orizzontalmente e verticalmente
Tile Vert.
objects obj_myplane Al centro in basso…
obj_islandX Tante isole dove preferisci
views Enable the use of Views
View 0
Visible when room starts
X: 0 Posizione iniziale della vista
Y: 4320
W: 640 Dimensione della vista
H: 480
X: 0 Nessuna porta
Y: 0
W: 640
H: 480
<no object> Nessun oggetto da seguire

Ecco le impostazioni della vista

Livello

 

Aereoobj_myplane

  • Depth=-100

image Create

Vertical Speed Action Set the vertical speed to -2

image <Left>

Text Expression If x is larger than 40

Start Block Start of a block
Jump to Position Jump relative to position (-4,0)
End Block End of a block

 

image <Right>

Text Expression If x is smaller than room_width-40

Start Block Start of a block
Jump to Position Jump relative to position (+4,0)
End Block End of a block

 

image <Up>

Text Expression If y is larger than view_yview+40

Start Block Start of a block
Jump to Position Jump relative to position (0,-2)
End Block End of a block

 

image <Down>

Text Expression If y is smaller than view_yview+480-120

Start Block Start of a block
Jump to Position Jump relative to position (0,-2)
End Block End of a block

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.
Con depth=-100 viene disegnato sopra tutti gli altri oggetti.
Le 4 frecce spostano l’aereo ma fino a una certa distanza (40) dal bordo.

obj_controller

Step Event Step

image Set variable view_yview relative to -2

Sposta la vista verso l’alto a ogni passo.

 

Aerei nemici

Aggiungiamo al gioco degli aerei nemici.
Il nostro aereo può sparare dei proiettili per tentare di colpire e distruggere gli aerei nemici.
Se viene a contatto con uno di essi esplode e ricomincia il gioco.

Aggiungi le risorse

TIPO NOME FILE
Sprite spr_enemy1 enemy1_strip3.png Aereo Nemico 1
spr_bullet bullet.png Proiettile
spr_explosion1 explosion1_strip6.png Esplosione 1
spr_explosion2 explosion2_strip7.png Esplosione 2
Sound snd_explosion1 explosion1.wav
snd_explosion2 explosion2.wav
Object obj_enemy1 spr_enemy1
obj_bullet spr_bullet
obj_explosion1 spr_explosion1
obj_explosion2 spr_explosion2

Aereoobj_myplane

image Create

Vertical Speed Action Set the vertical speed to -2
image Set variable can_shoot to 1

image <Space>

If Var Action If can_shoot is equal to 1

Start Block Start of a block
image Create instance of object obj_bullet at relative position (0,-16)
image Set variable can_shoot to 0
image Set Alarm 0 to 15
End Block End of a block

image Alarm 0

image Set variable can_shoot to 1

image <Left>
image <Right>
image <Up>
image <Down>

Come prima.

Permettiamo al giocatore di sparare solo 2 proiettili al secondo, cioè, uno ogni 15 passi.
Nell’evento Create dell’aereo principale impostiamo la variabile can_shoot 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, impostiamo la variabile can_shoot a 0 indicando che non possiamo più sparare e impostiamo Alarm 0 a 15.
L’allarme scende di un passo alla volta fino a 0 e quando lo raggiunge si verifica un evento Alarm 0.
Nell’evento Alarm 0 impostiamo di nuovo la variabile can_shoot a 1, indicando che possiamo sparare di nuovo.

Ecco tutti gli eventi dell’aereo con in primo piano l’evento <Space>

Evento Space

Aereo Nemico 1obj_enemy1

Step Event Step

If Var Action If y is smaller than view_yview-32

Start Block Start of a block
image Exit this event
End Block End of a block

If Var Action If y is larger than view_yview+480

Start Block Start of a block
image Exit this event
End Block End of a block

Speed Vertical Set the vertical speed to -10
If Var Action If y is larger than view_yview+480

Start Block Start of a block
Destroy Action Destroy the instance
End Block End of a block

Collision Event obj_myplane

Play Sound Play sound snd_explosion2; looping: false
image Create instance of object obj_explosion2 at relative position (0,0)
image Destroy the instance

Collision Event obj_bullet

Play Sound Play sound snd_explosion1; looping: false
image For other destroy the instance
image Create instance of object obj_explosion1 at relative position (0,0)
image Destroy the instance

Si tratta di un piccolo aereo che semplicemente vola verso il basso.
Non spara ma se colpisce l’aereo principale il gioco finisce.
L’aereo nemico è già nel livello da qualche parte ma non si muove se è invisibile.
Quando è in vista comincia a muoversi ma se supera il bordo inferiore si distrugge.
Nella collisione con il proiettile emette un suono, distrugge il proiettile, crea un’esplosione e si distrugge.
Nella collisione con l’aereo principale emette un suono (più potente), crea un’esplosione (più potente) e si distrugge.

Proiettileobj_bullet

Create Event Create

Speed Vertical Set the vertical speed to -10

 

Step Event Step

If Var Action If y is smaller than view_yview-16

Start Block Start of a block
Destroy Action Destroy the instance
End Block End of a block

Nell’evento Create gli diamo una velocità verso l’alto.
Nell’evento Step controlliamo se ha superato il bordo in alto e lo distruggiamo.

 

Esplosione 1obj_explosion1

image Animation End

image Destroy the instance

Non fa niente tranne che quando l’animazione dell’esplosione è finita si deve distruggere.

Esplosione 2obj_explosion2

image Animation End

image Destroy the instance
image Sleep 1000 milliseconds
Restart Game Restart the game

Questo oggetto è un po’ più complicato dell’altro oggetto esplosione perché deve gestire anche la fine del gioco.
Prima distruggiamo l’istanza per farlo scomparire.
Poi aspettiamo un po’ per essere sicuri che è finito il suono dell’esplosione.
L’azione successiva fa ripartire il gioco.

 

Il tabellone

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 le vite e disegneremo un pannello che visualizza tutte queste informazioni.

Aggiungi le risorse

TIPO NOME FILE
Sprite spr_life life.png Life
spr_bottom bottom.png Vedi sotto.

Pannello

 

Aereo Nemico 1obj_enemy1

Step Event Step

Collision Event obj_myplane


image Set the health relative to -30

 

Collision Event obj_bullet


image Set the score relative to 5

Scontrarsi con un aereo nemico provoca un danneggiamento di 30.
Colpire un aereo nemico fa guadagnare 5 punti.

obj_controller

  • Depth=-10000

image Create

image Set the score to 0
image Set the number of lives to 3
image Set the health to 100
image Set the information in the window caption: don’t… don’t … don’t …

 

Step Event Step

image Set variable view_yview relative to -2
Check Sound If view_yview is smaller than 0

Start Block Start of a block
image Display message: You survived all attacks!
Highscore Action Show the highscore table
Restart Game Restart the game
End Block End of a block

 

image No More Health

image Set the health to 100
Play Sound Play sound snd_explosion2; looping: false
image Change instance into obj_explosion2

 

image No More Lives

Highscore Action Show the highscore table
Restart Game Restart the game

image Draw

image At position (0,view_yview+404) draw image -1 of sprite spr_bottom
image Set the drawing color to 65535 (giallo)
image At position (180,view_yview+440) draw the value of score
image Draw the health bar with size (12,view_yview+449,138,view_yview+459)
with back color none and bar color green to red
image Draw the lives at (16,view_yview+410) with sprite spr_life

Nell’evento Create si imposta score a 0, il numero di vite a 3health a 100.
Inoltre si annullano i messaggi corrispondenti nella barra del titolo della finestra perché se ne occuperà l’evento Draw.
Nell’evento Step controlla se la variabile view_yview diventa 0.
Se l’aereo ha raggiunto la cima del livello allora il gioco è finito!
obj_controller controllerà anche quando siamo rimasti senza salute oppure senza vite e lancerà le azioni necessarie.

Per esempio l’evento No More Healthsarà impostato come

Draw 6

L’evento Draw si occupa di disegnare il pannello, la barra orizzontale della salute, le vite rimaste, il punteggio…

Controlla se hai compilato correttamente le azioni…

Draw 1 Draw 2
Draw 4 Draw 3

L’evento Draw completo dovrebbe apparire come segue

Draw 5

 

Più nemici

In questa sezione aggiungeremo al nostro gioco nuovi tipi di aereo nemico per arrivare a 4 comportamenti diversi

  1. Il primo, che non spara…
  2. Spara proiettili verso il basso.
  3. Spara proiettili in direzione dell’aereo principale.
  4. Spara e parte dal basso del livello (sarà più difficile da evitare o colpire).

Gli aerei nemici saranno distribuiti nel livello in formazioniche appariranno al momento opportuno…

Aggiungi le risorse

TIPO NOME FILE
Sprite spr_enemy2 enemy2_strip3.png Aereo Nemico 2
spr_enemy3 enemy3_strip3.png Aereo Nemico 3
spr_enemy4 enemy4_strip3.png Aereo Nemico 2
spr_enemybullet1 enemybullet1.png Proiettile 1
spr_enemybullet2 enemybullet2.png Proiettile 2
Sound snd_explosion3 explosion3.wav
Object obj_enemy2 spr_enemy2
obj_enemy3 spr_enemy3
obj_enemy4 spr_enemy4
obj_enemybullet1 spr_enemybullet1
obj_enemybullet2 spr_enemybullet2

 

Proiettile 1obj_enemybullet1

Create Event Create

Speed Vertical Set the vertical speed to 6

 

Step Event Step

If Var Action If y is larger than view_yview+480

Start Block Start of a block
Destroy Action Destroy the instance
End Block End of a block

 

Collision Event obj_myplane

Play Sound Play sound snd_explosion3; looping: false
image Destroy the instance
image Set the health relative to -5

Per fare in modo che l’aereo nemico spari abbiamo bisogno 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 e emettiamo un suono, distruggiamo il proiettile e impostiamo health a -5Relative.

Proiettile 2obj_enemybullet2

Create Event Create

Test Instance Count If the number of instance obj_myplane is larger than 0

Start Block Start of a block
Move Towards Start moving in the direction of position (obj_myplane.x,obj_myplane.y) with speed 8
End Block End of a block

image Else

Start Block Start of a block
Speed Vertical Set the vertical speed to 6
End Block End of a block

Collision Event obj_myplane

Play Sound Play sound snd_explosion3; looping: false
image Destroy the instance
image Set the health relative to -5

 

image Outside Room

Destroy Action Destroy the instance

Move 1L’evento creazione utilizza l’azione Move Towards per dirigersi verso la posizione dell’aereo principale.

Utilizza obj_myplane.x e obj_myplane.x ma se non ci fosse nessuna istanza dell’oggetto otterremmo un messaggio di errore quindi è meglio se prima controlliamo se l’aereo c’è.

Se l’aereo principale è presente il proiettile si dirigerà verso di esso altrimenti si dirigerà verso il basso.

L’evento Create dovrebbe apparire così

Proiettile 2
Con l’evento Outside Room distruggiamo il proiettile se esce dal livello.

Aereo Nemico 2obj_enemy2

Step Event Step


Test Chance With a chance of 1 out 30 do perform the next action

Start Block Start of a block
image Create instance of object obj_enemybullet1 at relative position (0,16)
End Block End of a block

 

Collision Event obj_myplane

 

Collision Event obj_bullet


image Set the score relative to 10

Siccome il comportamento sarà simile a quello del primo aereo nemico facciamo una copia di questo oggetto (pulsante destro e poi Duplicate) e gli diamo un nuovo nome e una nuova sprite.
Nell’evento Step facciamo in modo che spari proiettili in media una volta ogni 30 passi.
Nell’evento collisione con il proiettile modifichiamo score a 10 (vale di più perché è più pericoloso).

 

Aereo Nemico 3obj_enemy3

Step Event Step


Test Chance With a chance of 1 out 30 do perform the next action

Start Block Start of a block
image Create instance of object obj_enemybullet2 at relative position (0,16)
End Block End of a block

 

Collision Event obj_myplane

 

Collision Event obj_bullet


image Set the score relative to 20

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.
Nell’evento Step utilizziamo di nuovo l’azione dado ma adesso creiamo un proiettile ogni 80 passi, perché il nuovo tipo di proiettile è più difficile da evitare.

L’evento Step del 3° aereo nemico dovrebbe essere
Aereo Nemico 3

 

Aereo Nemico 4obj_enemy4

  • Visible (no)

Step Event Step

If Var Action If y is smaller than view_yview+480

Start Block Start of a block
image Exit this event
End Block End of a block

image Set variable visible to 1

Speed Vertical Set the vertical speed to -6
If Var Action If y is smaller than -32

Start Block Start of a block
Destroy Action Destroy the instance
End Block End of a block

Collision Event obj_myplane

If Var Action If visible is equal to 0

Start Block Start of a block
image Exit this event
End Block End of a block

Play Sound Play sound snd_explosion2; looping: false
image Create instance of object obj_explosion2 at relative position (0,0)
image Destroy the instance
image Set the health relative to -30

Collision Event obj_bullet

If Var Action If visible is equal to 0

Start Block Start of a block
image Exit this event
End Block End of a block

Play Sound Play sound snd_explosion1; looping: false
image For other destroy the instance
image Create instance of object obj_explosion1 at relative position (0,0)
image Destroy the instance
image Set the score relative to 40

Il 4° aereo nemico è il più complesso perché arriva dal basso e si muove verso l’alto.
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).

 

Finire il gioco

Abbiamo appena realizzato uno scrolling shooter con diversi aerei nemici.
Perché diventi un vero gioco sono necessarie ancora dellerifiniture:

  • una musica di sottofondo
  • spari multipli
  • un’immagine di apertura
  • un’icona migliore
  • una pagina di help.

Musica

Aggiungi la risorsa

TIPO NOME FILE
Sound snd_background background.mid

e fai partire l’esecuzione aggiungendo alla fine dell’evento Create dell’oggetto obj_controller l’azione

Play Sound Play sound snd_background; looping: true

 

Spari multipli

Sostituisci l’evento <Space> di obj_myplane con il seguente

image <Space>

If Var Action If can_shoot is equal to 1

Start Block Start of a block
If Var Action If score is larger than 400

Start Block Start of a block
image Create instance of object obj_bullet at relative position (-24,-8)
image Create instance of object obj_bullet at relative position (+24,-8)
If Var Action If score is larger than 1000

Start Block Start of a block
image Create instance of object obj_bullet at relative position (0,-48)
End Block End of a block

End Block End of a block

Else Else

Start Block Start of a block
image Create instance of object obj_bullet at relative position (0,-48)
End Block End of a block

image Set variable can_shoot to 0
image Set Alarm 0 to 15
End Block End of a block

Se il giocatore ha superato i 400 punti ci saranno 2 spari.
Se il giocatore ha superato i 1000 punti ci saranno 3 spari.

Immagine iniziale

LOADINGScegliamo un’immagine che apparirà durante il caricamento del gioco al posto di quella ufficiale (loading…)
L’immagine la trovi nel tutorial: Resources/loading.gif
Selezionala tramite

  • Global Game Settings > Loading > Show your own image while loading
  • Global Game Settings > Loading > Change Image

ICONIcona

Diamo un’icona specifica alla finestra dell’applicazione.
L’icona la trovi nel tutorial: Resources/Icon.ico
Selezionala tramite Global Game Settings > Loading > Change Icon

Help

Un buon gioco fornisce all’utente delle informazioni su come giocare.
Queste informazioni saranno visualizzate quando l’utente preme il tasto F1.
Per creare le informazioni del gioco fai doppio clic su Game Information nell’albero delle risorse a sinistra sullo schermo.

textVerrà aperto un piccolo editor dove potrai scrivere le informazioni del gioco

Puoi usare i font, i colori, gli stili e il colore di sfondo.

 

A scrolling shooter – 1945

1945Tratto 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 numerotipopericolosità 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 (03600 è 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 Set the value of a variable

Con questa azione puoi cambiare il valore di una certa variabile.
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 If a variable has a value

Con questa azione controlli quale valore ha una certa variabile.
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:
1945
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à

  1. 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.
  2. 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_waterAcqua

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.

  1. 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.
  2. 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.
  3. Vogliamo che lo sfondo si muova, in basso imposta Vert. Speed a 2.

La finestra dovrebbe apparire così

Finestra Livello

Lancia il gioco per verificare che effettivamente abbiamo uno sfondo scorrevole che dà l’illusione del movimento.

 Per aumentare la sensazione di movimento stiamo per aggiungere al mare un po’ di isole.
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)

Isola 1Isola 2 Isola 3

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.

Variabile 1Possiamo 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.

Jump 1Ecco 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à.
&Egrave abbastanza semplice.
Prima di tutto abbiamo bisogno di una sprite per l’aereo.
Utilizzeremo un aereo a eliche.
Strip AereoPer 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: Proiettile.
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 Create Event aggiungiamo l’azione Speed Vertical 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 Step Event controlliamo If Var Action se la variabile x è minore di –16.
Dovresti già sapere come si fa.
Se è così distruggiamo l’oggetto con l’azione appropriata Destroy Action.
Potresti anche usare l’evento Outside room che si trova negli eventi Other Other Event.

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 Create Event 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

Evento Space

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.

 Adesso realizziamo il primo nemico.
Si tratta di un piccolo aereo che semplicemente vola verso il basso.
Non spara ma se colpisce l’aereo principale il gioco finisce.
Di nuovo creiamo una sprite e un oggetto per l’aereo nemico: Aereo Nemico 1

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:

  1. l’evento di collisione con il proiettile, che dovrebbe distruggere l’aereo nemico
  2. 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.

Esplosione 1Per l’esplosione è necessaria una piccola sprite.
Impostiamo l’origine a (1616) 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,0Relative, 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 5Relative (vogliamo aggiungere 5 punti al punteggio, non ripartire da 5 punti).

Quindi l’evento dovrebbe essere simile a

Collisione 1

Adesso prendiamo in considerazione la collisione con l’aereo principale.
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

Collisione 2

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 puntivite 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 Draw Event.
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
Pannello
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 Draw Sprite

Draw 1Compiliamo 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 Draw Score 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)

Draw 2

Per disegnare le vite utilizziamo un meccanismo diverso.
Piuttosto che disegnare un numero disegneremo un certo numero di piccole immagini dell’aereo.
Per questo utilizzeremo una piccola sprite raffigurante l’aereo.

C’è un’azione specifica Draw Lives Image nella scheda Score

Draw 3

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 Score Caption 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 Draw Health.
La salute è visualizzata sotto forma di barretta orizzontale.
Puoi specificare la posizione, la dimensione e lo schema di colore.

Compiliamo così i parametri

Draw 4

L’evento Draw completo dovrebbe apparire come il seguente
Draw 5

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 -30Relative (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.

Esplosione 2
Inoltre reimpostiamo la salute e facciamo emettere il suono corretto.

L’evento sarà impostato come

Draw 6

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 (00Relative, ) e riduce il numero di vite, cioè imposta a –1Relative.

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.

Aereo Nemico 2Per 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.

Proiettile 1Per 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 -5Relative, 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 Test Chance 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.

Aereo Nemico 3Per 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.
Proiettile 2Creiamo 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 Test Instance Count 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ì

Proiettile 2

Move 1L’azione per muoversi verso un certo punto Move Towards assume i seguenti parametri

Ancora una modifica: siccome il proiettile si muove in qualsiasi direzione è un po’ più dificile controllare nell’evento Step se si trova all’esterno del livello.

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.

Aereo Nemico 4Questo 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 LOADING
un’icona migliore ICON

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:

  • 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 linetemporizzatori.
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 AddDelete, …
    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:

Time Line 1
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!
Time Line 2Devi assegnare un temporizzatore a un oggetto Set Time Line 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 roomy=4320, cioè la vista sarà alla base del livello.

Ecco le impostazioni della vista

Livello

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 -2Relative, 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

Aereo Nemico 3
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.

Platform game

PLATFORMTratto 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

  1. creare un movimento naturale per il personaggio
  2. creare abbastanza varianti dei mostri, degli sfondi, …
  3. progettare accuratamente livelli piacevoli da giocare e con difficoltà crescente.

In questo tutorial imparerai a realizzare un semplice gioco di piattaforma con GameMaker.

text

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 Blocco
spr_ball ball.png Palla
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ò camminaresaltarecadere in diversi modi.
Giochi di piattaforma diversi utilizzano modalità diverse.

Normalmente utilizziamo appena tre tasti per controllare il movimento

  1. Freccia sinistra dovrebbe muovere il protagonista a sinistra,
  2. Freccia destra dovrebbe muovere il protagonista a destra,
  3. 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.

Keyboard Event <Left>

If Free If relative position (-4,0) is collision free for Only solid object

Begin Start of block
Jump  To Position Action Jumpo relative to position (-4,0)
End End of block

Trattiamo la freccia destra in modo simile

Keyboard Event <Right>

If Free If relative position (+4,0) is collision free for Only solid object

Begin Start of block
Jump  To Position Action Jumpo relative to position (+4,0)
End 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 Event Step

If Free If relative position (0,1) is collision free for Only solid object

Begin Start of block
Set the gravity Set the gravity to 0.5 in direction 270
End End of block

Else Else

Begin Start of block
Set the gravity Set the gravity to 0 in direction 270
End End of block

If Variable If vspeed is larger then 12

Begin Start of block
Set vertical speed Set the vertical speed to 12
End End of block

La finestra dell’evento dovrebbe apparire così:

Platform 1
Adesso dobbiamo atterrare correttamente sul piano.
Questo è più difficile di quanto sembri.
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.
Per fortuna in GameMaker c’è un’azione per questo:
Contact Action Move to Contact.
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.

Platform 2Utilizziamo 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).

Collision Event Blocco obj_block

Contact Action Move in direction, direction at most 12, till a contact with solid object
Set vertical speed Set the vertical speed to 0

 

La finestra dell’evento collisione con il blocco dovrebbe apparire così:

Platform 3

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à.

Keyboard Event <Up>

If Collision If relative position (0,1) gives a collision with Only solid object

Begin Start of block
Set vertical speed Set the vertical speed to -10
End 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 Blocco
spr_blockh blockh.png Blocco Orizzontale
spr_blockv blockv.png Blocco Verticale
spr_left character_left.png Personaggio Sinistra
spr_right character_right.png Personaggio Destra
Background back_sky sky.png Cielo
back_tiles tiles.png Tessere
Object obj_block spr_block Blocco
obj_blockh spr_blockh Blocco Orizzontale
obj_blockv spr_blockv Blocco Verticale
obj_character spr_right Personaggio Destra
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

Keyboard Event <Left>

Sprite Action Change sprite into spr_left
If Free If relative position (-4,0) is collision free for Only solid object

Begin Start of block
Jump  To Position Action Jumpo relative to position (-4,0)
End End of block

Similmente per la freccia destra

Keyboard Event <Right>

Sprite Action Change sprite into spr_rightIf Free If relative position (+4,0) is collision free for Only solid object

Begin Start of block
Jump  To Position Action Jumpo relative to position (+4,0)
End 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…

spr_right

Nei giochi più avanzati vorrai probabilmente utilizzare sprite animate.
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.

Platform 5Nella 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.

Platform 6
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.

Platform 7

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 Oggetto Mortale
spr_marker marker.png Segnaposto
spr_monsterl monsterl.png Mostro Sinistra
spr_monsterr monsterr.png Mostro Destra
spr_monsterflat monsterflat.png Mostro Schiacciato
spr_flyingl flyingl.png Mostro Volante Sinistra
spr_flyingr flyingr.png Mostro Volante Destra
spr_mushroom mushroom_strip10.png Fungo
spr_level level.png Uscita Livello
Sound snd_killmonster killmonster.wav
snd_killcharacter killcharacter.wav
snd_getmushroom mushroom.wav
snd_finishlevel level.wav
Object obj_death spr_death Oggetto Mortale
obj_marker spr_marker Segnaposto
obj_monster spr_monsterr Mostro Destra
obj_monster_dead spr_monsterflat Mostro Schiacciato
obj_flyer spr_flyingr Mostro Volante Destra
obj_mushroom spr_mushroom
obj_levelexit spr_level Uscita Livello

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.

Platform 8
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_markersegnaposto.
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.

Collision Event Mostro Volante Destra obj_flyer

Play Sound Play sound snd_killcharacter; looping: false
Sleep Action Sleep 1000 milliseconds; redwrawing the screen: true
Room Current  Action 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 mortaleobj_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.

Collision Event Oggetto Mortale obj_death

Play Sound Play sound snd_killcharacter; looping: false
Sleep Action Sleep 1000 milliseconds; redwrawing the screen: true
Room Current  Action 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.

Other Event Outside Room

If Variable Action If y is larger then room_height

Begin Start of block
Play Sound Play sound snd_killcharacter; looping: false
Sleep Action Sleep 1000 milliseconds; redwrawing the screen: true
Room Current  Action Restart the current room
End 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 fungoobj_mushroom.
Per dare un po’ di variazione, il fungo contiene 10 sotto-immagini diverse.

Platform 9L’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.

image Create

Sprite Action Set the sprite to obj_mushroom with subimage random(10) and speed 0

Nell’evento collisione del protagonista con un fungo

  • viene emesso un suono
  • distrutto l’altro oggetto (il fungo)
  • e aggiunti 10 punti al punteggio.

Collision Event Fungo obj_mushroom

Sound Action Play sound snd_getmushroom; looping: false
Set Score Set the score relative to 10
Destroy Action 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 livelloobj_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.

Collision Event Uscita Livello obj_levelexit

Play Sound Play sound snd_finishlevel; looping: false
Sleep Action Sleep 1000 milliseconds; redwrawing the screen: true
If Next Room If next room exists

Begin Start of block
Next Room Go to next room
End End of block

Else Action Else

Begin Start of block
Highscore Action Show the highscore table
Restart Game Restart the game
End 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à.

Sono necessarie le risorse aggiuntive
TIPO NOME FILE
Sprite spr_ladder ladder.png ...
spr_climbing character_climbing.png ...
Object obj_ladder spr_ladder Oggetto Mortale

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:

Platform 10

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:

Platform 11
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 image
spr_ammunition ammunition.png Munizioni
spr_bonus bonus.png Bonus
spr_life life.png Vita
Object obj_bullet spr_bullet image
obj_ammunition spr_ammunition Munizioni
obj_bonus spr_bonus 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 image del protagonista la impostiamo a 0 utilizzando l’azione Set variable to Set Variable.
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 proiettileobj_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à:

Platform 12

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 specialeobj_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

Platform 13

Osserva che disegniamo anche un’immagine per indicare se il giocatore può sparare.

Il risultato nel gioco è quello nell’immagine

Platform 14

 

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

  1. mostri diversi, palle che rimbalzano, mostri che sparano
  2. chiavi da trovare, necessarie per aprire delle porte
  3. bombe che puoi spostare e che esplodono quando un mostro, o il personaggio, ci passa sopra
  4. 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, …)
  5. muri e pavimenti che si possono distruggere, per esempio colpendoli o saltandoci sopra con forza
  6. trampolini che permettono di saltare più alto
  7. piattaforme che appaiono e scompaiono
  8. strade a senso unico
  9. piattaforme mobili (non è facile!)

Buon divertimento.

3-Dimensional Games

3-DIMENSIONAL GAMETratto da: Game Maker Tutorial – Adding Depth to Games – Written by Mark Overmars – Copyright © 2007 YoYo Games Ltd – www.yoyogames.com/…/threed.zip

I giochi veri sono 3D, non è vero? In realtà non è vero.
Tutti i giochi producono, sullo schermo del computer, immagini 2D… possono sembrare 3D ma non significa che lo siano.
Ma allora cosa si intende quando si dice che un gioco è 3D? Si tratta di una domanda difficile.
La risposta è: la combinazione di diversi fattori

  • come il gioco è stato creato
  • l’immagine che il giocatore vede
  • il modo con cui il giocatore controlla il gioco.

In questo tutorial ti sarà spiegato come dare ai tuoi giochi un aspetto 3D e come aggiungere profondità ai tuoi giochi.
Ma non vogliamo utilizzare funzioni grafiche 3D per questo.
Descriveremo delle tecniche più semplici come parallasse, scalatura, trasparenza, viste isometriche.
Quasi tutto può essere ottenuto tramite drag-and-drop di azioni di GameMaker sebbene in qualche punto sarà necessario unpezzetto di codice GML.
Per seguire il tutorial dovresti avere qualche esperienza con GameMaker ma non è necessario che tu conosca GML a fondo.

Introduzione

I moderni giochi 3D modellano il mondo del gioco con oggetti 3D.
Per disegnare le scene utilizzano schede grafiche 3D.
Dato un punto di vista, cioè la posizione dalla quale il giocatore osserva il mondo del gioco, la scheda crea l’immagine corretta tenendo conto di aspetti come illuminazione, rimozione di superfici nascoste (oggetti che non si vedono non dovrebbero essere disegnati), effetti atmosferici…

Con l’hardware attuale questo produce esperienze di gioco spettacolari ma c’è un prezzo per tutto questo.
Modellare un mondo 3D con oggetti 3D e realizzare le animazioni per i personaggi richiede molte competenze e tanto tempo tempo.
Inoltre la logica del gioco, i comportamenti delle entità, il controllo delle collisioni, le animazioni, … sono molto più difficili che nei giochi 2D.
Il risultato è che la produzione di giochi 3D moderni richiede risorse enormi, personale numeroso e specializzato e arriva a costare milioni di dollari.
E comunque la maggior parte di questi giochi presentano errori, in particolare nei movimenti della camera e dei personaggi e nel controllo delle collisioni.

Questo significa che i giochi 3D sono fuori dalla tua portata? Bene, sì e no.
GameMaker non supporta direttamente mondi 3D, anche se ci sono funzioni per la grafica 3D (e su questo c’è un tutorial specifico).

The isometric world of Age of EmpiresMa tutti i giochi apparentemente 3D fino al 1995 e molti altri anche dopo non utilizzano mondi 3D.

Per esempio giochi come Age of Empires e Command and Conquer (eccetto le versioni più recenti) non utilizzano mondi 3D.
Sono giochi così detti isometrici.
Essi utilizzano sprite per rappresentare le scene e i personaggi e utilizzano alcuni trucchi relativamente semplici per dare la senzazione all’utente di essere in un mondo 3D.

Questo tutorial spiegherà le basi di giochi come questi.

Spero che questo tutorial ti convinca che con GameMaker è possibile realizzare molti tipi diversi di giochi che hanno un evidente look and feel 3D.
Come sempre l’unico limite è l’immaginazione.
Se vuoi realizzare giochi veramente 3D dovresti scaricare il tutorial ufficiale First Person Shooter.

 

Ingannare la mente

Come far sembrare 3D qualcosa?
Il concetto di base è ingannare la nostra mente e farle credere che le immagini che vede sono 3D.
Allora, il problema diventa perché pensiamo che un immagine che vediamo è 3D.
Giocano un ruolo in questo un certo numero di fattori.

Gli oggetti che si trovano dietro altri oggetti sono invisibili (anche parzialmente)

Questo è un aspetto importante.
Normalmente noi non vediamo attraverso gli oggetti solidi.

Hidden surface removal helps in establishing the depth relation of objectsQuando per esempio un oggetto è parzialmente nascosto da una roccia, l’osservatore capisce subito che l’oggetto si trova dietro la roccia.
In questo modo l’osservatore ottiene una visuale migliore delle relazioni 3D esistenti tra gli oggetti.
Per realizzare un mondo 3D dobbiamo quindi visualizzare gli (le parti degli) oggetti che sono attualmente visibili.
Questo processo si chiama rimozione delle superfici nascoste.

Le schede grafiche 3D rimuovono automaticamente le superfici nascoste ma, siccome GameMaker opera con mondi 2D, dobbiamo occuparcene noi.
Il modo per ottenerlo è disegnare le sprite degli oggetti nell’ordine corretto.
Un oggetto che si trova più lontano viene disegnato per primo.
Il prossimo oggetto viene disegnato sopra di esso, e così via.
Siccome gli oggetti più vicini sono disegnati sopra gli oggetti che stanno dietro, essi copriranno (anche parzialmente) gli altri oggetti.
Possiamo indicare questo ordine in GameMaker impostando la variabile depth per i diversi oggetti.
Le istanze di oggetti con profondità maggiore saranno disegnate prima degli oggetti con profondità minore e quindi appariranno dietro.

Gli oggetti trasparenti lasciano vedere cosa c’è dietro

Quando gli oggetti sono parzialmente trasparenti, attraverso di essi vedi cosa c’è dietro.
Utilizzare la trasparenza in combinazione con il corretto ordine di profondità aumenta ulteriormente la sensazione di profondità.

Gli oggetti che si trovano più lontano sembrano più piccoli

Chiaramente, più gli oggetti sono lontani più appaiono piccoli.

Distant instances appear smallerQuesto dà una forte sensazione di distanza e quindi una migliore sensazione 3D.
Questo si può ottenere cambiando la dimensione delle sprite a seconda della loro profondità.
Puoi realizzare sprite di dimensioni diverse oppure disegnare le sprite con un fattore di scala.
Quando un oggetto si muove verso l’osservatore deve diventare più grande.
In un mondo 3D, questo dà una forte sensazione di movimento.
La scalatura deve essere fatta con attenzione altrimenti potrebbe dare l’effetto opposto.

Gli oggetti che si trovano più lontano sembrano sfocati

Quando gli oggetti sono più lontani non riesci a vederli più così bene.
Questo vale anche al contrario: se un’immagine appare sfocata, la interpretiamo come se fosse più lontana.
Quindi, aggiungere alle immagini che si trovano più lontano un misto tra velatura e sfocatura aggiunge un maggiore senso della distanza.
Anche questo si può ottenere utilizzando sprite diverse per la stessa istanza, in funzione della sua profondità.

Gli oggetti che si trovano più lontano sembra che si muovano più piano

Un oggetto lontano impiega più tempo per attraversare la nostra vista da sinistra verso destra rispetto a un oggetto vicino che sembra passarci davanti più veloce.
Puoi utilizzare questo fenomeno per dare un’indicazione sulla profondità degli oggetti.
Un aspetto particolare di questo fenomeno sarà trattato più avanti come scorrimento con parallasse.
Inoltre, gli oggetti che si avvicinano o si allontanano da te cambiano posizione sullo schermo più lentamente.
Normalmente la velocità verticale, rispetto allo schermo, dovrebbe essere più piccola della velocità orizzontale.

Gli oggetti presentano un’ombra

Gli oggetti proiettano le ombre.
Le ombre proiettate da oggetti su altri oggetti sono difficili da calcolare ma è relativamente semplice realizzare ombre sul pavimento.
Anche se non si ottiene un’ombra precisa è comunque positivo avere una piccola macchia scura sotto un oggetto.
Questo dà l’impressione che l’oggetto stia sul pavimento.

Even a simple shadow gives position informationDevi fare le cose con cura, per esempio tutti gli oggetti, o nessuno, hanno l’ombra e tutte le ombre hanno la stessa dimensione e la stessa direzione.
Nella figura si intuisce che il personaggio al centro si trova sul terreno mentre quello a destra ci sta saltando sopra.

Le linee parallele sembra che si incontrino in un punto

Come probabilmente sai, in un mondo 3D le linee parallele, alla distanza, si incontrano in un punto.
Per esempio, i due lati di una strada alla distanza si toccano.
Per essere più precisi, la nostra vista genera una proiezione prospettica.
In qualche modo deforma gli oggetti a seconda della loro profondità ma è proprio questa deformazione che crea la sensazione 3D.

Using a perspective projection Using a perspective projection

L’immagine a sinistra mostra una proiezione senza prospettiva.
Le linee verticali sono parallele.
Nell’immagine a destre utilizziamo una trasformazione prospettica e come risultato le linee si toccheranno da qualche parte alla distanza.
Questo da una sensazione migliore di 3D.

Using an isometric projectionLe proiezioni prospettiche sono importanti nei giochi 3D ma sfortunatamente non sono facili da ottenere con le sprite.
Per questo i giochi basati sull’uso delle sprite normalmente non utilizzano trasformazioni prospettiche.
Per limitarne gli effetti spesso usano una proiezione con un angolo di 45 gradi.
Cioè, in questi giochi non si guarda dritto ma un po’ di lato.
Come risultato l’effetto delle linee parallele è meno evidente e anche l’osservatore ne è meno influenzato.
Questo fenomeno è alla base dei giochi isometrici.
Se guardi attentamente la figura vedi che le linee sono ancora parallele (che è sbagliato…) ma comunque appare di nuovo più 3D della prima.
La creazione di giochi isometrici è possibile in GameMaker e più avanti mostreremo come ottenerla.

 

Scorrimento con parallasse

Tratto da: www.yoyogames.com/…/threed.zip > parallax.gmk.

Come detto prima, gli oggetti lontani si muovono più lentamente degli oggetti che sono vicini all’osservatore.
In questo tutorial utilizzeremo questa osservazione.
Comunque, la utilizzeremo soltanto per creare sfondi scorrevoli lateralmente.

Come dovresti sapere puoi aggiungere sfondi ai tuoi livelli in GameMaker.
Molto spesso un livello contiene proprio uno sfondo ma è possibile avere sfondi multipli.
Naturalmente, perché siano visibili è necessario che siano parzialmente trasparenti oppure che coprano solo una parte del livello.
Dando agli sfondi più bassi velocità orizzontali più basse dai al giocatore l’impressione che questi sfondi si trovino più lontano.
Non puntiamo alla qualità grafica ma soltanto a dimostrare l’effetto.

Prima di tutto utilizziamo due sfondi.

Il primo visualizza alcune montagne alla distanza.
The distant mountains.
Questo sfondo sarà sistemato in cima al livello e scorre verso sinistra con una velocità molto bassa di -1.
Imposta questa velocità nella finestra delle proprietà del livello.
Tassella orizzontalmente ma non verticalmente.

RoadIl secondo sfondo rappresenta la strada.
È molto piccolo, è posizionato alla base del livello e si muove più velocemente (-4).
Di nuovo tasselliamo orizzontalmente.

CarPosizioniamo un’auto sulla strada ma non ha bisogno di muoversi.
Siccome la strada si muove sotto di essa abbiamo già l’illusione del movimento.
Siccome la strada si muove più velocemente delle montagne hai l’impressione che le montagne siano molto lontane.

Per aggiungere ancora più profondità alla scena aggiungiamo degli alberi.
Utilizziamo 3 sprite di 3 dimensioni diverse

The same tree at three different distances. The same tree at three different distances. The same tree at three different distances.

Per ognuno di questi alberi creiamo un oggetto.
Per assicurarci che l’albero piccolo stia dietro l’albero medio che a sua volta stia dietro l’albero grande dobbiamo assegnare loro profondità diverse.

  • L’albero grande lo sistemeremo vicino alla strada e nell’evento Create Create event gli daremo l’azione Move Action 1 di muoversi verso sinistra con speed=4, come la strada.
  • L’albero medio sarà sistemato un po’ più indietro con speed=3.
  • All’albero piccolo gli daremo speed=2.

Ne sistemeremo alcuni alle posizioni appropriate nel livello.
Per assicurarci che essi riappaiano a destra quando scompaiono a sinistra aggiungiamo un evento Outside Room nel quale includiamo un’azione Wrap Screen Action Wrap con selezionato Wrap horizontally.

Ecco il risultato

The parallax demo

Si tratta solamente di una dimostrazione e non di un gioco.
Per trasformarlo in gioco dovresti dare al giocatore la possibilità di sterzare e per esempio aggiungere del traffico da evitare.

Lo scorrimento con parallasse è molto utile per esempio nei giochi di piattaforma.
In questo caso dovresti adattare le velocità degli sfondi scorrevoli alla velocità (orizzontale) del protagonista controllato dal giocatore.

 

Proiezioni parallele

Tratto da: www.yoyogames.com/…/threed.zip > parallel.gmk.

Sebbene i veri giochi 3D dovrebbero usare le proiezioni prospettiche descriviamo prima come le proiezioni parallele possano essere comunque utilizzate per ricreare una sensazione di profondità.
In una proiezione parallela la dimensione degli oggetti rimane la stessa indipendentemente dalla distanza.
Anche le linee parallele rimangono parallele.
Questo rende tutto più facile perché le sprite hanno una dimensione fissa (anche se possono essere scalate).
Chiaramente, una proiezione parallela produce una distorsione della vista.
Per limitare questa distorsione ci assicureremo che il giocatore non veda gli oggetti che sono molto lontani.
In questo modo non noterà gli errori.
Otteniamo questo guardando il mondo sotto un angolo (normalmente si usa un angolo di circa 45°).
In questo modo un mondo di quadrati ci apparirà come un mondo di rettangoli

Per un’immagine di sfondo l’effetto è questo

A parallel project of a simple world. A parallel project of a simple world.

Creare un’immagine di questo tipo è semplice.
Semplicemente scaliamo l’immagine soltanto nella direzione verticale.

Dimostreremo questo approccio con un piccolo demo nel quale il giocatore controlla un personaggio che può muoversi in un mondo contenente degli alberi.
Ci sono tre cose da gestire in un’applicazione di questo tipo:

  1. La rimozione delle superfici nascoste deve essere fatta correttamente.
    Quindi quando il personaggio si trova dietro un albero dovrebbe essere disegnato prima dell’albero in modo da renderlo parzialmente invisibile.
  2. La velocità del personaggio deve essere trattata correttamente.
    Il movimento avanti-indietro deve essere più lento del movimento destra-sinistra.
  3. E la cosa più difficile, trattare correttamente le collisioni.

 

Rimozione delle superfici nascoste

Come dovresti sapere ogni sprite ha un’origine.
Di default è l’angolo in alto a sinistra della sprite.
Quando sistemiamo un’istanza di un oggetto in una posizione particolare stiamo in realtà posando la sprite corrispondente con la sua origine in quella posizione.
Quando si lavora con un mondo tridimensionale è più facile prendere come origine dell’oggetto la posizione dove si appoggia sul terreno.
Per tutte le sprite imposteremo l’origine a questa posizione.
Quindi per esempio per il personaggio che cammina nella foresta impostiamo l’origine della sprite alla posizione (16,30).

Inoltre abbiamo disabilitato Precise collision checking e modifichiamo la maschera tramiteBounding box – Manual a una piccola area alla base del personaggio.
The Mask properties form for the player’s sprite.
Così le collisioni non avverranno con l’intera sprite ma soltanto con il piccolo rettangolo.
Useremo questo più avanti.

Il nostro personaggio sarà rappresentato tramite 4 sprite diverse; una per ognuna delle 4 direzioni in cui può camminare.
Chiaramente imposteremo gli stessi valori per ciascuna.

Adesso quale dovrebbe essere la profondità?
In molti casi l’ordine con cui gli oggetti devono essere disegnati è lo stesso con cui si trovano sul terreno.
Quindi impostando l’origine come specificato prima la coordinata y dell’istanza determina l’ordine.
Le istanze con una coordinata y bassa sono vicine alla cima della finestra e devono essere disegnate prima di quelle con una coordinata y maggiore.
Quindi una coordinata y più frande deve corrispondere a una profondità più piccola.

Setting the depth of the instance.Si può ottenere questo impostando depth a –y utilizzando l’azione Set Variable.

Per gli oggetti statici, come gli alberi del nostro esempio, è necessario farlo una sola volta nell’evento Create.
Per gli oggetti dinamici, come il personaggio del nostro esempio, dobbiamo farlo a ogni passo.
Sarebbe meglio utilizzare l’evento End Step per essere sicuri che tutti gli altri eventi siano stati elaborati prima di aggiornare depth.

Movimento del personaggio

Possiamo muovere il personaggio utilizzando comunemente le frecce direzionali.
In ciascun evento del tasto freccia impostiamo il movimento nella direzione corretta e impostiamo la sprite corretta per l’istanza.
Inoltre, per avere un’animazione della sprite durante il movimento e nessuna animazione quando il personaggio non è in movimento utilizziamo la variabile image_speed.
Questa variabile specifica con quale velocità devono essere visualizzate le sottoimmagini dell’animazione.
Impostandola a 1 si ha l’animazione a velocità normale.
Impostandola a 0 si fermerà l’animazione.

Changing the sprite.Allora ogni volta che l’utente preme un tasto freccia scegliamo la sprite corretta e impostiamo image_speed a 1 utilizzando l’azione Change Sprite

Utilizziamo -1 per subimage per evitare un cambiamento di sottoimmagine quando ci stiamo già muovendo nella stessa direzione.

Quando il giocatore rilascia il tasto impostiamo image_speed a 0 utilizzando l’azioneSet Variable.
Facciamo lo stesso se avviene una collisione.

Tutto questo non ha niente a che fare con i giochi 3D.
In questo modo si gestisce normalmente il movimento del personaggio in molti giochi.
L’unica cosa che dobbiamo trattare accuratamente in un gioco tridimensionale è la variazione della velocità.
Utilizziamo una velocità 3 per il movimento orizzontale e una velocità 2, più bassa, per il movimento verticale.
Devi fare delle prove con questi numeri per ottenere l’effetto migliore per il tuo gioco.

Collisioni

Le collisioni avvengono normalmente quando le sprite si sovrappongono parzialmente.
Questo funziona nei giochi 2D ma non funziona nei giochi 3D.
Quando il personaggio si trova davanti a un albero le sprite si sovrappongono ma non c’è collisione.
Quindi abbiamo bisogno di un’altra area che definisca la collisione.
Quest’area corrisponde normalmente all’area dell’istanza sul terreno.
Soltanto quando i piedi del personaggio si sovrappongono alla base del tronco dell’albero c’è una vera collisione.
Il modo più semplice per ottenere questo è di definire un bounding box molto piccolo in basso per tutte le sprite e non utilizzare precise collision checking.
Una collisione viene segnalata soltanto quando si sovrappongono parzialmente i due bounding box, che è proprio quello che vogliamo.

Per le figure più complesse un piccolo rettangolo in basso potrebbe non rappresentare correttamente l’area di collisione.
In questi casi utilizziamo un’altra funzionalità di GameMaker.
Un oggetto può avere una maschera diversa rispetto alla sprite utilizzata per rappresentare l’istanza.
Allora possiamo realizzare una seconda sprite che ha la forma dell’area di collisione richiesta e utilizzarla come maschera di collisione.
Utilizzeremo questo approccio più avanti per realizzare un gioco isometrico.

Adesso abbiamo tutti gli ingredienti per il gioco 3D che vogliamo realizzare.
Per fare in modo che tutto sembri più bello utilizziamo un insieme di tessere per tassellare lo sfondo.
Le scaliamo come spiegato prima per ottenere la dimensione 48x24.
Riempiamo lo sfondo.
Aggiungiamo allo sfondo anche delle tessere di muri.
Per provocare le collisioni utilizziamo una tecnica standard nella quale definiamo un oggetto muro solido invisibile e sistemiamo istanze di questo oggetto sopra i muri dello sfondo.
In questo modo il personaggio si fermerà perché si scontra con queste istanze invisibili mentre il giocatore vedrà soltanto il piacevole sfondo davanti a esse.

Il livello

Utilizzeremo una vista nel livello in modo che il giocatore veda solo una parte del mondo.
Per aumentare la sensazione di profondità impostiamo la vista a 400x200, così facendo scaliamo di nuovo con un fattore 1/2 nella direzione verticale.
In molti giochi questa proporzione viene ottenuta aggiungendo un pannello delle informazioni sotto il mondo scorrevole.
Questo è il motivo per cui in questo tipo di giochi è meglio posizionare il pannello delle informazioni alla base dello schermo piuttosto che di lato.

Il demo finale appare così:

The parallel demo.

 

Sprite scalate

Tratto da: www.yoyogames.com/…/threed.zip > scaling.gmk.

Nel tutorial precedente abbiamo utilizzato la proiezione parallela.
Se fissi la vista in alto rispetto al terreno in una direzione fissa e se mostri una piccola parte della scena funziona abbastanza bene.
Ma se vogliamo avere una vista in prima persona oppure una vista più vicina al terreno allora è necessaria una proiezione prospettica.
La dimensione degli oggetti deve diminuire quando sono più lontani.
Ma come possiamo ottenerlo?
Nel tutorial sullo scorrimento con parallasse abbiamo utilizzato alberi di 3 dimensioni diverse.
Questo funziona quando gli alberi rimangono a distanze prefissate ma in un vero gioco 3D il giocatore deve potersi avvicinar e a essi, e quindi la dimensione dovrebbe cambiare continuamente.
Dovremmo creare un numero enorme di sprite diverse, una per ogni dimensione, ma questo comporterebbe un uso eccessivo di memoria.
Potresti comunque pensare di farlo per gli oggetti veramente importanti del gioco perché si ottiene la migliore qualità grafica.
Per le altre istanze possiamo utilizzare il ridimensionamento delle sprite.
In questo tutorial mostreremo come farlo utilizzando un semplice esempio nel quale il giocatore deve evitare degli alberimentre si muove in una foresta.

La pima sprite che ci serve è quella per l’albero.
Ne utilizziamo una.

The tree sprite

Impostiamo manualmente una piccolaBounding box per la sprite alla base dell’albero.
Questa è la sola parte dove vogliamo che avvengano le collisioni con il personaggio.

Utilizziamo ancora le montagne come sfondo, ma questa volta senza scorrimento, horizontal speed=0.
Piuttosto utilizziamo un ampio livello con width=2000.

The view keeps the player in the center
Sistemiamo il personaggio, per il quale ci serve una sprite, nel mezzo del livello in basso.
Utilizzeremo una vista di dimensioni 480x320 e posizioneremo il personaggio inizialmente al centro impostando correttamente i parametri e impostando che la vista deve seguirlo, con Object following …

Il personaggio si muoverà a sinistra e a destra quando il giocatore premerà le frecce direzionali sinistra e destra.
Chiaramente dobbiamo evitare di muoverci troppo a sinistra o a destra.
Come punteggio utilizziamo il tempo che il giocatore resiste…
Quindi nell’evento Step del personaggio aggiungiamo 1 a score.
Quando il personaggio provoca una collisione con un albero visualizziamo la classifica e facciamo ripartire il gioco.

Ci rimane ancora l’albero.
Ci sono 3 aspetti che dobbiamo trattare: la dimensione, la posizione sullo schermo, la profondità.

  1. Gli alberi appaiono alla coordinata y=180.
    Nell’evento End step scaliamo la sprite utilizzando la sua y per aggiornare le variabili image_xscale eimage_yscale.
    Utilizziamo un fattore prossimo a 0 quando y è 180 e aumenta quando l’albero si muove verso il basso.
    Per essere precisi utilizziamo un valore di scala (y-178)/100.
    Se vuoi, puoi fare degli esperimenti, ma assicurati che sia sempre positivo.
    Potresti anche usare l’azione Transform Sprite Transform Sprite Action della Standard Edition.
  2. Gestiamo la profondità tramite depth=-y nell’evento Step.
    Questo significa che gli alberi più vicini alla parte bassa dello schermo e che sono più vicini all’osservatore hanno ygrande e saranno disegnati sopra gli altri, come vogliamo.
    Anche il personaggio deve avere una profondità adeguata per stare nella posizione corretta tra gli alberi(-300).
  3. Controllare il movimento è più difficile del previsto.
    Potremmo muoverli con velocità costante ma si noterà come un rallentamento quando si avvicinano, perché dovrebbero in realtà accelerare.
    Quindi dobbiamo aumentare la velocità verticale.
    Inoltre si devono spostare di lato quando si avvicinano, perché le linee parallele dovrebbero convergere all’infinito.
    Quindi la velocità orizzontale deve essere adattata alla posizione dell’albero rispetto al centro della vista.
    Per questo utilizziamo del codice Execute Code Action nell’evento Step.

Adapting the movement of the tree
Osserva l’uso delle variabili locali xoff and yoff.
I numeri sono sperimentali, prova a cambiarli.

Per finire il gioco mancano ancora poche cose: distruggere gli alberi quando scompaiono sotto, aggiungere un oggetto controllore per l’apparizione degli alberi (di più quando il punteggio cresce).

Utilizza questo gioco come base di partenza per i tuoi giochi.

The scaling game.

Adesso puoi utilizzare lo stesso meccanismo per realizzare un gioco completo di tipo first person shooter.
In questi giochi l’oggetto principale ha una posizione e un orientamento nel mondo del gioco.
Per tutte le altre istanze nella scena devi calcolare la posizione relativa e la direzione rispetto allo sguardo del giocatore e la loro distanza.
La distanza determina l’ordine nel disegno e la dimensione, come sopra.
Per evitare di disegnare troppe istanze normalmente si disegnano solo quelle abbastanza vicine.
Tuttavia per questo tipo di giochi è conveniente l’uso di funzioni 3D come quelle contenute nella Standard Edition di GameMaker .
Questo argomento è trattato in un altro tutorial.

 

Giochi isometrici

Tratto da: www.yoyogames.com/…/threed.zip > isometric.gmk

SimCity is an isometric game.Per ultimo ci occupiamo di un tipo di gioco molto popolare: il gioco isometrico.
Molti dei giochi più popolari del recente passato sono isometrici.

Esempi sono Age of EmpiresDiablo,Command and ConquerSimCity, e molti altri giochi di strategia e di simulazione.

Questi giochi sono in linea di principio realizzabili con GameMaker (ma considera che la realizzazione di questi giochi commerciali richiede anni di lavoro di personale specializzato).

Il principio di un gioco isometrico è che il mondo 3D viene osservato con un angolo fisso di 45°.
Di nuovo si utilizza la proiezione parallela, cioè non c’è alcuna prospettiva e quindi gli oggetti più lontani non diventano più piccoli.
Immagina il mondo come costituito da celle quadrate.
In una vista isometrica tutti i quadrati diventano dei rombi.
Per rendere semplice l’allineamento delle celle tipicamente utilizziamo rombi 2x1, cioè di 32x16 pixel.
Facendo la stessa cosa con un’immagine di sfondo otteniamo

An isometric view on the world. An isometric view on the world.

Questi sfondi si possono realizzare in GameMaker in un modo abbastanza semplice.

  • crea un nuovo sfondo tassellato
  • componilo passo-passo
  • allarga l’immagine
  • ruotala di 45°
  • ingrandiscila (rimpiccioliscila) verticalmente del 50%.

In alternativa puoi utilizzare un insieme di tessere già pronto della giusta dimensione e orientazione.
Nella finestra del livello indica di utilizzare una griglia isometrica.
Adesso è relativamente semplice posizionare correttamente le tessere nel livello.

Il vantaggio della proiezione isometrica rispetto alla proiezione normale come abbiamo fatto prima è che la nostra mente interpreta immediatamente i rombi come quadrati visti sotto un certo angolo.
Questo produce un’impressione tridimensionale.
Chiaramente otterremo ancora distorsioni di prospettiva la dimensione degli oggetti non cambia con la distanza.
Questa distorsione di prospettiva può essere ancora limitata visualizzando soltanto una piccola parte del mondo.
Ecco perché la maggior parte dei giochi isometrici utilizzano una vista sul mondo limitante.

Una volta che hai uno sfondo piacevole passiamo alla posa degli oggetti in esso.
Gli oggetti dovrebbero avere ovviamente un aspetto 3D dell’angolo corretto di 45°.
La realizzazione di questi oggetti isometrici non è facile e normalmente è l’operazione che richiede più tempo nei giochi isometrici.

Ogni oggetto ha un’ombra sul terreno.
L’ombra è fondamentale.
Verrà utilizzata per il controllo delle collisioni, o detto in modo diverso, sarà utilizzata come maschera di collisione.
Allora avrai bisogno di due sprite per ogni oggetto: l’immagine dell’oggetto e la maschera ombra.
La cosa migliore è che l’origine della sprite e della maschera sia il centro dell’ombra.

An isometric sprite and its collision mask.Per esempio, a destra, vedi un’immagine di un muro che stiamo per utilizzare nel nostro gioco isometrico e la sua maschera ombra corrispondente (la x rappresenta l’origine).

In questo caso la maschera ha precisamente la dimensione di una tessera dell’immagine.
Svolgendo il controllo di collisione sulle ombre allora le immagini si possono sovrapporre, finché le loro ombre non si sovrappongono.
Questo è precisamente quello che noi vogliamo.
Per esempio, quando una palla gira tra i blocchi le sprite si possono sovrapporre.
Ma si ha una collisione con un muro quando l’ombra della palla tocca l’ombra del muro.

Come nel caso parallelo impostiamo depth in ogni istanza a –y.
In questo modo le istanze vengono disegnate nell’ordine corretto.

Tuttavia c’è ancora un problema.
Quando si creano i livelli le sprite non sono disegnate in questo ordine.
Questo potrebbe rendere difficile la realizzazione di scene corrette.
Un avvertimento è di iniziare sempre dall’alto e operare verso il basso.
Inoltre, c’è un pulsante nella barra degli strumenti che ordina le istanze secondo la coordinata y, che è proprio quello che vogliamo.

Un’ultima parola sul movimento.
Siccome c’è la proiezione il movimento orizzontale dovrebbe essere veloce il doppio del movimento verticale.
Inoltre, quando utilizzi le frecce direzionali (per esempio) per guidare il movimento, è comune farle corrispondere a movimenti in diagonale (lungo i lati delle tessere) piuttosto che a movimenti orizzontali e verticali.

Un labirinto come esempio

Using a second, translucent copy of the ball.Stiamo per realizzare un esempio di gioco isometrico: un semplice labirinto.
Non è molto sofisticato ma ti illustrerà le idee di base.

Come primo passo è meglio che tu realizzi il labirinto su carta.
Sarà molto difficile farlo mentre crei il livello.
Poi creiamo un terreno di sfondo per il labirinto che riempia l’intera area coperta dal labirinto.

Come secondo passo creiamo le sprite.
Come detto primo sono necessarie due sprite per ogni oggetto: l’immagine effettiva e la maschera utilizzata per il controllo di collisione.
Per molti oggetti utilizziamo la stessa maschera.
Assicurati che ogni sprite si inserisca bene sulla superficie e che l’origine sia al centro della maschera ombra.

Per rendere le cose più interessanti aggiungiamo un passaggio.
Il passaggio consiste di tre parti.
I pilastri destro e sinistro sono semplicemente dei muri più alti e di colore diverso.
Utilizzano la stessa maschera come i muri normali e sono esattamente identici (allora definiamo come loro Parent l’oggetto muro per farli comportare allo stesso modo).
Il pezzo in mezzo del passaggio è diverso.
Consiste di un blocco in alto nell’aria.
Non ha bisogno di una maschera perché la palla può passarci sotto.
Ma dobbiamo essere sicuri che la sua origine sia ancora al centro della sua ombra (altrimenti non sarebbe disegnato alla profondità giusta).

Per ciascun elemento impostiamo la sua profondità nell’evento Create.
Per la palla la impostiamo nell’evento End Step.
Per il resto il gioco è praticamente lo stesso di un semplice gioco di labirinto.
Quando premi un tasto freccia muoviamo la palla di un po’ nella direzione diagonale corretta, nell’ipotesi che la nuova posizione sia senza collisione.
Come detto prima la distanza orizzontale è il doppio della distanza verticale.
Quando la palla (la sua ombra…) colpisce la bandierina (la sua ombra…) il labirinto è stato risolto.

Realizzare il livello richiede maggiore impegno.
Bisogna posizionare correttamente tutti gli elementi muro.
Inoltre, come detto prima, è meglio se inizi dall’alto verso il basso.
Utilizza il pulsante nella barra degli strumenti Sort all instances by y-coordinate se hai commesso un errore.
Utilizza una griglia 16x8 per allineare correttamente le istanze.
Per rendere più facile il posizionamento delle istanze seleziona Turn the grid into an isometric grid.
Deseleziona la casella Delete underlying per rendere per lo stesso motivo.

C’è ancora un trucco aggiunto nel demo.
Quando mantieni premuto il tasto <Space> puoi vedere la palla attraverso i muri.
Questo è utile quando l’oggetto in movimento può scomparire completamente dietro gli altri oggetti.
Ecco come funziona.
C’è un nuovo oggetto chiamato transparent_ball.
Ha una profondità –100000, cioè davanti a qualsiasi altra cosa.
Quando l’utente preme <Space> viene creata un’istanza di questo oggetto e quando lo rilascia l’oggetto viene distrutto.
Per assicurarti che l’oggetto occupi la stessa posizione della palla dagli la stessa sprite ma impostagli alpha a 0.2.
Come risultato vediamo un’immagine trasparente della palla davanti al muro.
Questo rende produce l’impressione opposta che il muro sia parzialmente trasparente.

Dovresti giocare ancora per un po’ con il demo.
Aggiungi qualche altro muro e dei passaggi, aggiungi dei livelli, ecc.

Giochi isometrici più avanzati

I giochi isometrici si adattano particolarmente a molti tipi di giochi.
La maggiore complicazione comunque è che sono necessarie sprite e tessere fatte molo bene.

Utilizza Google con le parole isometric tiles e troverai molte pagine interessanti.

 

Ci sono del resto un sacco di risorse di questo tipo nel web, compresi dei programmi di aiuto.
Per il resto, come è stato spiegato bene prima, è più facile di quello che sembra.

Ci sono solo due cose che ti devi ricordare bene: le maschere di collisione e l’impostazione corretta della profondità.
Ecco altre due cose da tenere a mente:

  • Quando non puoi andare dietro certi oggetti (come le montagne o foreste) è meglio se li disegni sullo sfondo.
    Successivamente puoi utilizzare degli oggetti invisibili per evitare che gli oggetti in movimento possano coprirli.
  • Quando un oggetto si distribuisce su più tessere (come un passaggio) spezzalo in diverse tessere per evitare problemi con la profondità.
  • Ricordati sempre di impostare l’origine al centro della proiezione verticale dell’oggetto.
    Quindi, per esempio, un uccello in volo avrà il suo centro a una notevole distanza sotto di esso.
    Osserva che non è necessario allungare la sprite.
    Il centro può cadere fuori dalla sprite.

Maze games

MAZE GAMESTratto da: Game Maker Tutorial – Creating Maze Games – Written by Mark Overmars – Copyright © 2007-2009 YoYo Games Ltd
www.yoyogames.com/…/maze.zip

I giochi di labirinto sono una categoria di videogioco molto popolare e sono semplici da realizzare con GameMaker.

Questo tutorial ti spiega in pochi semplici passi come realizzare un gioco di questo tipo.
La parte divertente è che dal primo passo in poi abbiamo un gioco vero che, passo dopo passo, diventa sempre più esteso e attraente.

 

Quale gioco?

Prima di iniziare con la realizzazione del gioco dobbiamo arrivare a un’idea chiara su quale gioco vogliamo realizzare.
Questo è il passo più importante (e in qualche senso il più difficile) nella realizzazione di un gioco.
Un buon gioco è eccitante, sorprendente e coinvolgente.
Ci devono essere obbiettivi chiari per il giocatore e l’interfaccia grafica deve essere intuitiva.

Il gioco che stiamo per realizzare è un gioco di labirinto.
Ciascun livello è un labirinto.
Per uscire dal labirinto dobbiamo raccogliere tutti i diamanti e poi raggiungere l’uscita.
Per fare questo il giocatore deve risolvere degli enigmi ed evitare dei mostri.

Gli enigmi potrebbero essere

  • dei blocchi devono essere spinti dentro delle buche
  • parti del muro possono esplodere utilizzando delle bombe

È molto importante non rivelare tutto nel primo livello.
I nuovi oggetti, e i mostri, dovrebbero apparire gradualmente per rendere il gioco interessante.

Allora

  • L’oggetto principale è una persona controllata dal giocatore.
  • Ci sono muri (potrebbero essere di diverso tipo per rendere il labirinto più piacevole).
  • Ci sono diamanti da raccogliere.
  • Ci sono in giro degli oggetti che fanno qualcosa se toccati o raccolti dal giocatore.
  • Un oggetto particolare sarà l’uscita dal livello.
  • E ci sono dei mostri che si muovono da soli.

Ma trattiamo tutto un passo alla volta.

Tutti i giochi parziali sono forniti nella cartella Examples inclusa nel tutorial e possono essere caricati in GameMaker.
Sono fornite anche tutte le risorse nella cartella Resources.

Person Wall Goal Wall Wall Wall Door Diamond Mostro 1 Mostro 2 Mostro 3 Blocco Buca Bomba Detonatore Person Mostro 1 Mostro 2

Mostro 3 Bonus 1 Bonus 2 Bonus 3 Move Up Move Right Move Down Move Left

 

Un semplice inizio

Come primo passo dimentichiamoci dei diamanti.
Creeremo un gioco nel quale il giocatore deve semplicemente raggiungere l’uscita.

Ci sono 3 ingredienti fondamentali nel gioco: il giocatore, ilmuro e la meta.
Per ognuno di essi sono necessari una sprite e un oggetto.

Gli oggetti

Come primo passo creiamo gli oggetti.
Per ognuno dei 3 oggetti utilizziamo una semplice immagine 32x32.
Crea le 3 sprite e dagli i nomi spr_personspr_wall e spr_goal.
Il personaggio e la meta devono essere trasparenti.
Il muro non deve essere trasparente.
Adesso creiamo i 3 oggetti.

WallCominciamo con la realizzazione del muro.
Gli assegniamo la sprite spr_wall come immagine, lo nominiamo obj_wall, selezioniamo la casella Solid per indicare che il muro è solido.
In questo modo gli altri personaggi non potranno attraversarlo.
L’oggetto muro non fa altro.
Quindi non c’è bisogno di definire alcun evento per esso.

GoalPassiamo alla realizzazione dell’oggetto meta.
Questo è l’oggetto che il giocatore deve raggiungere.
Non è un oggetto solido.
Abbiamo deciso, momentaneamente, di assegnarli come figura una bandiera a schacchi.
Questo rende chiaro al giocatore che deve raggiungerla.
Quando il personaggio la tocca dobbiamo passare al prossimo livello.
Quindi aggiungiamo questa azione Next Room nell’evento collisione Collision Event (si trova nella scheda main1).
Quest’azione ha delle controindicazioni.
Provoca un errore quando il giocatore ha finito l’ultimo livello.

Dobbiamo quindi fare qualcosa:

  1. prima controlliamo se c’è un altro livello If Next Room
  2. se è vero ci andiamo Next Room
  3. altrimenti Else Action
  4. facciamo ripartire il gioco Restart Game.
obj_goal

Naturalmente, nel gioco completo faremo qualcosa di più quando il giocatore completa l’ultimo livello, come visualizzare un’immagine carina, oppure assegnargli un posto nella classifica dei giocatori più bravi.
Riprenderemo la cosa più avanti.

PersonInfine realizziamo il personaggio controllato dal giocatore.

Per questo serve del lavoro in più.
Deve reagire alle azioni dell’utente e non deve sbattere sui muri.
Utilizzeremo le frecce direzionali per il movimento.
Questo è naturale, quindi facile per l’utente.
Ci diversi modi per far muovere un personaggio

  1. Il modo più semplice è spostare il personaggio di una cella nella direzione indicata dal giocatore premendo una freccia.
  2. Una seconda possibilità, che noi utilizzeremo, è che il personaggio continui a muoversi in una direzione finché il tasto è premuto.
  3. Un altro approccio prevede che il personaggio continui a muoversi finché non viene premuto un altro tasto (come inPacMan).

Sono necessarie delle azioni per le 4 frecce direzionali.
Si tratta di azioni piuttosto banali.
Semplicemente impostano la giusta direzione per il movimento (come speed utilizziamo 4).
Per fermarci, quando il giocatore rilascia il tasto, utilizziamo l’evento Keyboard con il valore <no key>.
In questo evento fermiamo il movimento.
Purtroppo c’è una complicazione.
Vogliamo che il personaggio si trovi allineato con le celle della griglia che forma il labirinto.
Altrimenti il movimento diventerebbe piuttosto difficile.
Cioè vogliamo che si fermi nella posizione giusta per passare in un corridoio.
Si ottiene come segue.
Nella scheda control c’è un’azione If Grid per controllare se l’istanza dell’oggetto è allineata alla griglia.
Solamente se questo è vero verrà eseguita la prossima azione.

Check GridAggiungiamola a ogni evento delle frecce direzionali e impostiamo i parametri snap a32 che è la dimensione della griglia nel nostro labirinto:

 Chiaramente è necessario anche fermare il movimento quando si finisce sul muro.
Quindi nell’evento collisione del personaggio con il muro inseriamo un’azione che ferma il movimento.

C’è un problema che devi valutare a questo punto.
Se la sprite del personaggio non riempie completamente la cella, che è la normalità, potrebbe accadere che il personaggio non sia allineato alla griglia quando collide con il muro.
Per precisione, succede quando c’è un bordo di dimensione maggiore della velocità intorno all’immagine.
In questo caso il personaggio rimarrà immobile perché non reagirà ai tasti (perché non è allineato alla griglia) ma non potrà nemmeno muoversi in avanti (perché c’è il muro).
La soluzione è rendere la sprite più grande oppure disabilitare Precise collision checking e specificare Full image comeBounding box.

I livelli

Questo è tutto quello che dovevamo per le azioni.
Adesso realizziamo alcuni livelli.
Crea 1 o 2 livelli che assomiglino a un labirinto.
In ogni livello posiziona l’0ggetto meta come destinazione e un oggetto personaggio alla posizione di partenza.

Finito!

E questo è tutto, il primo gioco è pronto.
Giocaci per un po’ e prova a fare delle modifiche, per esempio

  • cambia la velocità del personaggio nel suo evento Create
  • crea dei nuovi livelli
  • cambia le immagini

 

 Raccogliere i diamanti

Ma l’obiettivo del nostro gioco non era raccogliere i diamanti?

I diamanti sono oggetti piuttosto semplici.
Ma come facciamo a essere sicuri che il giocatore non possa uscire dal livello finché non ha raccolto tutti i diamanti?
Per questo aggiungiamo un oggetto porta.
L’oggetto porta si comporterà come un muro finché ci saranno diamanti in giro e si dissolverà quando saranno spariti tutti i diamanti.

Oltre agli oggetti muro, meta e personaggio adesso sono necessari altri due oggetti con le sprite corrispondenti: il diamante e la porta.

DiamondIl diamante è un oggetto semplicissimo.
Ha bisogno di una sola azione che lo distrugga quando collide con il personaggio.
Allora aggiungiamo un’azione Destroy nell’evento di collisione.

Door 2L’oggetto porta sarà piazzato in posizione cruciale per bloccare il passaggio verso la meta.
Sarà Solid (per bloccare il passaggio al personaggio).
Nell’evento collisione della persona con la porta dobbiamo fermare il movimento.

Nell’evento Step della porta controlliamo se il numero di diamanti è 0 e se è vero si distrugge.
C’è un’azione per questo.

Step

Emetteremo anche un suono in modo che il giocatore senta che la porta si è aperta.

 

Miglioramenti grafici

Adesso che le basi del gioco sono in campo rendiamolo un po’ più carino.

I muri sono piuttosto ripetitivi.
Realizziamo 3 tipi diversi di oggetto muro, uno per gli angoli, uno per i muri verticali e un altro per i muri orizzontali.

Dagli ad ognuno la sprite corretta e rendili SolidWall Corner Wall Horizontal Wall Vertical
Adesso risistemando un po’ i livelli, appariranno più belli.

BackgroundAnche aggiungere un’immagine di sfondo aiuta.

Per evitare di dover specificare gli eventi di collisione della persona con tutti questi muri diversi (e più avanti lo stesso con i mostri) utilizziamo un’importante tecnica presente in GameMaker.
Rendiamo l’oggetto muro d’angolo parentgenitore, degli altri oggetti muro.
Questo significa che gli oggetti muro si comporteranno come varianti dell’oggetto muro d’angolo.
Avranno esattamente lo stesso comportamento (a meno che non specifichiamo per essi diversi comportamenti).
Anche per altre istanze sarà la stessa cosa.
Quindi dobbiamo specificare le collisioni con l’angolo.
Quest’azione sarà utilizzata automaticamente per tutti gli altri oggetti muro.
Anche all’oggetto porta possiamo dare il muro d’angolo come parent.

Il punteggio

Diamo al giocatore un punteggio in modo che possa misurare i suoi progressi.
È piuttosto semplice.
Per ogni diamante raccolto gli assegniamo 5 punti.
Quindi nell’evento Destroy del diamante aggiungiamo 5 a score.
Completare un livello regala 40 punti quindi aggiungiamo 40 a score nell’evento di collisione della meta con il personaggio.

Quando il giocatore completa l’ultimo livello deve essere visualizzata la classifica dei punteggi migliori.
Questo è semplice in GameMaker perché esiste un’azione appropriata.
L’oggetto meta diventa quindi un po’ più complicato.

Quando si scontra con il personaggio viene eseguito il seguente evento:

obj_goal

Aggiunge qualcosa al punteggio, emette un suono, aspetta per un po’ e quindi passa al prossimo livello oppure, se questo è l’ultimo livello, visualizza un messaggio , la classifica e fa ripartire il gioco.

Osserva che il punteggio appare automaticamente nel titolo della finestra.
Questo è leggermente brutto.
Per questo creeremo un oggetto di controllo.
Non ha bisogno di una sprite.
Sarà posizionato su tutti i livelli.
Esegue alcuni controlli globali su quello che sta succedendo.
Per il momento lo utilizziamo soltanto per visualizzare il punteggio.
Nel suo evento Draw utilizziamo Set Font e Set Color e poi Draw the score.

Schermata iniziale

La prima schermata del gioco dovrebbe mostrare il nome del gioco, il nome dell’autore, ….
Per questo utilizziamo il primo livello.
Creiamo una risorsa background con un’immagine piacevole.
Questo sfondo è utilizzato per il primo livello (è meglio se disabiliti il colore di sfondo e la tassellatura).
L’oggetto start_controller (invisibile, naturalmente) semplicemente aspetta finché l’utente non preme un tasto e poi passa al prossimo livello.
Il controllare inoltre imposta score a 0 e si assicura che il punteggio non venga visualizzato nella barra del titolo della finestra.

Suoni

Un gioco senza suoni è piuttosto noioso.
Quindi ci servono dei suoni.
Prima di tutto ci serve un suono di sottofondo.
Per questo utilizziamo qualche file midi piacevole.
Facciamo partire il pezzo nell’oggetto start_controller impostando loop a true.
Poi ci servono degli effetti audio per la raccolta di un diamante, la porta che si apre, e per il raggiungimento della meta.
Quando si raggiunge la meta, e dopo l’emissione del suono, è bene introdurre un’azione Sleep per avere una breve attesa prima di passare al livello successivo.

Nuovi livelli

Adesso possiamo realizzare dei livelli con diamanti.
Osserva che il primo livello senza diamanti possiamo semplicemente lasciarlo.
Questo va bene perché introduce il giocatore al concetto di movimento verso la bandiera a scacchi prima che abbia a che fare con la raccolta dei diamanti.
Se diamo nomi significativi ai livelli (Caption for the room nella scheda Settings del livello) il giocatore capirà cosa fare.

 

Mostri e altre sfide

Al punto in cui siamo adesso, il gioco sembra carino ma è completamente banale, e quindi noioso da giocare.
Abbiamo bisogno di un po’ d’azione sotto forma di mostri.
Inoltre aggiungeremo delle bombe, dei blocchi mobili e delle buche.

I mostri

Realizzeremo 3 tipi diversi di mostri:

  1. uno che si muove a destra e a sinistra, orizzontalmente
  2. uno che si muove in alto e in basso, verticalmente
  3. e uno che si muove nelle 4 direzioni.

Aggiungere un mostro è molto semplice.
Si tratta di un oggetto che comincia a muoversi e cambia direzione quando colpisce il muro.
Quando il personaggio tocca un mostro viene ucciso, cioè il livello riparte e il giocatore perde una vita.
Il giocatore riceve alla partenza 3 vite.

Monster 1Realizziamo il primo mostro che si muove a destra e a sinistra.
Utilizziamo una semplice sprite e poi creiamo l’oggetto corrispondente.
Nel suo evento Create decide se andare a destra o a sinistra.
Inoltre, per rendere la vita più difficile, impostiamo speed a un valore piuttosto alto.
Quando avviene una collisione cambia la sua direzione orizzontale.

Monster 2Il secondo mostro si comporta esattamente come il primo eccetto per la direzione iniziale che sarà verso l’alto oppure verso il basso e quando sbatte col muro inverte la direzione verticale.

Monster 3Il terzo mostro è leggermente più complesso.

Inizia muovendosi orizzontalmente o verticalmente.
Quando sbatte col muro prova a girarsi a sinistra oppure a destra.
Se non è possibile torna indietro.

monster_all
Per evitare problemi con i mostri che hanno immagini leggermente più piccole deselezioniamo Precise collision checking e impostiamo Bounding box alla maschera Full image.

Quando il personaggio tocca un mostro dobbiamo far emettere un suono, aspettare per un po’, decrementare di 1 il numero di vite e poi far ripartire il livello.
Osserva che l’ordine è cruciale: una volta che riparte il livello, le altre azioni non vengono più eseguite.
L’oggetto controllore, nell’evento No more lives, visualizza la classifica e fa ripartire il gioco.

Le vite

Abbiamo utilizzato il meccanismo di GameMaker per dare 3 vite al giocatore.
Sarebbe carino se mostrassimo anche il numero di vite.
L’oggetto controllore potrebbe farlo utilizzando la stessa modalità del punteggio.

Live

Ma è più carino se si vedono delle piccole immagini del personaggio per le vite.
C’è un’azione apposita nella scheda score.

L’evento Draw apparirà così:

controller_main

Osserva che abbiamo usato anche una risorsa di tipo Font per visualizzare il punteggio.

Le bombe

Aggiungiamo le bombe e i detonatori per farle esplodere.
L’idea è che quando il personaggio si avvicina al detonatore tutte le bombe esplodono, distruggendo tutte le cose nelle loro vicinanze.
Questo può servire per creare buchi nei muri e per distruggere i mostri.
Sono necessari 3 oggetti: un detonatore, una bomba e un’esplosione.
Per ciascuno è necessaria una sprite appropriata.

bombLa bomba è semplicissima.
Sta lì e non fa nulla.
Per essere sicuri che i mostri ci passino sopra (piuttosto che sotto) impostiamo depth a 10.
Le istanze degli oggetti sono disegnate in ordine di profondità, depth.
Quelle col valore più alto sono disegnate per prime.
E quindi finiranno dietro le istanze con valori più bassi.
Impostando depth a 10 per la bomba gli altri oggetti, che hanno depth a 0 di default, saranno disegnati sopra di essa.

TriggerAnche il detonatore è piuttosto semplice.

Quando collide con il personaggio trasforma tutte le bombe in esplosioni.
Questo si ottiene utilizzando l’azione che cambia un oggetto in un altro.
In cima indichiamo che si deve applicare a tutte le bombe.

Change Instance

ExplosionL’oggetto esplosione visualizza proprio l’animazione dell’esplosione.
Dopo l’animazione si distrugge.
Devi assicurarti che l’origine dell’esplosione sia nel posto giusto quando la bomba si trasforma in esplosione.
L’oggetto deve distruggere tutto quello che tocca.

Questo richiede un po’ di lavoro.

  • Non vogliamo che l’esplosione si autodistrugga quindi la spostiamo fuori temporaneamente.
  • Utilizziamo le azioni per distruggere tutte le istanze alle posizioni intorno alla posizione originaria dell’esplosione.
  • Infine rimettiamo l’esplosione al posto originario.

obj_explosion

Osserva che va tutto storto se il personaggio è vicino a una bomba!
Assicurati che i detonatori non siano vicini alle bombe.
Bisogna progettare con cura i livelli con bombe e detonatori in modo che presentino sfide interessanti.

Blocchi e buche

Realizziamo qualcos’altro per rendere il gioco più complicato.
Realizziamo dei blocchi che possono essere spinti dal giocatore.
Inoltre realizziamo delle buche che il giocatore non può attraversare ma che possono essere colmate con i blocchi per creare nuovi passaggi.
Così si presentano nuove possibilità per il gioco.
I blocchi devono essere spinti in modo particolare per creare i passaggi.
E puoi utilizzare i blocchi per catturare i mostri.

BlockIl blocco è un oggetto solido.
La cosa importante è che deve seguire il movimento del personaggio quando viene spinto.
Quando collide con il personaggio svolgiamo le seguenti azioni:

  • Controlliamo se la posizione relativa (8*other.hspeed8*other.vspeed) è vuota.
    Questa è la posizione dove deve essere spinto il blocco.
  • Se è vuota spostiamo lì il blocco.

Facciamo la stessa cosa se alla posizione c’è una buca.
Per evitare che i mostri corrano sui blocchi rendiamo il muro d’angolo parent del blocco.
C’è ancora un piccolo problema.
Siccome l’evento di collisione è definito tra il personaggio e il muro d’angolo e non tra il personaggio e il blocco, l’evento viene eseguito e il personaggio viene fermato.
Non è quello che vogliamo.
Per risolverlo aggiungiamo un’azione inattiva (un commento) nell’evento collisione della persona con il blocco.
Adesso l’evento viene eseguito comunque, e non ferma il personaggio.
Per essere precisi, il nuovo evento collisione sovrascrive l’evento collisione del parent.
Come detto prima, puoi fare in questo modo per dare a un oggetto figlio un comportamento leggermente diverso dal suo oggetto genitore.

HoleLa buca è un oggetto solido.
Quando collide con il blocco distrugge se stessa e il blocco.
Inoltre impostiamo come suo parent il muro d’angolo in modo che si comporti come un muro.

Con i blocchi e le buche puoi creare molti livelli intriganti.
Tuttavia, c’è un piccolo problema.
Puoi rimanere facilmente bloccato e quindi il livello diventa insolubile.
Allora dobbiamo dare al giocatore la possibilità di ricominciare il livello, al costo di una vita.
Per questo utilizziamo il tasto R, per ripartire.
In questo evento Keyboard del controllore semplicemente sottraiamo 1 dalle vite e facciamo ripartire il livello.

Con questo è finita la nostra terza versione del gioco di labirinto.
Adesso ha tutti gli ingredienti per realizzare tanti livelli interessanti.

 

Miglioramenti finali

Finiamo definitivamente il gioco.
Dobbiamo migliorare ancora la grafica.
Inoltre abbiamo bisogno di un certo numero di livelli più interessanti.
Per questo aggiungiamo alcuni bonus e altre caratteristiche.

Miglioramenti grafici

L’attuale grafica del gioco è piuttosto povera.
Facciamo allora qualcosa per migliorarla.
La cosa che maggiormente vogliamo cambiare è che il personaggio guardi nella direzione in cui si muove.
Person NiceIl modo più semplice per ottenere questo è utilizzare una nuova sprite che consiste di 4 sottoimmagini, una per ogni direzione:

Normalmente GameMaker cicla tra queste sottoimmagini.
Possiamo evitarlo impostando a 0 la variabile image_speed.

Change SpriteQuando cambiamo la direzione del personaggio, possiamo cambiare anche la sottoimmagine visualizzata dall’azione che cambia la sprite:

Una cosa simile possiamo farla per tutti i mostri ma non hanno un evento esplicito dove cambiano direzione.
È più semplice aggiungere un controllo alla fine del passo, con l’evento End step, per vedere in quale direzione il mostro si sta muovendo e adattare la sprite di conseguenza.

Bonus

Aggiungiamo due bonus:

  • 100 punti: Bonus 1
  • 1 vita: Bonus 2

Sono estremamente semplici: quando vengono toccati dal personaggio emettono un suono, si distruggono e aggiungono dei punti al punteggio oppure 1 al numero di vite.
Questo è tutto.

Sensi unici

Per rendere i livelli più complicati aggiungiamo delle strade a senso unico., cioè che possono essere attraversate in un’unica direzione.
Per questo realizziamo 4 oggetti, uno per ogni direzione, ciascuno con la forma di una freccia che punta nella direzione del movimento: Move Up Move Right Move Down Move Left.
Quando il personaggio è completamente su di essa ci dobbiamo muovere nella giusta direzione.
Lo facciamo nell’evento Step del personaggio.
Controlliamo se il personaggio è allineato alla griglia nel modo giusto e se si trova sulla freccia particolare.
Se corrisponde impostiamo il movimento nella direzione giusta.
Impostiamo speed a 8 per renderlo più evidente.

Mostri impauriti

Per realizzare livelli che assomiglino a quelli di Pacman diamo ai mostri una variabile di nome afraid.
Nell’evento Create la impostiamo a 0 (false).

Mostro 3Quando il personaggio incontra un nuovo oggetto anello impostiamo la variabile di tutti i mostri a true e cambiamo la sprite per far vedere che il mostro è piuttosto impaurito.
Adesso quando il personaggio incontra il mostro prima controlliamo se è impaurito o meno.
Se il mostro è impaurito viene spostato alla sua posizione iniziale.
Altrimenti, il giocatore perde una vita.
Guarda il gioco per i particolari.

Completiamo il gioco

Abbiamo creato un sacco di oggetti ma ancora non abbiamo un vero gioco.
Una caratteristica vincente nei giochi è il progetto dei livelli.
Dovrebbero andare dal più facile al più difficile.
All’inizio ci dovrebbero essere pochi oggetti e più avanti dovrebbero apparire gli altri.
Assicurati di proporre delle sorprese che spuntano fuori soltanto intorno al livello 50 e così via.
Chiaramente i livelli dovrebbero essere adattati ai giocatori attesi.
I rompicapi per bambini sono completamente diversi da quelli per adulti.

Inoltre un gioco ha bisogno di una documentazione.
In GameMaker puoi aggiungere facilmente una documentazione utilizzando Game Information.

Infine, i giocatori non vogliono giocare l’intero gioco in una sola volta.
Allora devi aggiungere un meccanismo per caricare e salvare i giochi.
Fortunatamente, è molto semplice.
In GameMaker è presente un meccanismo di load/save:

F5 salva il gioco corrente
F6 carica l’ultimo gioco salvato.

Dovresti scriverlo nella documentazione…

Considera il demo di questo tutorial: aprilo, giocaci, controllalo e cambia tutto quello che vuoi.
In particolare, dovresti aggiungere molti più livelli (al momento sono solo 20).
Inoltre potresti aggiungere altri oggetti, come

  • chiavi che aprono certe porte,
  • transporter che ti spostano da un posto all’altro nel labirinto,
  • proiettili che il personaggio spara contro i mostri,
  • porte che si aprono e si chiudono in certi momenti,
  • ghiaccio sul quale il personaggio scivola in una certa direzione,
  • trappole …

 

Conclusioni

Spero che questo tutorial ti abbia aiutato nella creazione dei tuoi giochi con GameMaker.
Ricordati di progettare prima il tuo gioco e poi di realizzarlo passo dopo passo (o meglio oggetto dopo oggetto).
Ci sono sempre molte strade diverse con le quali si possono raggiungere le cose.
Quindi se qualcosa non funziona prova in qualche altro modo.
Buona fortuna!

Binman

BINMANTratto da: GAME LEARNING > RESOURCES – Binman.zip
Autore: Jake Habgood, coautore del libro ufficiale.

A simple example of a platform game.
Aliens have invaded the city and you must hide from their patrols in a dustbin whilst you try to infiltrate the alien base.

Crea le risorse elencate di seguito con le caratteristiche specificate.
Salva con nome… le immagini originali.

TIPO NOME FILE
Sprites binman_left binman_left_strip18.png image
binman_right binman_right_strip18.png image
alien_left alien_left.png image
alien_right alien_right.png image
girder girder.png image
standing standing.png image
hide hide_strip16.png image
stand stand_strip6.png image
hidden hidden.png image
disk disk.png image
exit exit.png image
Sound music music.mid music.mid
Background cityscape cityscape.png vedi dopo
Objects Alien alien_left
Binman standing
Girder girder
Disk disk
Exit exit
Room level_1

 

imageGirder

Solid

 

image

Disk

Collision Event image Binman

image Destroy the instance

imageExit

Collision Event image Binman

image Destroy the instance

 

imageAlien

 

imageBinman

 

Livello 1

Imposta le proprietà del livello

Snap X / Snap Y32

settings

Width1280
Height960
Speed30

backgrounds

Draw background colornero
Foreground image: cityscape
Tile Hor
X0
Y400

views

Enable th use of Views
Visible when room starts
View in room

X: 0
Y: 480
W: 640
H: 480

Port on screen

X: 0
Y: 0
W: 640
H: 480

Object following

Binman
Hbor: 256
Vbor: 64
Hsp: -1
Vsp: -1

image

Posiziona tutti gli oggetti

image

continua…

Koalabr8

KOALABR8Tratto da: GAME LEARNING > RESOURCES – Koalabr8.zip.
Sviluppato ulteriormente nel libro ufficiale.
Autore: Jake Habgood, coautore del libro ufficiale.

Impara a realizzare giochi di labirinto con un rompicapo ispirato (molto alla lontana) da Lemmings (Wikipedia:Lemmings).

Muovi in modo sicuro una squadra di koala attraverso un labirinto pericoloso, controllandoli tutti e otto allo stesso tempo!

Ogni livello è costituito da

  • un labirinto di cespugli di eucalipto
  • più uscite per i koala
  • oggetti pericolosi: esplosivo, seghe circolari
  • un commutatore per aprire dei varchi
  • 8 koala da portare in salvo.

Se un koala tocca l’esplosivo o la sega circolare salta in aria e la missione di salvataggio è fallita.

Per comandare il gioco puoi usare

  • le 4 frecce per muovere i koala
  • il tasto R per ricominciare il livello
  • il tasto F1 per leggere l’help.

La versione del tutorial contiene solo 3 livelli, ma puoi provare a realizzarne innumerevoli altri.

Livello 1

Le risorse utilizzate nel primo livello sono:

  • l’eucalipto, l’uscita, il koala (4 direzioni), il koala morto, l’esplosivo
  • la musica di sottofondo, due effetti audio
  • l’immagine di sfondo.

Realizza le risorse elencate e poi aggiungi gli eventi e le azioni corrispondenti

TIPO NOME FILE
Sprite spr_eucalyptus eucalyptus.png Eucalyptus
spr_tnt tnt.png TNT
spr_exit exit.png Exit
spr_walk_up walk_up_strip8.png Walk up
spr_walk_left walk_left_strip8.png Walk left
spr_walk_down walk_down_strip8.png Walk down
spr_walk_right walk_right_strip8.png Walk right
spr_dead_koala dead_koala.png Dead koala
Sound snd_music music.mid
snd_bonza bonza.wav
snd_explosion explosion.wav
Background back_game background.png
Object obj_wall spr_eucalyptus Eucalyptus
obj_tnt spr_tnt TNT
obj_exit spr_exit Exit
obj_controller <no sprite>
obj_koala spr_walk_up Walk up
obj_dead_koala spr_dead_koala Dead koala
Room room_1

 

Eucalyptusobj_wall

  • Solid

TNT

obj_tnt

 

Exitobj_exit

Sono oggetti inanimati.

obj_controller

Step Event Step

image If lives are equal to 8

Start Block Start of a block
Sleep Action Sleep 1000 milliseconds
Next Room Go to next room with transition effect Interlaced from top
End Block End of a block

 

image Game Start

Play Sound Play sound snd_music; looping: true
image Show the game info

 

image Room Start

image Set the number of lives to 0

 

image Draw

image Draw the lives at (0,0) with sprite spr_walk_up

 

image press R-key

Current Room Restart the current room

 

Walk upobj_koala

  • Solid

Collision Event obj_koala
Collision Event obj_wall

Move Fixed Start moving in direction (000010000) with speed set 0

 

Collision Event obj_exit

Play Sound Play sound snd_bonza; looping: false
image Set the number of lives relative to 1
Destroy Action Destroy the instance

 

Collision Event obj_tnt

Play Sound Play sound snd_explosion; looping: false
image Change into instance obj_dead_koala

 

image <no key>

If Grid If object is aligned with grid with cells of 40 by 40 pixels

Begin Start of block
Move Fixed Start moving in direction (no) with speed set 0
End End of block

 

image <Left>

If Grid For all obj_koala: If object is aligned with grid with cells of 40 by 40 pixels

Begin Start of block
Sprite Action Change sprite into spr_walk_left
If Free If relative position (-4,0) for Only solid objects

Begin Start of block
Move Action 1 Start moving in a direction (sx) with speed set to 4
End End of block

Else Action Else

Begin Start of block
Move Action 1 Start moving in a direction (no) with speed set to 0
End End of block

End End of block

 

image <Right>
image <Up>
image <Down>

Copia l’evento precedente e cambia la sprite (up) (right) (down), la posizione relativa di collisione (0,-4) (+4,0) (0,+4) e la direzione del movimento (su) (dx) (giù)

 

Nella versione originale i koala si bloccano se il giocatore inverte bruscamente la direzione.
Ho eliminato il problema modificando gli eventi corrispondenti.
Adesso un koala si muove soltanto se tutti i koala sono allineati alla griglia.

 

Dead koalaobj_dead_koala

image Create

Set the gravity Set the gravity to 2 in direction 270
Move Free Set speed to 15 and direction to 80

 

Other Event Outside Room

Destroy Action Destroy the instance

Il koala salta in aria e scompare in basso.

Il primo livello

Inserisci l’immagine dello sfondo.

Background

Imposta

  • Snap X: 40
  • Snap Y: 40

Posiziona un’istanza di obj_controller in un punto qualsiasi e poi tutte le altre istanze…

KOALABR8 1

Livello 2

Nel secondo livello compare una sega circolare che si muove in verticale.
Se il koala la tocca fa una brutta fine…

Realizza le risorse in elenco e poi aggiungi gli eventi e le azioni corrispondenti
TIPO NOME FILE
Sprite spr_vertical_saw vertical_saw_strip2.png Vertical saw
Sound snd_saw saw.wav
Object obj_vertical_saw spr_vertical_saw Vertical saw
Room room_2

 

Vertical sawobj_vertical_saw

image Create

Vertical Speed Action Set the vertical speed to 4

 

Collision Event obj_koala

Play Sound Play sound snd_saw; looping: false
image Change into instance into obj_dead_koala

 

Collision Event obj_wall

image Reverse vertical direction

La sega si muove verticalmente (quando tocca la siepe inverte la direzione).
Se tocca il koala si comporta come l’esplosivo.

Ecco il secondo livello
KOALABR8 2

 

Livello 3

Nel terzo livello compaiono

  • la sega circolare con movimento orizzontale
  • i passaggi bloccati e l’interruttore.

Se l’interruttore viene toccato da un koala

  • passa da spento ad acceso
  • e le siepi, segnalate da un lucchetto chiuso, scompaiono aprendo dei passaggi.
 Realizza le risorse in elenco e poi aggiungi gli eventi e le azioni corrispondenti
TIPO NOME FILE
Sprite spr_locked locked.png Locked area
spr_switch_off switch_off.png Interruttore spento
spr_switch_on switch_on.png Interruttore acceso
spr_horizontal_saw horizontal_saw_strip2.png Horizontal saw
Object obj_locked spr_locked Locked area
obj_lever spr_switch_off Interruttore spento
obj_horizontal_saw spr_horizontal_saw Horizontal saw
Room room_3

 

Interruttore spentoobj_lever

Oggetto inanimato

Walk upobj_koala

Collision Event obj_locked_area

Move Fixed Start moving in direction (000010000) with speed set 0

 

Collision Event obj_lever

Sprite Action For other object: set the sprite to spr_switch_on
Destroy Action For all obj_locked_area: destroy the instance

L’area bloccata è invalicabile.
L’interruttore cambia stato e distrugge tutte le aree bloccate.

 

Horizontal sawobj_horizontal_saw

image Create

Horizontal Speed Action Set the horizontal speed to 4

 

Collision Event obj_koala

Play Sound Play sound snd_saw; looping: false
image Change into instance into obj_dead_koala

 

Collision Event obj_wall
Collision Event obj_locked_area
Collision Event obj_lever

image Reverse horizontal direction

Si comporta come la sega verticale tranne che per il movimento orizzontale.

Ecco il terzo livello
KOALABR8 3

 

Riepilogo

personaggi del gioco sono: l’eucalipto, l’uscita, il koala, l’esplosivo, le due seghe, il passaggio bloccato, l’interruttore.

TIPO NOME FILE
Sprite spr_walk_up walk_up_strip8.png Walk up
spr_walk_left walk_left_strip8.png Walk left
spr_walk_down walk_down_strip8.png Walk down
spr_walk_right walk_right_strip8.png Walk right
spr_dead_koala dead_koala.png Dead koala
spr_eucalyptus eucalyptus.png Eucalyptus
spr_exit exit.png Exit
spr_locked locked.png Locked area
spr_switch_off switch_off.png Interruttore spento
spr_switch_on switch_on.png Interruttore acceso
spr_tnt tnt.png TNT
spr_vertical_saw vertical_saw_strip2.png Vertical saw
spr_horizontal_saw horizontal_saw_strip2.png Horizontal saw
Sound snd_music music.mid
snd_bonza bonza.wav
snd_explosion explosion.wav
snd_saw saw.wav
Background back_game background.png
Object obj_koala spr_walk_up Walk up
obj_dead_koala spr_dead_koala Dead koala
obj_wall spr_eucalyptus Eucalyptus
obj_exit spr_exit Exit
obj_locked spr_locked Locked area
obj_lever spr_switch_off Interruttore spento
obj_tnt spr_tnt TNT
obj_vertical_saw spr_vertical_saw Vertical saw
obj_horizontal_saw spr_horizontal_saw Horizontal saw
obj_controller <no sprite>
Room room_1

 

Eucalyptusobj_wall

  • Solid

 

TNTobj_tnt

 

Exit

obj_exit

 

Interruttore spentoobj_lever

 

obj_controller

Step Event Step

image If lives are equal to 8
Start Block Start of a block
Sleep Action Sleep 1000 milliseconds
Next Room Go to next room with transition effect Interlaced from top
End Block End of a block

 

image Game Start

Play Sound Play sound snd_music; looping: true
image Show the game info

 

image Room Start

image Set the number of lives to 0

 

image Draw

image Draw the lives at (0,0) with sprite spr_walk_up

 

image press R-key

Current Room Restart the current room

 

Walk upobj_koala

  • Solid

 

Collision Event obj_koala
Collision Event obj_wall
Collision Event obj_locked_area

Move Fixed Start moving in direction (000010000) with speed set 0

 

Collision Event obj_exit

Play Sound Play sound snd_bonza; looping: false
image Set the number of lives relative to 1
Destroy Action Destroy the instance

 

Collision Event obj_tnt

Play Sound Play sound snd_explosion; looping: false
image Change into instance obj_dead_koala

 

Collision Event obj_lever

Sprite Action For other object: set the sprite to spr_switch_on
Destroy Action For all obj_locked_area: destroy the instance

 

image <no key>

If Grid If object is aligned with grid with cells of 40 by 40 pixels

Begin Start of block
Move Fixed Start moving in direction (no) with speed set 0
End End of block

 

image <Left>

If Grid For all obj_koala: If object is aligned with grid with cells of 40 by 40 pixels

Begin Start of block
Sprite Action Change sprite into spr_walk_left
If Free If relative position (-4,0) for Only solid objects

Begin Start of block
Move Action 1 Start moving in a direction (sx) with speed set to 4
End End of block

Else Action Else

Begin Start of block
Move Action 1 Start moving in a direction (no) with speed set to 0
End End of block

End End of block

 

image <Right>
image <Up>
image <Down>

Copia l’evento precedente e cambia la sprite (up) (right) (down), la posizione relativa di collisione (0,-4) (+4,0) (0,+4) e la direzione del movimento (su) (dx) (giù)

 

Dead koalaobj_dead_koala

image Create

Set the gravity Set the gravity to 2 in direction 270
Move Free Set speed to 15 and direction to 80

 

Other Event Outside Room

Destroy Action Destroy the instance

 

Vertical sawobj_vertical_saw

image Create

Vertical Speed Action Set the vertical speed to 4

 

Collision Event obj_koala

Play Sound Play sound snd_saw; looping: false
image Change into instance into obj_dead_koala

 

Collision Event obj_wall
Collision Event obj_locked_area
Collision Event obj_lever

image Reverse vertical direction

 

Horizontal sawobj_horizontal_saw

image Create

Horizontal Speed Action Set the horizontal speed to 4

 

Collision Event obj_koala

Play Sound Play sound snd_saw; looping: false
image Change into instance into obj_dead_koala

 

Collision Event obj_wall
Collision Event obj_locked_area
Collision Event obj_lever

image Reverse horizontal direction

 

I livelli

Inserisci l’immagine dello sfondo

Background

e poi continua
  • imposta
    • Snap X: 40
    • Snap Y: 40
  • posiziona un’istanza di obj_controller nell’angolo in alto a destra
  • posiziona tutte le altre istanze
  • lascia la prima riga libera per l’indicatore dei koala salvati.

Unlock!

È un clone di SOKOBAN

Progetto

In questa versione

  • un esploratore deve raccogliere le chiavi sparse in un labirinto
  • per sbloccare tutte le serrature e passare al livello successivo…

Utilizzo alcune risorse disponibili in GameMaker 8

  • le sprite della cartella Examples > Maze - Platform
  • la gestione degli eventi è simile a quella di MAZE.

UNLOCK

Ci sono poche risorse necessarie e i comportamenti degli oggetti sono relativamente semplici.

Risorse

Crea le risorse di base

TIPO NOME FILE IMMAGINE
Sprite spr_Muro wall_block.png Wall
wall_block_cracked1.png Wall
wall_block_cracked2.png Wall
spr_EsploratoreSu explorer_up_strip8.png Up
spr_EsploratoreDx explorer_right_strip8.png Right
spr_EsploratoreGiu explorer_down_strip8.png Down
spr_EsploratoreSx explorer_left_strip8.png Left
spr_Chiave key_gold.png key Gold
spr_Chiusa lock_silver.png Lock Silver
spr_Aperta lock_gold.png key Gold
Background back_Gioco Sfondo
Object obj_Muro spr_Muro Wall
obj_Chiave spr_Chiave key Gold
obj_Chiusa spr_Chiusa Lock Silver
obj_Aperta spr_Aperta key Gold
obj_Esploratore spr_Esploratore_Su Up
Room

Note

  1. Carica più immagini per il muro tramite Edit Sprite > File > Add from File....
  2. Per la chiave e le serrature sono disponibili le versioni luccicanti con 32 immagini!
  3. Per semplificare la gestione delle collisioni imposta, in tutte le sprite Modify Mask > Full image > Rectangle.
  4. Scegli un’immagine per lo sfondo di tuo gradimento
  5. Imposta il primo livello
    • Snap X / Snap Y32
    • Width640 (20 colonne)
    • Height576 (18 righe)
    • Speed20
    • bgSfondo
    • Tile Hor.
    • Tile Vert.
e poi utilizza Duplicate

 

WalloMuro

  • Solidon

image Create

Sprite Action Change sprite into spr_wall (subimage0speed0)
Dice Action With chance 1 out of 2 perform next (sides2)

Begin Start of block
Sprite Action Change sprite into spr_wall (subimage1speed0)
Dice Action With chance 1 out of 2 perform next (sides2)

Begin Start of block
Sprite Action Change sprite into spr_wall (subimage2speed0)
End End of block

End End of block

Usa la prima immagine ma con il lancio del dado potrebbe usare la seconda, ma con un altro lancio del dado potrebbe usare la terza.
Il contorno del labirinto risulterà sempre diverso.

 

key Goldobj_Chiave

  • Solid
  • Depth: 0

Collision Event Explorer obj_Esploratore

If Free If a position is collision free (x8*other.hspeedy8*other.vspeedRelativeonobjectsOnly solid)

Begin Start of block
image Jump to position (x8*other.hspeedy8*other.vspeedRelativeon)
End End of block

Se la chiave viene a contatto con l’esploratore, e la cella adiacente è libera, si sposta.

 

Lock Silverobj_Chiusa

  • Depth: -1

Step Event Step

image If there is a collision at position (x0y0RelativeonobjectsOnly solid)

Begin Start of block
image Change instance into obj_Aperta (…)
End End of block

Se la serratura chiusa è a contatto con un oggetto solido, la chiave, allora diventa obj_Aperta.

 

key Goldobj_Aperta

  • Depth: -1

Step Event Step

image If there is a collision at position (x0y0RelativeonobjectsOnly solidNOTon)

Begin Start of block
image Change instance into obj_Chiusa (…)
End End of block

Se la serratura aperta NON è a contatto con un oggetto solido, la chiave, allora diventa obj_Chiusa.

 

Upobj_Esploratore

  • Depth: -10

<Left>

Sprite Action Change sprite into spr_EsploratoreSx (spritespEsploratoreSxsubimage-1speed0.5)
If Grid If instance is aligned with grid (snap hor32snap vert32)

Begin Start of block
Move Action 1 Start moving in a direction (speed4)
End End of block

 

<Up>
<Right>
<Down>

Cambia la sprite dell’esploratore e la freccia in Start moving in a direction

 

<no key>

If Grid If instance is aligned with grid (snap hor32snap vert32)

Begin Start of block
Move Action 1 Start moving in a direction (speed0)
End End of block

Quando l’esploratore è allineato alla griglia

  • reagisce ai tasti di direzione e si mette in movimento
  • se nessun tasto è premuto si ferma…

Collision Event Wall obj_Muro

Move Action 1 Start moving in a direction (Speed0)

 

Collision Event key Gold obj_Chiave

image Comment

In caso di collisione con il muro, si ferma.
In caso di collisione con la chiave, non fa niente (perché agisce la chiave) ma è necessario comunque inserire l’evento.

Step Event Step

If Number If the number of instances is a value (objectobj_Chiusanumber0operationEqual to)

Begin Start of block
Sleep Action Sleep 1000 milliseconds
If Next Room If next room exists

Begin Start of block
Next Room Go to next room
End End of block

Else Action Else

Begin Start of block
Restart Game Restart the game
End End of block

End End of block

Se nel livello non ci sono oggetti obj_Chiusa, perchè sono diventati tutti obj_Aperta

  • aspetta un secondo
  • passa al prossimo livello, se esiste, oppure ricomincia da capo.

 

Finito!

Realizza dei livelli per controllare che tutto funzioni e buon divertimento!

 

Alcuni miglioramenti

Siccome hai terminato presto con gli oggetti, potresti dedicarti agli altri aspetti che possono rendere il gioco piùprofessionale

  • un certo numero di livelli
  • tutti gli accessori che non mancano mai…

 

I livelli

Crea dei gruppi di livelli all’interno della cartella di risorse Rooms e inserisci più livelli possibile…

Alcuni consigli

Tutorial Livelli semplici e progressivi per guidare l’utente alle prime armi col Sokoban
Nome_Cognome Le tue sfide rompicapo!
Sokoban
Boxworld
Peterbox
Finché i tuoi livelli non ti sembreranno avvincenti copia i livelli della versione originale e dellealtre versioni che trovi nel web!

Accessori del gioco

Prova ad aggiungere

  1. comandi per la gestione del gioco: prossimo/precedente/ricomincia livello, salva/ricarica gioco, …
  2. transizioni di livello: scegli tra quelle disponibili
  3. animazioni: tutte le serrature aperte, risolti tutti i livelli di un gruppo, …
    Wall Wall Wall Wall Wall
  4. effetti sonori: spinta, chiave nella serratura
  5. musica di sottofondo
  6. pannelli: inizio e fine del gioco, inizio e fine di un gruppo di livelli, informazioni generali
  7. contatori: livello, passi, spinte, tempo impiegato

Diamonds

DIAMONDSTratto da Treasure.

I giochi di labirinto sono una categoria di videogioco molto popolare e sono semplici da realizzare con Game Maker.

Nei giochi di labirinto ogni livello è un labirinto.
Per uscire dal labirinto, il personaggio deve raccogliere tutti gli oggetti disseminati nei corridoi, evitando di venire a contatto con dei mostri che girano per i livelli.

Progetto

In pratica è un clone di PACMAN anche se le sprite sono completamente diverse

  • l’oggetto principale del gioco è controllato dal giocatore ed è raffigurato come un esploratore
  • corridoi sono realizzati tramite 2 mattoni di base
  • gli oggetti preziosi sparsi per il pavimento devono essere raccolti tutti per poter superare il livello
  • mostri sono degli animali repellenti che si muovono continuamente
  • se l’esploratore viene a contatto con un mostro perde una vita
  • se l’esploratore raccoglie un oggetto speciale diventa invincibile contro i mostri
  • nel passaggio da un livello all’altro aumenta il numero di mostri oppure i corridoi diventano più intricati ma si presentano anche delle aperture nel perimetro del labirinto che aiutano a evitare i mostri quando si avvicinano troppo
  • compaiono, di tanto in tanto, anche dei bonus.

DIAMONDS

Il progetto è abbastanza semplice ma alcuni aspetti del gioco richiederanno un approfondimento

  • il personaggio si muove nelle 4 direzioni e quindi è necessario farlogirare quando cambia direzione
  • anche i mostri si girano e in più si muovono autonomamente.

In una versione più evoluta del gioco

  • i mostri potrebbero avere comportamenti diversi (uno di loro potrebbe addirittura inseguirel’esploratore)
  • si potrebbero aggiungere alcune delle idee presenti nel tutorial MAZE

Il gioco

Realizziamo una prima versione del gioco nella quale l’esploratore, per passare di livello, deve semplicemente raccogliere dei diamanti sparsi lungo il percorso.

Le sprite

Tramite il comando Resources > Create Sprite aggiungi al progetto 6 nuove sprite dando il nome specificato spEsploratoreSuspEsploratoreDestraspEsploratoreGiuspEsploratoreSinistraspMurospDiamante.

Associa a ogni sprite le immagini corrispondenti, si trovano in Maze > Maze – Platform, tramite il comando Menu contestuale > Properties... > Edit Sprite > File > Add from File....

Wall Diamond

Up Right

Down Left

Osserva che le sprite per l’esploratore sono delle strisce formate da 8 immagini che formeranno le animazioni nelle 4 direzioni…

Alcune immagini potrebbero essere leggermente più piccole del quadrato 32×32.
Per evitare problemi quando dovremo gestire il movimento e le collisioni deselezioniamo Precise collision checking e impostiamo Full image per Bounding box.

Gli oggetti

Adesso creiamo i 3 oggetti.

Il diamante

Gli assegniamo il nome oDiamante, la sprite spDiamante come immagine, non selezioniamo la casella Solid.
L’oggetto diamante non fa altro, quindi non ci sarà bisogno di specificare alcun comportamento.

Il muro

Gli assegniamo il nome oMuro, la sprite spMuro come immagine e selezioniamo la casella Solid.

L’esploratore

Gli assegniamo il nome oEsploratore, la sprite spEsploratoreSu come immagine, non selezioniamo la casella Solid.
Si tratta dell’oggetto controllato dal giocatore tramite le frecce direzionali.
Presenta una certa complessità perché dovrà avere diversi comportamenti.

Il livello

Realizziamo un livello.
Impostiamo alcuni valori nella barra degli strumenti

  • Snap X: 32
  • Snap Y: 32

e nelle schede presenti a sinistra della finestra delle proprietà
settings

  • NamerLivello, il nome interno del livello
  • Caption for the roomPrimi passi…, il nome che appare nella barra del titolo dell’applicazione
  • Width480, la larghezza del gioco (un multiplo della dimensione delle sprite)
  • Height480, l’altezza del gioco
  • Speed20, la velocità del gioco

backgrounds

  • Draw background color, disegna lo sfondo
  • Color: …, scegli un colore

objects

  • seleziona nel menu in basso oMuro e posizionalo più volte sul livello per formare un labirinto (utilizza i tasti sinistro e destro del mouse)
  • seleziona oDiamante e spargine sul pavimento del livello
  • seleziona oEsploratore e posizionalo alla sua posizione iniziale.

 

I comportamenti

Aggiungiamo all’esploratore un certo numero di eventi, Add Event, e per ognuno di essi le azioni corrispondenti che deve eseguire.

 

image Create

Sprite Action Change sprite into spEsploratoreSu
Alla sua prima comparsa riceve l’immagine girato verso l’alto

 

<Left>

If Grid If instance is aligned with grid
If Free If a position is collision free

Begin Start of block
Move Action 1 Start moving in a direction
Sprite Action Change sprite into spEsploratoreSinistra
End End of block

Quando viene premuto il tasto sinistro, se l’esploratore è allineato con la griglia di gioco e se la cella alla sua sinistra (x=-4, y=0, Relativeobjects=Only solid) è libera allora gli assegna un movimento selezionando la freccia corrispondente, con Speed=4 e cambia la sprite.

 

<Up>
<Right>
<Down>

Si comporta in modo analogo…

x=0, y=-4
x=+4, y=0
x=0, y=+4

 

Collision Event Wall oMuro

Move Action 1 Start moving in a direction
Set Variable Set variable image_speed to 0
Quando l’esploratore finisce sul muro deve essere fermato, impostando la direzione rappresentata dal quadrato centrale e Speed=0.
Anche l’animazione del movimento deve essere fermata, con image_speed=0.

 

Collision Event Diamond oDiamante

Destroy Action Destroy the instance
Quando l’esploratore trova un diamante lo raccoglie, facendolo scomparire dalla scena tramite Destroy Instance conApplies to=Other.

 

Step Event Step

If Number If the number of instances is a value

Begin Start of block
Restart Game Restart the game
End End of block

A ogni passo del gioco l’esploratore controlla se ha finito di raccogliere i diamanti, effettuando un Test Instance Countcon objectoDiamantenumber0 e operationEqual to.
In caso di risposta affermativa fa ripartire il gioco.

Finito!

La prima versione del gioco è pronta.
Giocaci per un po’ e poi prova a fare delle modifiche

  • cambia le immagini degli oggetti
  • ingrandisci il livello e crea un vero labirinto
  • fai andare più veloce l’esploratore…
  • fai andare più piano le animazioni dell’esploratore…
  • fai andare più piano tutto il gioco…

 

Alcuni miglioramenti

Aggiungiamo al gioco delle rifiniture per renderlo piùaccattivante: più livelli, suoni e punteggi.

Il muro

Il muro viene rappresentato, in modo casuale, con 2 immagini diverse.
Bisogna aggiungere la seconda immagine Cracked Wall alla sprite spMuro e poi aggiungere un evento e le azioni corrispondenti all’oggetto oMuro

image Create

Sprite Action Change sprite into spMuro
Dice Action With chance 1 out of 10 perform next

Begin Start of block
Sprite Action Change sprite into spMuro
End End of block

La prima azione Change Sprite assegna 0 come subimage.
La seconda assegna 1 come subimage (il muro rotto) ma soltanto 1 volta su 10 perché dipende dal lancio del dado consides=10.

 

I livelli

Aggiungiamo al progetto una risorsa nella cartella Backgrounds che utilizzeremo come sfondo, pavimento, per i livelli.

Utilizziamo il comando Resources > Create Backgrounds e assegnamo alla risorsa il nome bSfondo e l’immagine Stone tramite Load Background.

Aggiungiamo lo sfondo al livello impostando le proprietà nella scheda backgrounds del livello

  • Visible when room starts
  • Tile Horizontal, l’immagine deve essere ripetuta perché è piccola…
  • Tile Vertical

Adesso realizza alcuni livelli (rLivello1rLivello2, … ) riciclando il primo livello tramite Menu contestuale > Duplicate.
In particolare, realizza un livello con delle aperture nel perimetro esterno di muri: permetteranno all’esploratore di passare velocemente da un lato del labirinto al lato opposto.

Suoni e musica

Per aggiungere dei suoni in corrispondenza di eventi particolari e una musica di sottofondo, crea 3 risorse nella cartellaSounds e imposta, con Load Sound, i suoni corrispondenti

  • sDiamante, sarà emesso quando l’esploratore raccoglie un diamante
  • sDiamantiFiniti, alla fine del livello
  • sSottofondo, una piacevole musica di sottofondo sempre in azione.

 

L’esploratore

I comportamenti dell’esploratore devono essere aggiornati per rendere effettive le novità che vogliamo introdurre.
Gli eventi Game Start e Outside Room si trovano nella cartella Other Event Other event.

Other Event Game Start

Set Score Set the score to 0
Set Caption Set the score caption info
Play Sound Play sound sSottofondo

Quando inizia il gioco

  • azzera il punteggio, new score0
  • aggiungi il punteggio nella barra del titolo dell’applicazione, show scoreshow
  • inizia a suonare la musica di sottofondo, soundsSottofondolooptrue.

Other Event Outside Room

Wrap Action Wrap in both directions when outside

Se esce fuori dal livello allora entra dall’altra parte, directionin both directions.

Collision Event Diamond oDiamante

Destroy Action Destroy the instance
Play Sound Play sound sDiamante
Set Score Set the score relative to 100

Quando l’esploratore trova un diamante lo raccoglie e guadagna 100 punti, new score100Relative.
Viene emesso anche un suono.

Step Event Step

Set Score Set the score relative to -1
If Number If the number of instances is a value

Begin Start of block
Play Sound Play sound sDiamantiFiniti
Sleep Action Sleep 2000 milliseconds
If Next Room If next room exists

Begin Start of block
Next Room Go to next room
End End of block

Else Action Else

Begin Start of block
Highscore Action Show the highscore table
Restart Game Restart the game
End End of block

End End of block

A ogni passo del gioco l’esploratore perde un punto (questo per evitare che il giocatore si appisoli…) e controlla se ha finito di raccogliere i diamanti.
Se ha finito il livello emette un suono, aspetta qualche secondo e poi decide tra caricare il prossimo livello, se esiste, oppure visualizzare la classifica e ricominciare il gioco dall’inizio.

 

Prova!

Con i suoni, i punti e tanti livelli il gioco comincia a farsi interessante!
Prova a giocarci.
Fai qualche ritocco sui valori delle variabili.

Cosa manca al gioco per essere veramente avvincente?

 

I ragni

Al gioco manca il brivido!
Bisogna aggiungere gli animali più repellenti che esistono e aizzarli contro l’esploratore!

In questa fase di sviluppo del gioco ci basta che i ragni si muovano autonomamente, anche se lo fanno in modostupido.

 

I ragni

I ragni, per certi aspetti, assomigliano all’esploratore: sono rappresentati tramite 4 animazioni, se escono dal bordo rientrano dal lato opposto, …

image Create

Sprite Action Change sprite into spRagnoSu

Other Event Outside Room

Wrap Action Wrap in both directions when outside

Collision Event Wall oMuro

Hor. Reverse Reverse horizontal direction
Ver. Reverse Reverse vertical direction

Se i ragni sbattono sul muro fanno marcia indietro… invertendo la direzione orizzontale e verticale.

Step Event Step

If Grid If instance is aligned with grid

Begin Start of block
Dice Action With chance 1 out of 10 perform next

Begin Start of block
Move Action 1 Start moving in a direction
End End of block

End End of block

Ogni tanto cambiano direzione… scegliendo a caso tra le 4: sinistra-destra, su-giù.

Step Event End Step

If Variable If direction is equal to 0

Begin Start of block
Sprite Action Change sprite into spRagnoDestra
End End of block

Else Action Else
If Variable If direction is equal to 90

Begin Start of block
Sprite Action Change sprite into spRagnoSu
End End of block

Else Action Else
If Variable If direction is equal to 180

Begin Start of block
Sprite Action Change sprite into spRagnoSinistra
End End of block

Else Action Else
If Variable If direction is equal to 270

Begin Start of block
Sprite Action Change sprite into spRagnoGiu
End End of block

Siccome cambiano direzione autonomamente, è necessario controllare in che direzione si muovono per assegnare loro l’animazione giusta.
Si può fare meglio…

 

L’esploratore

È necessario apportare degli aggiornamenti nei comportamenti dell’esploratore per tenere conto della presenza dei ragni.

 

Other Event Game Start

Set Lives Set lives to 5
Set Score Set the score to 0
Set Caption Set the score caption info
Play Sound Play sound sSottofondo

Quando inizia il gioco

  • riceve anche un certo numero di vite, new lives5
  • aggiunge anche le vite alla barra del titolo dell’applicazione, show livesshow

 

Other Event No More Lives

Highscore Action Show the highscore table
Restart Game Restart the game

Se perde tutte le vite si ricomincia da capo.

 

Collision Event … oRagno

Play Sound Play sound sColpito
Sleep Action Sleep 2000 milliseconds
Set Lives Set lives relative to -1
Current Room Restart the current room

Se l’esploratore viene a contatto con un ragno perde una vita e ricomincia lo stesso livello.

 

Prova!

Adesso il gioco è più appassionante perché bisogna continuamente controllare i movimenti dei ragni per evitare di rimanere senza vite prima di aver finito l’ultimo livello!

 

La pozione magica

Mancano ancora degli oggetti speciali che rendano il gioco ancora più imprevedibile

  • la pozione magica contro i ragni
  • la gemma sfuggente

Se l’esploratore raccoglie la pozione magica tutti i ragni diventano degli scheletri.
Gli scheletri continuano a muoversi come i ragni ma sono innocui: al contatto con l’esploratore scompaiono e ricompaiono alla posizione iniziale come ragni.

Se passa un certo intervallo di tempo lo scheletro ritorna alla posizione iniziale e ridiventa un ragno.

 

La pozione

L’esploratore gestisce la collisione con la pozione

Collision Event Red Potion oPozione

Destroy Action Destroy the instance (Applies toOther)
Play Sound Play sound sPozione (soundsPozioneloopfalse)
image Change instance into oScheletro (ObjectoRagnochange intooScheletroperform eventsnot)
image Set Alarm 0 to 200 (ObjectoScheletronumber of steps200in alarm noAlarm 0)

Tutti i ragni diventano scheletri dotati di un allarme con 200 passi.

 

Gli scheletri

Duplica l’oggetto oRagno e mantieni gli eventi: StepCollisione con il muroOutside Room (quindi elimina Create e End Step).
Aggiungi la gestione dell’allarme

image Alarm 0

image Change instance into oRagno (Selfonchange intooRagnoperform eventsnot)

 

Finito?

Adesso il gioco presenta dei momenti difficili intervallati da attimi di tranquillità… potrebbe diventare un gioco interessante con l’aggiunta di un certo numero di livelli originali e nella giusta progressione.

Treasure

TREASURETratto da: Treasure – Written by Mark Overmars – Graphics by Matt Sandford – Sounds and music by Jacob Habgood.

Un clone di PACMAN presente nella cartella Examples di GameMaker 8.
Sviluppato ulteriormente nel libro ufficiale.

 

Se sei un principiante studia prima il tutorial DIAMONDS.
Se hai già un po’ d’esperienza crea le risorse elencate di seguito con le caratteristiche specificate

TIPO NOME FILE
Sprites spr_wall wall_strip2.png image
spr_treasure treasure.png image
spr_expl_left expl_left_strip4.png image
spr_expl_left expl_right_strip4.png image
spr_expl_left expl_up_strip4.png image
spr_expl_down expl_down_strip4.png image
spr_monster monster_strip4.png image
spr_scared afraid_strip4.png image
spr_special special.png image
spr_bonus bonus.png image
Sounds snd_beep beep.wav
snd_dead dead.wav
snd_bonus bonus.wav
snd_won won.wav
snd_catch catch.wav
snd_music music.mid
Backgrounds back_game background.png vedi dopo
Scripts script_direction
Objects obj_wall spr_wall image
obj_point spr_treasure image
obj_explorer spr_expl_up image
obj_monster spr_monster image
obj_scared spr_scared image
obj_pil spr_special image
obj_bonus spr_bonus image
Room room_0
room_1

Imposta le proprietà dei livelli

Snap X / Snap Y32
Width / Height480
Speed20

image

 

 

imageobj_point

imageobj_pil

imageobj_wall

  • Solidon

image Create

Sprite Action Change sprite into spr_wall (subimage0)
Dice Action With chance 1 out of 20 perform next (sides20)

Begin Start of block
Sprite Action Change sprite into spr_wall (subimage1)
End End of block

 

imageobj_explorer

  • Depth-1

image Create

Sprite Action Change sprite into spr_expl_up (spritespr_expl_upsubimage: 0, speed0)

Other Event Game Start

Set Lives Set lives to 3 (new lives3)
Set Score Set the score to 0 (new score0)
Set Caption Set the score caption info (show scoreshowshow livesshow)
Play Sound Play sound snd_music (soundsnd_musiclooptrue)

<Left>

If Free If a position is collision free (x-4y0RelativeonobjectsOnly solid)

Begin Start of block
Move Action 1 Start moving in a direction (speed4)
Sprite Action Change sprite into spr_expl_left (spritespr_expl_leftsubimage-1speed0.5)
End End of block

<Up>


(x0y-4spritespr_expl_up)

<Right>


(x4y0spritespr_expl_right)

<Down>


(x0y4spritespr_expl_down)

Collision Event obj_wall

Move Action 1 Start moving in a direction (Speed0Relativeoff)
Set Variable Set variable image_speed to 0 (variableimage_speedvalue0)

Other Event Outside Room

Wrap Action Wrap in both directions when outside (directionsin both directions)

Collision Event obj_point

Destroy Action Destroy the instance (Applies toOther)
Play Sound Play sound snd_beep (soundsnd_beeploopfalse)
Set Score Set the score relative to 10 (new score10Relativetrue)

Step Event Step

If Number If the number of instances is a value (objectpointnumber0operationEqual to)

Begin Start of block
Play Sound Play sound snd_won (soundsnd_wonloopfalse)
Sleep Action Sleep 2000 milliseconds (milliseconds2000redrawtrue)
If Next Room If next room exists

Begin Start of block
Next Room Go to next room
End End of block

Else Action Else

Begin Start of block
Highscore Action Show the highscore table
Restart Game Restart the game
End End of block

End End of block

Collision Event obj_monster

Play Sound Play sound snd_dead; loop: false
Sleep Action Sleep 1500 milliseconds (milliseconds1500redrawtrue)
image Jump to the start position (Objectobj_monster)
image Jump to the start position (Objectobj_scared)
Move Action 1 Start moving in a direction (speed0Relativeoff)
Set Variable Set variable image_speed to 0 (variableimage_speedvalue0)
image Jump to the start position (Selfon)
Set Lives Set lives relative to -1 (new lives-1Relativetrue)

Other Event No More Lives

Highscore Action Show the highscore table
Restart Game Restart the game

Collision Event obj_pil

Play Sound Play sound snd_bonus (soundsnd_bonusloopfalse)
Destroy Action Destroy the instance (Applies toOther)
image Change instance into obj_monster (Objectobj_scaredchange intoobj_monsterperform events:not)
image Change instance into obj_scared (Objectobj_monsterchange intoobj_scaredperform eventsnot)
image Set Alarm 0 to 160 (Objectobj_scarednumber of steps160in alarm noAlarm 0)

Collision Event obj_scared

Play Sound Play sound snd_catch (soundsnd_catchloopfalse)
image Jump to the start position (Otheron)
image Change instance into obj_monster (Otheronchange intoobj_monsterperform eventsnot)
Set Score Set the score relative to 100 (new score100Relativeon)

 

imageobj_monster

  • Depth-2

image Create

Sprite Action Change sprite into spr_monster (Selfonspritespr_monstersubimage0speed0)
Move Action 1 Start moving in a direction (speed4)

Step Event Step

If Grid If instance is aligned with grid

Begin Start of block
image Execute script script_direction: (scriptscript_direction)
End End of block

Step Event End Step

If Variable If direction is equal to 0

Begin Start of block
image Set variable image_index to 2
End End of block

Else Action Else
If Variable If direction is equal to 90

Begin Start of block
image Set variable image_index to 3
End End of block

Else Action Else
If Variable If direction is equal to 180

Begin Start of block
image Set variable image_index to 0
End End of block

Else Action Else
If Variable If direction is equal to 270

Begin Start of block
image Set variable image_index to 1
End End of block

Collision Event obj_wall

Hor. Reverse Reverse horizontal direction
Ver. Reverse Reverse vertical direction
image Execute script script_direction: (scriptscript_direction)

Other Event Outside Room

Wrap Action Wrap in both directions when outside (Selfondirectionsin both directions)

 

imageobj_scared

  • Parentobj_monster

image Alarm 0

image Change instance into obj_monster (Selfonchange intomonsterperform eventsnot)
Move Action 1 Start moving in a direction (DirectionsN-E-S-OSpeed4Relativeoff)

 

imageobj_bonus

image Create

image Jump to position (-1000,0) (x-1000y0)
image Set Alarm 0 to 500 (Selfonnumber of steps500in alarm noAlarm 0)

image Alarm 0

image Jump to the start position (Selfon)
image Set Alarm 1 to 200 (Selfonnumber of steps200in alarm noAlarm 1)

image Alarm 1

image Jump to position (-1000,0) (x-1000y0)
image Set Alarm 0 to 500 (Selfonnumber of steps500in alarm noAlarm 0)

Collision Event explorer

Play Sound Play sound snd_bonus (Soundsnd_bonusloopfalse)
Set Score Set the score relative to 200 (new score200Relativeon)
image Jump to position (-1000,0) (x-1000y0)
image Set Alarm 0 to 500 (Selfonnumber of steps500in alarm noAlarm 0)

 

script_direction

// This script adapts the direction of the monster
// when it comes at a possible crossing
{
  if (hspeed == 0)
  {
    if (random(3)<1 && place_free(x-4,y)) { hspeed = -4; vspeed = 0;}
    if (random(3)<1 && place_free(x+4,y)) { hspeed =  4; vspeed = 0;}
  }
  else
  {
    if (random(3)<1 && place_free(x,y-4)) { hspeed = 0; vspeed = -4;}
    if (random(3)<1 && place_free(x,y+4)) { hspeed = 0; vspeed =  4;}
  }
}