From bb0b5256c1ccff43c50e9466a7b734e9780f44dc Mon Sep 17 00:00:00 2001 From: Spectre Date: Tue, 18 Feb 2025 15:40:50 +0100 Subject: [PATCH] Auto urgent commit. --- casse-brique/main.py | 307 ++++++++++++++++++++++++++--------------- casse-brique/pygame.py | 0 2 files changed, 198 insertions(+), 109 deletions(-) create mode 100644 casse-brique/pygame.py diff --git a/casse-brique/main.py b/casse-brique/main.py index 925cafd..41bf370 100644 --- a/casse-brique/main.py +++ b/casse-brique/main.py @@ -1,6 +1,7 @@ import pygame import sys import random +import math # Initialisation de Pygame pygame.init() @@ -17,125 +18,213 @@ RED = (255, 0, 0) # Création de la fenêtre de jeu screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) -pygame.display.set_caption("Casse-Brique") +pygame.display.set_caption("Casse-Brique Auto-Play") -# Paramètres de la raquette -PADDLE_WIDTH = 100 -PADDLE_HEIGHT = 15 -paddle_x = (SCREEN_WIDTH - PADDLE_WIDTH) / 2 # position horizontale centrée -paddle_y = SCREEN_HEIGHT - PADDLE_HEIGHT - 10 # position verticale (en bas) -paddle_speed = 7 - -# Paramètres de la balle -ball_radius = 10 -ball_x = SCREEN_WIDTH / 2 -ball_y = SCREEN_HEIGHT / 2 -# La balle part dans une direction aléatoire horizontalement -ball_speed_x = 9 * random.choice([-1, 1]) -ball_speed_y = -9 - -# Paramètres des briques -BRICK_ROWS = 5 # nombre de lignes de briques -BRICK_COLUMNS = 10 # nombre de colonnes de briques -BRICK_WIDTH = SCREEN_WIDTH // BRICK_COLUMNS -BRICK_HEIGHT = 20 -brick_padding = 5 - -# Création de la grille de briques sous forme de liste de listes -bricks = [] -for row in range(BRICK_ROWS): - brick_row = [] - for col in range(BRICK_COLUMNS): - # Calcul des coordonnées de la brique - brick_x = col * BRICK_WIDTH + brick_padding - brick_y = row * (BRICK_HEIGHT + brick_padding) + brick_padding - # On soustrait un peu de largeur pour le padding entre les briques - brick_rect = pygame.Rect(brick_x, brick_y, BRICK_WIDTH - brick_padding * 2, BRICK_HEIGHT) - brick_row.append(brick_rect) - bricks.append(brick_row) - -# Horloge pour contrôler le taux de rafraîchissement (FPS) clock = pygame.time.Clock() FPS = 100 -# Boucle principale du jeu -running = True -while running: - clock.tick(FPS) +# Fonction d'affichage du menu de démarrage +def show_menu(): + menu_running = True + title_font = pygame.font.SysFont("Arial", 72) + button_font = pygame.font.SysFont("Arial", 36) + button_width = 200 + button_height = 50 + button_rect = pygame.Rect(0, 0, button_width, button_height) + button_rect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2) - # Gestion des événements (fermeture de la fenêtre, etc.) - for event in pygame.event.get(): - if event.type == pygame.QUIT: + while menu_running: + clock.tick(FPS) + screen.fill(BLACK) + + # Affichage du titre + title_surface = title_font.render("Casse-Brique", True, WHITE) + title_rect = title_surface.get_rect(center=(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 3)) + screen.blit(title_surface, title_rect) + + # Dessiner le bouton "Jouer" + pygame.draw.rect(screen, BLUE, button_rect) + button_text = button_font.render("Jouer", True, WHITE) + button_text_rect = button_text.get_rect(center=button_rect.center) + screen.blit(button_text, button_text_rect) + + # Gestion des événements du menu + for event in pygame.event.get(): + if event.type == pygame.QUIT: + pygame.quit() + sys.exit() + # Détection d'un clic sur le bouton "Jouer" + if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: + if button_rect.collidepoint(event.pos): + menu_running = False + + pygame.display.flip() + +# Fonction principale du jeu +def game_loop(): + # Paramètres de la raquette + PADDLE_WIDTH = 100 + PADDLE_HEIGHT = 15 + paddle_x = (SCREEN_WIDTH - PADDLE_WIDTH) / 2 # centré horizontalement + paddle_y = SCREEN_HEIGHT - PADDLE_HEIGHT - 10 # position verticale en bas + paddle_speed = 7 + + # Paramètres de la balle + ball_radius = 10 + # Liste de balles (initialement une seule) + balls = [{ + 'x': SCREEN_WIDTH / 2, + 'y': SCREEN_HEIGHT / 2, + 'radius': ball_radius, + 'speed_x': 9 * random.choice([-1, 1]), + 'speed_y': -9 + }] + + # Paramètres des briques + BRICK_ROWS = 5 # nombre de lignes de briques + BRICK_COLUMNS = 10 # nombre de colonnes de briques + BRICK_WIDTH = SCREEN_WIDTH // BRICK_COLUMNS + BRICK_HEIGHT = 20 + brick_padding = 5 + + # Création de la grille de briques (liste de listes) + bricks = [] + for row in range(BRICK_ROWS): + brick_row = [] + for col in range(BRICK_COLUMNS): + brick_x = col * BRICK_WIDTH + brick_padding + brick_y = row * (BRICK_HEIGHT + brick_padding) + brick_padding + brick_rect = pygame.Rect(brick_x, brick_y, BRICK_WIDTH - brick_padding * 2, BRICK_HEIGHT) + brick_row.append(brick_rect) + bricks.append(brick_row) + + running = True + while running: + clock.tick(FPS) + screen.fill(BLACK) + + # Gestion des événements + for event in pygame.event.get(): + if event.type == pygame.QUIT: + running = False + + # --- Déplacement automatique de la raquette --- + # On cherche une balle qui descend (speed_y > 0), sinon on prend la première balle + target_ball = None + for ball in balls: + if ball['speed_y'] > 0: + target_ball = ball + break + if target_ball is None: + target_ball = balls[0] + # Calcul du centre de la raquette + paddle_center = paddle_x + PADDLE_WIDTH / 2 + # Si le centre est trop à gauche ou à droite de la balle cible, on déplace la raquette + if paddle_center < target_ball['x'] - 5: + paddle_x += paddle_speed + elif paddle_center > target_ball['x'] + 5: + paddle_x -= paddle_speed + + # Limiter la raquette à l'intérieur de l'écran + paddle_x = max(0, min(paddle_x, SCREEN_WIDTH - PADDLE_WIDTH)) + # Création du rectangle de la raquette pour la collision + paddle_rect = pygame.Rect(paddle_x, paddle_y, PADDLE_WIDTH, PADDLE_HEIGHT) + + # Liste pour stocker les nouvelles balles créées lors des collisions avec la raquette + nouvelles_balles = [] + + # Mise à jour de la position des balles + for ball in balls: + ball['x'] += ball['speed_x'] + ball['y'] += ball['speed_y'] + + # Collision avec les murs latéraux + if ball['x'] - ball['radius'] <= 0 or ball['x'] + ball['radius'] >= SCREEN_WIDTH: + ball['speed_x'] *= -1 + + # Collision avec le haut de l'écran + if ball['y'] - ball['radius'] <= 0: + ball['speed_y'] *= -1 + + # Création du rectangle de la balle pour la détection des collisions + ball_rect = pygame.Rect(ball['x'] - ball['radius'], ball['y'] - ball['radius'], + ball['radius'] * 2, ball['radius'] * 2) + + # Collision entre la balle et la raquette (uniquement si la balle descend) + if ball_rect.colliderect(paddle_rect) and ball['speed_y'] > 0: + ball['speed_y'] *= -1 # Inversion de la vitesse verticale + offset = (ball['x'] - (paddle_x + PADDLE_WIDTH / 2)) / (PADDLE_WIDTH / 2) + ball['speed_x'] = 4 * offset + + # Création d'une nouvelle balle lors de la collision + new_ball = ball.copy() + new_ball['speed_x'] *= -1 + new_ball['speed_x'] += random.choice([-1, 1]) + nouvelles_balles.append(new_ball) + + # Collision entre la balle et les briques + hit_brick = None + for row in bricks: + for brick in row: + if brick and ball_rect.colliderect(brick): + hit_brick = brick + ball['speed_y'] *= -1 # Inversion de la vitesse verticale + break + if hit_brick: + row[row.index(hit_brick)] = None + break + + # Ajout des nouvelles balles générées + balls.extend(nouvelles_balles) + + # Gestion des collisions entre balles + for i in range(len(balls)): + for j in range(i + 1, len(balls)): + dx = balls[i]['x'] - balls[j]['x'] + dy = balls[i]['y'] - balls[j]['y'] + distance = math.sqrt(dx * dx + dy * dy) + if distance < balls[i]['radius'] + balls[j]['radius']: + # Échange des vitesses pour simuler une collision élastique + balls[i]['speed_x'], balls[j]['speed_x'] = balls[j]['speed_x'], balls[i]['speed_x'] + balls[i]['speed_y'], balls[j]['speed_y'] = balls[j]['speed_y'], balls[i]['speed_y'] + # Ajustement des positions pour éviter la superposition + overlap = balls[i]['radius'] + balls[j]['radius'] - distance + if distance != 0: + nx = dx / distance + ny = dy / distance + else: + nx, ny = 1, 0 + balls[i]['x'] += nx * overlap / 2 + balls[i]['y'] += ny * overlap / 2 + balls[j]['x'] -= nx * overlap / 2 + balls[j]['y'] -= ny * overlap / 2 + + # Suppression des balles qui sortent par le bas de l'écran + balls = [ball for ball in balls if ball['y'] - ball['radius'] <= SCREEN_HEIGHT] + if not balls: + print("Game Over!") running = False - # Gestion du mouvement de la raquette avec les touches fléchées gauche et droite - keys = pygame.key.get_pressed() - if keys[pygame.K_LEFT] and paddle_x > 0: - paddle_x -= paddle_speed - if keys[pygame.K_RIGHT] and paddle_x < SCREEN_WIDTH - PADDLE_WIDTH: - paddle_x += paddle_speed + # Dessiner la raquette + pygame.draw.rect(screen, BLUE, paddle_rect) - # Mise à jour de la position de la balle - ball_x += ball_speed_x - ball_y += ball_speed_y + # Dessiner les briques + for row in bricks: + for brick in row: + if brick: + pygame.draw.rect(screen, RED, brick) - # Gestion des collisions avec les murs latéraux - if ball_x - ball_radius <= 0 or ball_x + ball_radius >= SCREEN_WIDTH: - ball_speed_x *= -1 + # Dessiner les balles + for ball in balls: + pygame.draw.circle(screen, WHITE, (int(ball['x']), int(ball['y'])), ball['radius']) - # Collision avec le haut de la fenêtre - if ball_y - ball_radius <= 0: - ball_speed_y *= -1 + pygame.display.flip() - # Création des rectangles pour la raquette et la balle (pour la détection des collisions) - paddle_rect = pygame.Rect(paddle_x, paddle_y, PADDLE_WIDTH, PADDLE_HEIGHT) - ball_rect = pygame.Rect(ball_x - ball_radius, ball_y - ball_radius, ball_radius * 2, ball_radius * 2) + pygame.quit() + sys.exit() - # Collision entre la balle et la raquette - if ball_rect.colliderect(paddle_rect) and ball_speed_y > 0: - ball_speed_y *= -1 - # Ajustement de la direction de la balle en fonction de l'endroit où elle touche la raquette - offset = (ball_x - (paddle_x + PADDLE_WIDTH / 2)) / (PADDLE_WIDTH / 2) - ball_speed_x = 4 * offset - - # Gestion des collisions avec les briques - hit_brick = None - for row in bricks: - for brick in row: - if brick and ball_rect.colliderect(brick): - hit_brick = brick - # Inverser la direction verticale de la balle lors d'une collision avec une brique - ball_speed_y *= -1 - break - if hit_brick: - # Supprimer la brique touchée en la remplaçant par None - row[row.index(hit_brick)] = None - break - - # Vérification si la balle sort de l'écran (cas de défaite) - if ball_y - ball_radius > SCREEN_HEIGHT: - print("Game Over!") - running = False - - # Dessin de la scène - screen.fill(BLACK) - - # Dessiner la balle - pygame.draw.circle(screen, WHITE, (int(ball_x), int(ball_y)), ball_radius) - - # Dessiner la raquette - pygame.draw.rect(screen, BLUE, paddle_rect) - - # Dessiner les briques restantes - for row in bricks: - for brick in row: - if brick: - pygame.draw.rect(screen, RED, brick) - - # Actualiser l'affichage - pygame.display.flip() - -# Fermeture de Pygame et du programme -pygame.quit() -sys.exit() +# Programme principal +if __name__ == "__main__": + show_menu() # Afficher le menu de démarrage + game_loop() # Lancer le jeu diff --git a/casse-brique/pygame.py b/casse-brique/pygame.py new file mode 100644 index 0000000..e69de29