Skip to content

Commit 93746a2

Browse files
committed
refactor stranger game
1 parent e939617 commit 93746a2

File tree

2 files changed

+183
-98
lines changed

2 files changed

+183
-98
lines changed
985 KB
Loading

game04_1/stranger_things.py

Lines changed: 183 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -2,178 +2,263 @@
22
import random
33
import math
44

5-
TITLE = "Stranger Python"
6-
FONT_COLOR = (255, 255, 255)
7-
WIDTH = 800
8-
HEIGHT = 600
9-
CENTRO_X = WIDTH / 2
10-
CENTRO_Y = HEIGHT / 2
5+
# COSTANTI DI GIOCO
6+
7+
TITOLO_GIOCO = "Stranger Python"
8+
COLORE_TESTO = (255, 255, 255)
9+
10+
LARGHEZZA = 800
11+
ALTEZZA = 600
12+
13+
LIVELLO_MASSIMO = 8
14+
15+
# Coordinate che useremo per stampare a video il testo
16+
CENTRO_X = LARGHEZZA / 2
17+
CENTRO_Y = ALTEZZA / 2
1118
CENTRO = (CENTRO_X, CENTRO_Y)
1219

13-
LIVELLO_FINALE = 8
20+
# Personaggi disponibili
21+
LISTA_PERSONAGGI = ["dustin", "lucas", "mike", "undici", "will"]
1422

15-
PERSONAGGI = ["dustin", "lucas", "mike", "undici", "will"]
23+
# Timer casuale per attivare il Sottosopra
24+
TEMPO_MIN_SOTTOSOPRA = 3
25+
TEMPO_MAX_SOTTOSOPRA = 10
1626

17-
game_over = False
18-
game_completato = False
27+
# VARIABILI DI STATO
28+
29+
gioco_terminato = False
30+
gioco_completato = False
1931
livello_corrente = 1
20-
selezione_iniziale = True
32+
fase_scelta_personaggio = True
33+
34+
personaggio_obiettivo = None
35+
personaggi_da_selezionare = []
36+
lista_personaggi_in_gioco = [] # gli attori che cadono a schermo
2137

22-
personaggio_target = None
23-
personaggi_scelta = []
24-
stelle = []
38+
modalita_sottosopra = False
39+
timer_sottosopra = random.randint(TEMPO_MIN_SOTTOSOPRA, TEMPO_MAX_SOTTOSOPRA)
2540

2641

2742
def draw():
2843
screen.clear()
29-
screen.blit("sfondo", (-150, -50))
3044

31-
if game_over:
45+
# Sfondi diversi in base al mondo
46+
if modalita_sottosopra:
47+
screen.blit("sfondo-sottosopra", (-200, -50))
48+
else:
49+
screen.blit("sfondo", (-150, -50))
50+
51+
# GAME OVER
52+
if gioco_terminato:
3253
mostra_messaggio("GAME OVER", "Prova di nuovo...")
3354
return
3455

35-
if game_completato:
56+
# VITTORIA
57+
if gioco_completato:
3658
mostra_messaggio("HAI VINTO!", "Complimenti!")
3759
return
3860

39-
if selezione_iniziale:
61+
# SCHERMATA DI SCELTA PERSONAGGIO
62+
if fase_scelta_personaggio:
4063
screen.draw.text(
4164
"Scegli il tuo personaggio",
4265
center=(CENTRO_X, 100),
4366
fontsize=40,
4467
color="white",
4568
)
46-
for p in personaggi_scelta:
47-
p.draw()
69+
for personaggio in personaggi_da_selezionare:
70+
personaggio.draw()
4871
return
4972

50-
for s in stelle:
51-
s.draw()
73+
# Disegna tutti i personaggi
74+
for attore in lista_personaggi_in_gioco:
75+
attore.draw()
76+
77+
78+
# LOGICA DI AGGIORNAMENTO
5279

5380

5481
def update():
55-
global stelle, selezione_iniziale, game_over
82+
global lista_personaggi_in_gioco, timer_sottosopra, modalita_sottosopra
5683

57-
if selezione_iniziale:
84+
# Se siamo in una schermata di pausa
85+
if fase_scelta_personaggio or gioco_terminato or gioco_completato:
5886
return
5987

60-
if len(stelle) == 0:
61-
stelle = genera_stelle(livello_corrente)
88+
# Se non ci sono attori sullo schermo → genera quelli del livello
89+
if len(lista_personaggi_in_gioco) == 0:
90+
lista_personaggi_in_gioco = genera_personaggi_in_caduta(livello_corrente)
6291
return
6392

