In basso allego tutto il codice, il problema è presto detto, ma apparentemente di difficile soluzione: dopo la collisione, rilanciando il gioco, riappare l'ultimo ostacolo contro il quale è sbattuto il personaggio. Se è sui lati scorre via senza problemi, ma se l'ostacolo è in mezzo allo schermo avviene subito una nuova collisione e il programma si blocca. ChatGPT ha proposto varie soluzioni per cancellare tutti gli ostacoli, senza successo. Qui il punto incriminato:
- Codice: Seleziona tutto
new_obstacles = []
for x, y in obstacles:
y += 5 - ferma
if y < HEIGHT:
new_obstacles.append((x, y))
draw_tree(x, y)
if check_mask_collision(player_x, player_y, x, y, player_masks[player_image_key], tree_mask):
obstacles = []
save_score(sciatore_nome, guida_nome, score)
partenza = "left"
choice = end_game_screen()
if choice == "new_names":
sciatore_nome, guida_nome = input_names()
reset_game()
break
else:
score += 1
obstacles = new_obstacles
anche con obstacles.clear() e altro, non scompare.
Qui tutto il codice (sul PC ho le immagini 4 per il personaggio e 2 per il bambino) e il file punteggio.csv
- Codice: Seleziona tutto
import pygame
import random
import sys
import csv
from datetime import datetime
# Inizializza Pygame
pygame.init()
# Dimensioni finestra di gioco
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Simulatore di sci con i ciechi")
# Colori
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 128, 0)
BLUE = (0, 0, 255)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
LIGHT_BLUE = (173, 216, 230) # Colore per le cunette
# Clock
clock = pygame.time.Clock()
# Font
font = pygame.font.Font(None, 36)
# Caricamento immagini
try:
player_images = {
"right": pygame.image.load("DerapDes.gif"),
"left": pygame.image.load("DerapSin.gif"),
"fast_right": pygame.image.load("CarvDes.gif"),
"fast_left": pygame.image.load("CarvSin.gif"),
}
bambino_images = {
"right": pygame.image.load("SpazzDes.gif"),
"left": pygame.image.load("SpazzSin.gif"),
}
except pygame.error as e:
print("Errore nel caricamento delle immagini:", e)
pygame.quit()
sys.exit()
# Maschere immagini
player_masks = {
"right": pygame.mask.from_surface(player_images["right"]),
"left": pygame.mask.from_surface(player_images["left"]),
"fast_right": pygame.mask.from_surface(player_images["fast_right"]),
"fast_left": pygame.mask.from_surface(player_images["fast_left"]),
}
bambino_masks = {
"right": pygame.mask.from_surface(bambino_images["right"]),
"left": pygame.mask.from_surface(bambino_images["left"]),
}
# Caratteristiche del personaggio
player_width = 90
player_height = 90
player_x = WIDTH // 2
player_y = HEIGHT - 150
player_speed = 3
partenza = random.choice(["right", "left"])
player_direction = partenza
# Caratteristiche degli ostacoli e cunette
obstacles = []
cunette = []
ferma = 0
ferma2 = 0
bambino = None
TApp = 3000 # Millisecondi
DeltaTApp = 100 # Riduzione del tempo TApp
last_obstacle_time = pygame.time.get_ticks()
# Punteggio
score = 0
# Input iniziale per nome sciatore e guida
def input_names():
sciatore = ""
guida = ""
active = "sciatore"
while True:
screen.fill(WHITE)
draw_text("Inserisci il nome dello sciatore:", 50, 100, BLACK)
draw_text(f"Sciatore: {sciatore}", 50, 150, BLUE)
draw_text("Inserisci il nome della guida:", 50, 250, BLACK)
draw_text(f"Guida: {guida}", 50, 300, BLUE)
draw_text("Muovi lo sciatore con le frecce destra e sinistra.", 50, 400, BLACK)
draw_text("Tenendo premuto il tasto esso si muoverà più veloce.", 50, 430, BLACK)
draw_text("Evita gli ostacoli e i bordi.", 50, 460, BLACK)
draw_text("Premi INVIO per iniziare.", 50, 500, RED)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN and sciatore and guida:
countdown()
return sciatore, guida
if event.key == pygame.K_BACKSPACE:
if active == "sciatore" and sciatore:
sciatore = sciatore[:-1]
elif active == "guida" and guida:
guida = guida[:-1]
elif event.key == pygame.K_TAB:
active = "guida" if active == "sciatore" else "sciatore"
else:
if active == "sciatore":
sciatore += event.unicode
elif active == "guida":
guida += event.unicode
pygame.display.flip()
def countdown():
"""Mostra un conto alla rovescia prima dell'inizio del gioco."""
for i in range(3, 0, -1):
screen.fill(WHITE)
draw_text(str(i), WIDTH // 2, HEIGHT // 2, RED, 100)
pygame.display.flip()
pygame.time.delay(1000)
def draw_text(text, x, y, color=BLACK, size=36):
font = pygame.font.Font(None, size)
text_surface = font.render(text, True, color)
screen.blit(text_surface, (x, y))
def draw_cunetta(x, y):
pygame.draw.arc(screen, LIGHT_BLUE, (x, y, 40, 20), 0, 3.14, 3)
def draw_tree(x, y):
pygame.draw.rect(screen, GREEN, (x + 15, y + 70, 10, 15)) # Tronco
pygame.draw.polygon(screen, GREEN, [(x, y + 70), (x + 40, y + 70), (x + 20, y + 35)]) # Base
pygame.draw.polygon(screen, GREEN, [(x + 5, y + 55), (x + 35, y + 55), (x + 20, y + 25)]) # Centro
pygame.draw.polygon(screen, GREEN, [(x + 10, y + 40), (x + 30, y + 40), (x + 20, y + 10)]) # Punta
# Creazione di una maschera per l'albero (poligono)
tree_mask_surface = pygame.Surface((40, 70), pygame.SRCALPHA)
pygame.draw.polygon(tree_mask_surface, (255, 255, 255), [(0, 60), (20, 10), (40, 60)]) # Forma triangolare
tree_mask = pygame.mask.from_surface(tree_mask_surface)
# Verifica se le maschere si sovrappongono
def check_mask_collision(player_x, player_y, obstacle_x, obstacle_y, mask1, mask2):
offset_x = obstacle_x - player_x
offset_y = obstacle_y - player_y
return mask1.overlap(mask2, (offset_x, offset_y))
def save_score(sciatore, guida, score):
with open("punteggio.csv", "a", newline="") as csvfile:
writer = csv.writer(csvfile)
writer.writerow([sciatore, guida, datetime.now().strftime("%Y-%m-%d %H:%M:%S"), score])
def reset_game():
global player_x, player_direction, obstacles, cunette, score, TApp, last_obstacle_time, bambino
player_x = WIDTH // 2
player_direction = partenza
obstacles.clear() # Svuota completamente la lista degli ostacoli
# Pulisci lo schermo per rimuovere residui visivi
screen.fill(WHITE)
pygame.display.flip()
pygame.event.clear() # Pulisce la coda degli eventi per evitare input residui
cunette = [(random.randint(0, WIDTH - 40), random.randint(-HEIGHT, HEIGHT // 2)) for _ in range(10)]
bambino = None
score = 0
TApp = 3000
last_obstacle_time = pygame.time.get_ticks()
def end_game_screen():
while True:
screen.fill(WHITE)
draw_text("Partita Terminata!", WIDTH // 2 - 150, HEIGHT // 2 - 100, RED, 48)
draw_text(f"Punteggio: {score}", WIDTH // 2 - 80, HEIGHT // 2 - 40, BLACK, 36)
draw_text("1: Riprova", WIDTH // 2 - 100, HEIGHT // 2 + 40, BLUE, 28)
draw_text("2: Scegli nuovi nomi", WIDTH // 2 - 100, HEIGHT // 2 + 80, BLUE, 28)
draw_text("3: Esci", WIDTH // 2 - 100, HEIGHT // 2 + 120, BLUE, 28)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
obstacles = []
reset_game()
return "restart"
elif event.key == pygame.K_2:
return "new_names"
elif event.key == pygame.K_3:
pygame.quit()
sys.exit()
pygame.display.flip()
def move_bambino(bambino):
x, y, direction = bambino
y += 2 - ferma
if random.random() < 0.02:
direction = "right" if direction == "left" else "left"
if direction == "right":
x = min(WIDTH - 30, x + 1)
else:
x = max(0, x - 1)
return (x, y, direction)
sciatore_nome, guida_nome = input_names()
reset_game()
running = True
while running:
screen.fill(WHITE)
for event in pygame.event.get():
if event.type == pygame.QUIT:
save_score(sciatore_nome, guida_nome, score)
pygame.quit()
sys.exit()
# Movimento personaggio
keys = pygame.key.get_pressed()
if player_direction == "right":
player_x += 3 - ferma2 if not keys[pygame.K_RIGHT] else 12
else:
player_x -= 3 - ferma2 if not keys[pygame.K_LEFT] else 12
if keys[pygame.K_LEFT] and player_direction == "right":
player_direction = "left"
ferma = 0
ferma2 = 0
elif keys[pygame.K_RIGHT] and player_direction == "left":
player_direction = "right"
ferma = 0
ferma2 = 0
elif keys[pygame.K_DOWN] :
ferma = 5
ferma2 = 3
score = score - 1
if player_x <= 0 or player_x + player_width >= WIDTH:
save_score(sciatore_nome, guida_nome, score)
choice = end_game_screen()
if choice == "new_names":
sciatore_nome, guida_nome = input_names()
reset_game()
continue
current_time = pygame.time.get_ticks()
if current_time - last_obstacle_time > TApp and ferma ==0:
obstacles.append((random.randint(0, WIDTH - 30), -60))
last_obstacle_time = current_time
TApp = max(500, TApp - DeltaTApp)
if bambino is None and random.random() < 0.01:
bambino = (random.randint(0, WIDTH - 30), -60, "right")
cunette = [(x, y + 5 - ferma) if y < HEIGHT else (random.randint(0, WIDTH - 40), -20) for x, y in cunette]
for x, y in cunette:
draw_cunetta(x, y)
new_obstacles = []
for x, y in obstacles:
y += 5 - ferma
if y < HEIGHT:
new_obstacles.append((x, y))
draw_tree(x, y)
if check_mask_collision(player_x, player_y, x, y, player_masks[player_image_key], tree_mask):
obstacles = []
save_score(sciatore_nome, guida_nome, score)
partenza = "left"
choice = end_game_screen()
if choice == "new_names":
sciatore_nome, guida_nome = input_names()
reset_game()
break
else:
score += 1
obstacles = new_obstacles
if bambino:
bambino = move_bambino(bambino)
bx, by, bdir = bambino
screen.blit(bambino_images[bdir], (bx, by))
if pygame.Rect(player_x, player_y, player_width, player_height).colliderect((bx, by, 50, 50)):
save_score(sciatore_nome, guida_nome, score)
choice = end_game_screen()
if choice == "new_names":
sciatore_nome, guida_nome = input_names()
reset_game()
continue
if by > HEIGHT:
bambino = None
# Disegna il personaggio
player_image_key = "fast_right" if keys[pygame.K_RIGHT] else "fast_left" if keys[pygame.K_LEFT] else player_direction
screen.blit(player_images[player_image_key], (player_x, player_y))
draw_text(f"Punteggio: {score}", 10, 10)
pygame.display.flip()
clock.tick(30)