CAMPO MINATO [exe+source+html5]
Salute a voi non ho idea se qualcuno l'abbia già fatto comunque oggi vi presento un giochino che ho programmato al volo (penso possa essere utile, almeno si spera, a chi si avvicina a GM). Per farlo girare basta la lite/standard.
Il gioco (CAMPO MINATO) credo lo conosciate tutti
Screeenshots:
Spoiler
Video:
Spoiler
Download e info:
Spoiler
ecco il link:
http://www.giochi3.altervista.org/cm.htm
difetti conosciuti:
- ci sono solo le funzioni di base...
- la grafica è tutta da rivedere
- FINE non ho notato niente altro di anomalo
dettagli tecnici:
se volete sapre qualcosa chiedete (cosa volete sapere di preciso ?).
http://www.giochi3.altervista.org/cm.htm
difetti conosciuti:
- ci sono solo le funzioni di base...
- la grafica è tutta da rivedere
- FINE non ho notato niente altro di anomalo
dettagli tecnici:
se volete sapre qualcosa chiedete (cosa volete sapere di preciso ?).
codice poco commentato per chi ama il brivido ( )
Spoiler
Information about object: oInvis
Codice: Seleziona tutto
Sprite: <no sprite>
Solid: false
Visible: true
Depth: 0
Persistent: false
Parent: <no parent>
Mask: <same as sprite>
Create Event:
execute code:
// personalizzazioni text box
message_alpha(0.8)
message_text_font("arial", 15, c_white, 0)
message_button_font("arial",10,c_white, 1)
fine = false
scoperte = 0
// colonna (x)
for (k=0; k <= 8; k += 1)
// riga (y)
for (k2=0; k2 <= 8; k2 += 1)
{
cas[k,k2] = 0
scoperta[k,k2] = false
}
// posiziono le bombe
bombs = get_integer("Quante Bombe ?",30)
for (k3=0; k3 <= bombs-1; k3 += 1)
{
xpos = irandom_range(0,8)
ypos = irandom_range(0,8)
if (cas[xpos,ypos] == 1)
{k3 -= 1}
cas[xpos,ypos] = 1
}
// calcolo totali
// colonna (x)
for (k=0; k <= 8; k += 1)
// riga (y)
for (k2=0; k2 <= 8; k2 += 1)
{
tot[k,k2] = 0
if k+1 <= 8
tot[k,k2] += cas[k+1,k2]
if k+1 <= 8 && k2-1 >= 0
tot[k,k2] += cas[k+1,k2-1]
if k2-1 >= 0
tot[k,k2] += cas[k,k2-1]
if k-1 >= 0 && k2-1 >= 0
tot[k,k2] += cas[k-1,k2-1]
if k-1 >= 0
tot[k,k2] += cas[k-1,k2]
if k-1 >= 0 && k2+1 <= 8
tot[k,k2] += cas[k-1,k2+1]
if k2+1 <= 8
tot[k,k2] += cas[k,k2+1]
if k+1 <= 8 && k2+1 <= 8
tot[k,k2] += cas[k+1,k2+1]
}
Mouse Event for Glob Left Pressed:
execute code:
if (fine == false)
{
xsel = mouse_x div 32
ysel = mouse_y div 32
if (scoperta[xsel,ysel] == true)
{exit}
//show_message(string(xsel)+","+string(ysel))
scoperta[xsel,ysel] = true
if (cas[xsel,ysel] == 1)
{
fine = true
cas[xsel,ysel] = 2
}
else
{
scoperte += 1
if (scoperte == 9*9-bombs)
{
fine = true
screen_redraw()
show_message("Hai vinto!!")
}
}
}
Mouse Event for Glob Right Pressed:
execute code:
if show_question("Vuoi iniziare una nuova partita ?")
{game_restart()}
Draw Event:
execute code:
draw_set_font(font0)
draw_set_halign(fa_center)
// colonna (x)
for (k=0; k <= 8; k += 1)
// riga (y)
for (k2=0; k2 <= 8; k2 += 1)
{
if (scoperta[k,k2])
{
draw_sprite(sCasSco,cas[k,k2],k*32,k2*32)
if (cas[k,k2] == 0)
{draw_text(k*32+16,k2*32,string(tot[k,k2]))}
}
else
{
if (!fine)
{draw_sprite(sCasCo,0,k*32,k2*32)}
//{draw_sprite(sCasCo,cas[k,k2],k*32,k2*32)}
else
{draw_sprite(sCasCo,cas[k,k2],k*32,k2*32)}
}
}
Spoiler
Codice: Seleziona tutto
Information about object: oInvis
Sprite: <no sprite>
Solid: false
Visible: true
Depth: 0
Persistent: false
Parent: <no parent>
Mask: <same as sprite>
Create Event:
execute code:
/*visto che avevo promesso di fare una SPIEGAZIONE DIRETTA A PRINCIPIANTI inizio subito:
---
stanze:
il gioco si svolge in una scacchierà a 9 x 9 = 81 caselle, ogni casella e grossa 32x32 pixel, quindi l'atezza / larghezza della stanza l'ho messa pari a 32 x 9 =288 pixel.
Ricordo che il gioco è ambientato in un'unica stanza che viene avviata appena il gioco parte
funzioni particolari:
Naturalmente non ho usato le views poichè la scacchiera ci sta tutta nello schermo e quindi non avrebbe senso usarle
oggetti:
il gioco è formato da UN UNICO oggetto che inizializza il gioco (diciamo "prepara" i valori di partenza), disegna la scacchiera, controlla le cliccate fatte con il mouse.
Naturalmente un'istanza dell'oggetto è poi stata inserita nella room (altrimenti la programmazione dell'oggetto rimarebbe disattivata e io avrei sprecato il mio tempo :mrgreen: )
sprite:
gli sprite non sono asscociati ad oggetti ma sono disegnati direttamente dove servono dal draw_event. Le 2 sprite sono sCaSco (sprite_casella_scoperta) e sCasCo (sprite_casella_coperta). La prima ha 2 sottoimmagini (casella coperta e casella coperta con bomba), la seconda ne ha 3 (casella scoperta, casella scoperta con bomba e casella scoperta con bomba e contorno rosso). Mi rendo conto che così su 2 piedi potrebbe non essere chiaro...comunque per adesso prendetela così...
varibili usate:
Codice:
fine // indica se è finita o meno la partita
scoperte // quante caselle vuote sono state scoperte dall'inizio della partita
k,k2,k3 // contatori dei cicli for
cas(array 2D) // se 0 la casella è vuota, se 1 la casella è con bomba, se 2 la casella contiene bomba con contorno rosso (quest'ultima sarebbe la bomba fatale, quella che hai fatto esplodere se hai perso)
scoperta(array 2D) // se la casella è scoperta o meno
tot (array 2D) // quante bombe ci sono nelle caselle adiacenti
bombs // quante bombe ci sono (lo decide il giocatore all'inzio della partita)
xpos, ypos // variabili usate nel posizionamento delle bombe (contengono le coordinate di una casella a caso)
xsel, ysel //coordinate della casella correntemente selezionata (calcolata a partite da mouse_x, mouse_y e la dimensione delle caselle)
*/
//ALL'AVVIO DEL GIOCO:
// personalizzazioni text box
// livello trasparenza (opaco = 1 completamente invisibile = 0)
message_alpha(0.8)
// testo messaggi (grafia: arial, dimensione: 15, colore: bianco, stile: normale)
message_text_font("arial", 15, c_white, 0)
// testo bottoni (grafia: arial, dimensione: 10, colore: bianco, stile: grassetto)
message_button_font("arial",10,c_white, 1)
//all'avio la partita ovviamente non è finita e...
fine = false
//...le caselle scoperte sono zero
scoperte = 0
// per ogni casella...
// colonna (x)
for (k=0; k <= 8; k += 1)
// riga (y)
for (k2=0; k2 <= 8; k2 += 1)
{
// ...la casella è vuota (non ha bombe)
cas[k,k2] = 0
// ...la casella è coperta
scoperta[k,k2] = false
}
// posiziono le bombe
// chiede al giocatore quante bombe devono essere nascoste nella scacchiera
bombs = get_integer("Quante Bombe ?",30)
// posiziona le bombe in caselle a caso
for (k3=0; k3 <= bombs-1; k3 += 1)
{
// sceglie una casella a caso
xpos = irandom_range(0,8)
ypos = irandom_range(0,8)
// se nella casella (scelta a caso) c'era già una bomba...
if (cas[xpos,ypos] == 1)
// ...impedisce a k3 di incrementare
{k3 -= 1}
cas[xpos,ypos] = 1
}
// calcolo totali
// qui per ogni casella viene calcolato quante bombe adiacenti ha
/* gli "if" sono stati messi perché atrimenti venivano richiamate nell'elaborazione
degli array con indici non validi*/
// colonna (x)
for (k=0; k <= 8; k += 1)
// riga (y)
for (k2=0; k2 <= 8; k2 += 1)
{
tot[k,k2] = 0
if k+1 <= 8
tot[k,k2] += cas[k+1,k2]
if k+1 <= 8 && k2-1 >= 0
tot[k,k2] += cas[k+1,k2-1]
if k2-1 >= 0
tot[k,k2] += cas[k,k2-1]
if k-1 >= 0 && k2-1 >= 0
tot[k,k2] += cas[k-1,k2-1]
if k-1 >= 0
tot[k,k2] += cas[k-1,k2]
if k-1 >= 0 && k2+1 <= 8
tot[k,k2] += cas[k-1,k2+1]
if k2+1 <= 8
tot[k,k2] += cas[k,k2+1]
if k+1 <= 8 && k2+1 <= 8
tot[k,k2] += cas[k+1,k2+1]
}
Mouse Event for Glob Left Pressed:
execute code:
// QUANDO VIENE PREMUTO IL TASTO SINISTRO DEL MOUSE:
// se la partita non è finita
if (fine == false)
{
// calcola su quale casella è avvenuto il click
xsel = mouse_x div 32
ysel = mouse_y div 32
// se la casella è già scoperta...
if (scoperta[xsel,ysel] == true)
// ...esci da questo evento
{exit}
/*istruzione per provare se funziona il riconoscimento
della casella su cui si è cliccato:
show_message(string(xsel)+","+string(ysel))*/
// scopre la casella selezionata
scoperta[xsel,ysel] = true
// se c'è una bomba...
if (cas[xsel,ysel] == 1)
{
//...fine del gioco (cioè non si può più cliccare, non è che esce)
fine = true
//...nella casella appare la "bomba con contorno rosso"
// come promemoria di quale è il punto in cui hai sbagliato
/* nel draw_event c'è un controllo che causa la visualizzazione di tutte
le bombe quando fine == true*/
cas[xsel,ysel] = 2
}
// se la casella è vuota
else
{
//tieni il conto di tutte le caselle scoperte fino ad ora
scoperte += 1
// se il numero di caselle scoperte e pari al totale delle caselle meno il numero di bombe
// (cioè se hai azzeccato TUTTE le caselle senza bomba)...
if (scoperte == 9*9-bombs)
{
//...fine del gioco (cioè non si può più cliccare, non è che esce)
fine = true
// ridisegna tutto (altrimenti prima compare "Hai vinto!!" e POI si scopre l'ultima casella cliccata)
screen_redraw()
// visualizza il messaggio dei vittoria ("Hai vinto!!")
show_message("Hai vinto!!")
}
}
}
Mouse Event for Glob Right Pressed:
execute code:
// QUANDO VIENE PREMUTO IL TASTO DESTRO DEL MOUSE:
// domanda se vuoi iniziare una nuova partita
// se si clicca su "yes" riavvia il gioco
if show_question("Vuoi iniziare una nuova partita ?")
{game_restart()}
Draw Event:
execute code:
// PER OGNI STEP:
// imposta la font
draw_set_font(font0)
// allineamento orizzontale: accentrato
draw_set_halign(fa_center)
// per ogni casella...
// colonna (x)
for (k=0; k <= 8; k += 1)
// riga (y)
for (k2=0; k2 <= 8; k2 += 1)
{
// ...se è scoperta...
if (scoperta[k,k2])
{
// ...disegnala scoperta
draw_sprite(sCasSco,cas[k,k2],k*32,k2*32)
// ...se non ha bombe...
if (cas[k,k2] == 0)
//...indica quante bombe sono adiacenti
{draw_text(k*32+16,k2*32,string(tot[k,k2]))}
}
//...se è coperta e...
else
{
//...se la partita non è finita...
if (!fine)
// ...diesgnala coperta non visualizzando le bombe
{draw_sprite(sCasCo,0,k*32,k2*32)}
//{draw_sprite(sCasCo,cas[k,k2],k*32,k2*32)}
// ...se la partita è finita....
else
//...disegnala coperta visualizzando comunque eventuali bombe
{draw_sprite(sCasCo,cas[k,k2],k*32,k2*32)}
}
}
Spoiler
Codice: Seleziona tutto
// questo è un one script game: tutti gli automatismi di Game Maker sono inibiti
//ALL'AVVIO DEL GIOCO:
// imposto il testo della barra del titolo e...
room_caption = "CAMPO MINATO OSG "
// ...lo visualizzo
screen_redraw()
// personalizzazioni text box
// livello trasparenza (opaco = 1 completamente invisibile = 0)
message_alpha(0.8)
// testo messaggi (grafia: arial, dimensione: 15, colore: bianco, stile: normale)
message_text_font("arial", 15, c_white, 0)
// testo bottoni (grafia: arial, dimensione: 10, colore: bianco, stile: grassetto)
message_button_font("arial",10,c_white, 1)
//all'avio la partita ovviamente non è finita e...
fine = false
//...le caselle scoperte sono zero
scoperte = 0
// per ogni casella...
// colonna (x)
for (k=0; k <= 8; k += 1)
// riga (y)
for (k2=0; k2 <= 8; k2 += 1)
{
// ...la casella è vuota (non ha bombe)
cas[k,k2] = 0
// ...la casella è coperta
scoperta[k,k2] = false
}
// posiziono le bombe
// chiede al giocatore quante bombe devono essere nascoste nella scacchiera
bombs = get_integer("Quante Bombe ?",30)
// posiziona le bombe in caselle a caso
for (k3=0; k3 <= bombs-1; k3 += 1)
{
// sceglie una casella a caso
xpos = irandom_range(0,8)
ypos = irandom_range(0,8)
// se nella casella (scelta a caso) c'era già una bomba...
if (cas[xpos,ypos] == 1)
// ...impedisce a k3 di incrementare
{k3 -= 1}
cas[xpos,ypos] = 1
}
// calcolo totali
// qui per ogni casella viene calcolato quante bombe adiacenti ha
/* gli "if" sono stati messi perché atrimenti venivano richiamate nell'elaborazione
degli array con indici non validi*/
// colonna (x)
for (k=0; k <= 8; k += 1)
// riga (y)
for (k2=0; k2 <= 8; k2 += 1)
{
tot[k,k2] = 0
if k+1 <= 8
tot[k,k2] += cas[k+1,k2]
if k+1 <= 8 && k2-1 >= 0
tot[k,k2] += cas[k+1,k2-1]
if k2-1 >= 0
tot[k,k2] += cas[k,k2-1]
if k-1 >= 0 && k2-1 >= 0
tot[k,k2] += cas[k-1,k2-1]
if k-1 >= 0
tot[k,k2] += cas[k-1,k2]
if k-1 >= 0 && k2+1 <= 8
tot[k,k2] += cas[k-1,k2+1]
if k2+1 <= 8
tot[k,k2] += cas[k,k2+1]
if k+1 <= 8 && k2+1 <= 8
tot[k,k2] += cas[k+1,k2+1]
}
do // ciclo "principale" (sostituisce il sistema di step di Game Maker)
{
//aggiorno manualmente lo stato della tastiera e del mouse
io_handle()
// QUANDO VIENE PREMUTO IL TASTO DESTRO DEL MOUSE:
// domanda se vuoi iniziare una nuova partita
// se si clicca su "yes" riavvia il gioco
if mouse_check_button(mb_right)
{
if show_question("Vuoi iniziare una nuova partita ?")
{
// riavvia il gioco
game_restart()
// esce dall'evento (altrimenti resta imprigionato nel ciclo "principale")
exit
}
}
// QUANDO VIENE PREMUTO F1:
// visualizza la guida
if keyboard_check(vk_f1)
{show_info()}
// QUANDO VIENE PREMUTO IL TASTO SINISTRO DEL MOUSE:
if mouse_check_button(mb_left)
{
// se la partita non è finita
if (fine == false)
{
// calcola su quale casella è avvenuto il click
xsel = mouse_x div 32
ysel = mouse_y div 32
// se la casella è già scoperta...
if !(scoperta[xsel,ysel] == true)
// ...salta le istruzioni successive e riinizia da (**)
{
/*istruzione per provare se funziona il riconoscimento
della casella su cui si è cliccato:
how_message(string(xsel)+","+string(ysel))*/
// scopre la casella selezionata
scoperta[xsel,ysel] = true
// se c'è una bomba...
if (cas[xsel,ysel] == 1)
{
//...fine del gioco (cioè non si può più cliccare, non è che esce)
fine = true
//...nella casella appare la "bomba con contorno rosso"
// come promemoria di quale è il punto in cui hai sbagliato
/* nel draw_event c'è un controllo che causa la visualizzazione di tutte
le bombe quando fine == true*/
cas[xsel,ysel] = 2
}
// se la casella è vuota
else
{
//tieni il conto di tutte le caselle scoperte fino ad ora
scoperte += 1
// se il numero di caselle scoperte e pari al totale delle caselle meno il numero di bombe
// (cioè se hai azzeccato TUTTE le caselle senza bomba)...
if (scoperte == 9*9-bombs)
{
//...fine del gioco (cioè non si può più cliccare, non è che esce)
fine = true
// ridisegna tutto (altrimenti prima compare "Hai vinto!!" e POI si scopre l'ultima casella cliccata)
screen_redraw()
// visualizza il messaggio dei vittoria ("Hai vinto!!")
show_message("Hai vinto!!")
}
}
}//(**)
}
}
// GESTIONE GRAFICA:
// imposta la font
draw_set_font(font0)
// allineamento orizzontale: accentrato
draw_set_halign(fa_center)
// per ogni casella...
// colonna (x)
for (k=0; k <= 8; k += 1)
// riga (y)
for (k2=0; k2 <= 8; k2 += 1)
{
// ...se è scoperta...
if (scoperta[k,k2])
{
// ...disegnala scoperta
draw_sprite(sCasSco,cas[k,k2],k*32,k2*32)
// ...se non ha bombe...
if (cas[k,k2] == 0)
//...indica quante bombe sono adiacenti
{draw_text(k*32+16,k2*32,string(tot[k,k2]))}
}
//...se è coperta e...
else
{
//...se la partita non è finita...
if (!fine)
// ...diesgnala coperta non visualizzando le bombe
{draw_sprite(sCasCo,0,k*32,k2*32)}
//{draw_sprite(sCasCo,cas[k,k2],k*32,k2*32)}
// ...se la partita è finita....
else
//...disegnala coperta visualizzando comunque eventuali bombe
{draw_sprite(sCasCo,cas[k,k2],k*32,k2*32)}
}
}
// aggiorna manualmente la grafica
screen_refresh()
// limitazione velocità
sleep(1)
}
until keyboard_check(vk_escape) //quando viene premuto escape il gioco esce dal ciclo "principale" e...
//...si chiude la finistra di gioco
game_end()
Spoiler
se qualcuno "in avvicinamento a GM" non capisce qualcosa saro lieto (o almeno ci proverò) a spiegare il (tutto sommato semplice) procedimento che ho usato
se avete (per caso) dei codici da integrare per rendere possibili miglioramenti li inserisco (con tanto di crediti) nel gioco volentieri (magari faccio 2 versioni, una base e una avanzata)
se avete (per caso) dei codici da integrare per rendere possibili miglioramenti li inserisco (con tanto di crediti) nel gioco volentieri (magari faccio 2 versioni, una base e una avanzata)
[11 ago 2014 ]
- aggiunte alcune migliorie al gioco
[13 ago 2014]
- possibilità di scegliere da quante caselle e formata la scacchiera (prima si poteva solo scegliere il numero di bombe)
- possibilità di scegliere tra campo minato e prato fiorito (tanto la programmazione è la stessa).
[28 ago 2014]
- aggiunti i disegni di MagicFool
- ora il gioco è a vite (cioè non perdi al primo errore)