64-
for s in stelle:
65-
# Movimento verticale
66-
s.y += s.vy
93+
# Aggiorna movimento di ogni personaggio
94+
for attore in lista_personaggi_in_gioco:
95+
# Movimento verticale diverso nel Sottosopra
96+
if modalita_sottosopra:
97+
attore.y -= attore.velocita_y
98+
if attore.y < -80:
99+
attiva_game_over()
100+
else:
101+
attore.y += attore.velocita_y
102+
if attore.y > ALTEZZA + 80:
103+
attiva_game_over()
104+
105+
# Oscillazione orizzontale sinusoidale
106+
oscillazione = math.sin(attore.timer * 0.1) * attore.ampiezza_oscillazione
107+
attore.x += attore.velocita_x + oscillazione
108+
attore.timer += 1
109+
110+
# Evita che escano dai bordi orizzontali
111+
if attore.x < 0:
112+
attore.x = 0
113+
attore.velocita_x = -attore.velocita_x
114+
if attore.x > LARGHEZZA:
115+
attore.x = LARGHEZZA
116+
attore.velocita_x = -attore.velocita_x
117+
118+
# Piccole variazioni casuali del movimento
119+
if random.random() < 0.01:
120+
attore.velocita_x = random.randint(-3, 3)
67121

68-
# Movimento orizzontale + oscillazione sinusoidale
69-
oscillazione = math.sin(s.timer * 0.1) * s.osc_amp
70-
s.x += s.vx + oscillazione
122+
# Gestione timer Sottosopra
123+
timer_sottosopra -= 1 / 60
124+
if timer_sottosopra <= 0:
125+
attiva_sottosopra()
126+
timer_sottosopra = random.randint(TEMPO_MIN_SOTTOSOPRA, TEMPO_MAX_SOTTOSOPRA)
71127

72-
s.timer += 1
73128

74-
# Rimbalzo ai bordi
75-
if s.x < 0:
76-
s.x = 0
77-
s.vx = -s.vx
78-
if s.x > WIDTH:
79-
s.x = WIDTH
80-
s.vx = -s.vx
129+
# GENERAZIONE PERSONAGGI
81130

82-
# Cambio direzione casuale ogni tanto
83-
if random.random() < 0.01:
84-
s.vx = random.randint(-3, 3)
85131

86-
# Se tocca il fondo → game over
87-
if s.y > HEIGHT:
88-
gestisci_game_over()
132+
def genera_personaggi_in_caduta(numero_extra):
133+
"""Genera il personaggio obiettivo + altri personaggi casuali."""
134+
lista_nomi = scegli_personaggi_livello(numero_extra)
135+
nuovi_attori = []
89136

137+
for nome in lista_nomi:
138+
attore = Actor(nome)
90139

91-
def genera_stelle(numero_extra):
92-
# lista: 1 target + numero_extra distrazioni
93-
lista = ottieni_personaggi_da_creare(numero_extra)
94-
nuove = []
140+
# Posizione iniziale X
141+
attore.x = random.randint(100, LARGHEZZA - 100)
95142

96-
for nome in lista:
97-
a = Actor(nome)
98-
a.x = random.randint(100, WIDTH - 100)
99-
a.y = -50
143+
# Posizione iniziale Y (alto o basso nel Sottosopra)
144+
attore.y = -50 if not modalita_sottosopra else ALTEZZA + 50
100145

101-
# velocità verticale
102-
a.vy = random.uniform(livello_corrente * 0.3, livello_corrente * 0.6)
146+
# Velocità verticale basata sul livello
147+
velocità_base = random.uniform(livello_corrente * 0.3, livello_corrente * 0.6)
148+
attore.velocita_y = velocità_base * (1.3 if modalita_sottosopra else 1)
103149

104-
# velocità orizzontale
105-
a.vx = random.randint(-3, 3)
150+
# Velocità orizzontale
151+
attore.velocita_x = random.randint(-3, 3)
106152

107-
# parametri oscillazione
108-
a.osc_amp = random.uniform(1, 4)
109-
a.timer = random.randint(0, 1000)
153+
# Oscillazione sinusoidale
154+
attore.ampiezza_oscillazione = random.uniform(1, 4)
155+
attore.timer = random.randint(0, 1000)
110156

111-
nuove.append(a)
157+
nuovi_attori.append(attore)
112158

113-
return nuove
159+
return nuovi_attori
114160

115161

116-
def ottieni_personaggi_da_creare(num_extra):
117-
lista = [personaggio_target]
118-
altri = [p for p in PERSONAGGI if p != personaggio_target]
162+
def scegli_personaggi_livello(num_extra):
163+
"""Ritorna il personaggio obiettivo + altri casuali."""
164+
lista = [personaggio_obiettivo]
165+
altri = [p for p in LISTA_PERSONAGGI if p != personaggio_obiettivo]
119166

120167
for _ in range(num_extra):
121168
lista.append(random.choice(altri))
122169

123170
return lista
124171

125172

126-
def on_mouse_down(pos):
127-
global selezione_iniziale, personaggio_target, livello_corrente, stelle
173+
# INPUT DEL MOUSE
174+
128175

129-
if selezione_iniziale:
130-
for p in personaggi_scelta:
131-
if p.collidepoint(pos):
132-
personaggio_target = p.image
133-
selezione_iniziale = False
176+
def on_mouse_down(pos):
177+
global fase_scelta_personaggio, personaggio_obiettivo, lista_personaggi_in_gioco
178+
179+
# Se siamo nella schermata di scelta
180+
if fase_scelta_personaggio:
181+
for attore in personaggi_da_selezionare:
182+
if attore.collidepoint(pos):
183+
personaggio_obiettivo = attore.image
184+
fase_scelta_personaggio = False
134185
return
135186

136-
for s in stelle:
137-
if s.collidepoint(pos):
138-
if s.image == personaggio_target:
139-
click_su_target()
187+
# Durante il gioco: verifica se si clicca il personaggio corretto
188+
for attore in lista_personaggi_in_gioco:
189+
if attore.collidepoint(pos):
190+
if attore.image == personaggio_obiettivo:
191+
avanza_livello()
140192
else:
141-
gestisci_game_over()
193+
attiva_game_over()
142194

143195

144-
def click_su_target():
145-
global livello_corrente, stelle, game_completato
196+
# LOGICA DI LIVELLO / GAME OVER
146197

147-
if livello_corrente == LIVELLO_FINALE:
148-
game_completato = True
198+
199+
def avanza_livello():
200+
"""Gestisce il passaggio al livello successivo."""
201+
global livello_corrente, lista_personaggi_in_gioco, gioco_completato
202+
203+
if livello_corrente == LIVELLO_MASSIMO:
204+
gioco_completato = True
149205
else:
150206
livello_corrente += 1
151-
stelle = []
207+
lista_personaggi_in_gioco = [] # per rigenerare i nuovi personaggi
208+
209+
210+
def attiva_game_over():
211+
"""Mostra la schermata di fallimento."""
212+
global gioco_terminato
213+
gioco_terminato = True
152214

153215

154-
def gestisci_game_over():
155-
global game_over
156-
game_over = True
216+
# INTERFACCIA UTENTE
157217

158218

159219
def mostra_messaggio(titolo, sottotitolo):
160-
screen.draw.text(titolo, fontsize=60, center=CENTRO, color=FONT_COLOR)
220+
screen.draw.text(titolo, fontsize=60, center=CENTRO, color=COLORE_TESTO)
161221
screen.draw.text(
162-
sottotitolo, fontsize=30, center=(CENTRO_X, CENTRO_Y + 30), color=FONT_COLOR
222+
sottotitolo,
223+
fontsize=30,
224+
center=(CENTRO_X, CENTRO_Y + 30),
225+
color=COLORE_TESTO,
163226
)
164227

165228

166-
def mostra_schermata_scelta():
167-
global personaggi_scelta
168-
personaggi_scelta = []
169-
distanza = WIDTH / (len(PERSONAGGI) + 1)
229+
# SOTTOSOPRA
230+
231+
232+
def attiva_sottosopra():
233+
"""Attiva/disattiva la modalità Sottosopra e modifica la fisica."""
234+
global modalita_sottosopra
235+
236+
modalita_sottosopra = not modalita_sottosopra
237+
238+
for attore in lista_personaggi_in_gioco:
239+
attore.velocita_y *= 1.25 # più veloce nel Sottosopra
240+
attore.y = ALTEZZA - attore.y # ribalta asse verticale
241+
242+
243+
# SCHERMATA DI SCELTA
244+
245+
246+
def mostra_schermata_scelta_personaggio():
247+
"""Genera i personaggi da cliccare nella schermata iniziale."""
248+
global personaggi_da_selezionare
249+
250+
personaggi_da_selezionare = []
251+
spaziatura = LARGHEZZA / (len(LISTA_PERSONAGGI) + 1)
252+
253+
for indice, nome in enumerate(LISTA_PERSONAGGI):
254+
attore = Actor(nome)
255+
attore.x = (indice + 1) * spaziatura
256+
attore.y = ALTEZZA / 2
257+
personaggi_da_selezionare.append(attore)
170258

171-
for i, nome in enumerate(PERSONAGGI):
172-
a = Actor(nome)
173-
a.x = (i + 1) * distanza
174-
a.y = HEIGHT / 2
175-
personaggi_scelta.append(a)
176259

260+
# Avvia schermata iniziale
261+
mostra_schermata_scelta_personaggio()
177262

178-
mostra_schermata_scelta()
263+
# Avvio del gioco Pygame Zero
179264
pgzrun.go()

0 commit comments

Comments
 (0)