Vous rêvez de construire votre propre labyrinthe 3D et de vous perdre virtuellement sans risquer d’appeler les secours ? Bonne nouvelle ! Avec Python, c'est possible. Pour cela il existe 4 bibliothèques à installer avec pip.
Pygame
Pygame est une bibliothèque qui gère tout ce qui est fun : graphismes, sons, et interactions.
Numpy
Si vous avez toujours trouvé que les maths étaient votre ennemi juré, Numpy va changer votre vie. Cette bibliothèque permet de gérer des calculs complexes sans douleur (ou presque).
Math
La bibliothèque standard math vous aide à résoudre tous les problèmes trigonométriques liés à votre jeu. Cosinus, sinus et angles ne seront plus un mystère pour vous.
Time
Vous voulez chronométrer le temps que vous mettez pour vous échapper du labyrinthe ? Le module time est là pour ajouter une touche de suspense.
Bon, le jeu tourne en 118 lignes ! c'est presque rien non ? Le rendu est basique mais juste ce qu'il faut pour se faire une idée de comment fonctionne python pour faire un petit jeu. Pour se déplacer, il suffit d'utiliser les flèches du clavier.
Voici le code
import pygame
import math
import time
# Configuration de l'écran et du jeu
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FOV = math.pi / 3 # Champ de vision (Field of View)
NUM_RAYS = 120
MAX_DEPTH = 20
TEXTURE_SIZE = 64
MAP_SIZE = 10
# Définition du labyrinthe (1 = mur, 0 = espace libre, 2 = sortie)
maze = [
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 1, 1, 0, 1, 1, 0, 1],
[1, 0, 1, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 1, 0, 1, 1, 0, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 0, 1, 1, 1, 0, 1, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 0, 1, 1, 1, 1, 1, 0, 2, 1], # Sortie au point (8,8)
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
]
# Position et angle du joueur (entrée du labyrinthe)
player_pos = [1.5, 1.5]
player_angle = 0
player_speed = 0.1
rotation_speed = 0.05
# Initialisation de Pygame
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
clock = pygame.time.Clock()
font = pygame.font.Font(None, 36)
# Compte à rebours avant le départ
for count in range(3, 0, -1):
screen.fill((0, 0, 0))
text = font.render(f'{count}...', True, (255, 255, 255))
screen.blit(text, (SCREEN_WIDTH // 2 - 50, SCREEN_HEIGHT // 2))
pygame.display.flip()
time.sleep(1)
screen.fill((0, 0, 0))
text = font.render('Find the exit!', True, (255, 255, 255))
screen.blit(text, (SCREEN_WIDTH // 2 - 100, SCREEN_HEIGHT // 2))
pygame.display.flip()
time.sleep(1)
start_time = time.time()
# Fonction de rendu des rayons pour simuler la 3D
def cast_rays():
for i in range(NUM_RAYS):
angle = player_angle - (FOV / 2) + (i / NUM_RAYS) * FOV
sin_a = math.sin(angle)
cos_a = math.cos(angle)
dist = 0
while dist < MAX_DEPTH:
x = int(player_pos[0] + dist * cos_a)
y = int(player_pos[1] + dist * sin_a)
if maze[y][x] == 1:
break
dist += 0.05
depth_correction = dist * math.cos(player_angle - angle)
wall_height = int(TEXTURE_SIZE / (depth_correction + 0.0001) * 5)
color = 255 / (1 + dist * dist * 0.1)
if maze[y][x] == 2:
pygame.draw.rect(screen, (0, 255, 0), (i * (SCREEN_WIDTH / NUM_RAYS), SCREEN_HEIGHT//2 - wall_height // 2, SCREEN_WIDTH / NUM_RAYS, wall_height))
else:
pygame.draw.rect(screen, (color, color, color), (i * (SCREEN_WIDTH / NUM_RAYS), SCREEN_HEIGHT//2 - wall_height // 2, SCREEN_WIDTH / NUM_RAYS, wall_height))
# Boucle principale du jeu
running = True
while running:
screen.fill((0, 0, 0))
cast_rays()
# Vérification de la sortie
if int(player_pos[0]) == 8 and int(player_pos[1]) == 8:
end_time = time.time()
elapsed_time = end_time - start_time
screen.fill((0, 0, 0))
text = font.render(f'You escaped in {elapsed_time:.2f} seconds!', True, (0, 255, 0))
screen.blit(text, (SCREEN_WIDTH // 2 - 200, SCREEN_HEIGHT // 2))
pygame.display.flip()
pygame.time.delay(5000)
running = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player_angle -= rotation_speed
if keys[pygame.K_RIGHT]:
player_angle += rotation_speed
if keys[pygame.K_UP]:
new_x = player_pos[0] + player_speed * math.cos(player_angle)
new_y = player_pos[1] + player_speed * math.sin(player_angle)
if maze[int(new_y)][int(new_x)] == 0 or maze[int(new_y)][int(new_x)] == 2:
player_pos[0] = new_x
player_pos[1] = new_y
if keys[pygame.K_DOWN]:
new_x = player_pos[0] - player_speed * math.cos(player_angle)
new_y = player_pos[1] - player_speed * math.sin(player_angle)
if maze[int(new_y)][int(new_x)] == 0:
player_pos[0] = new_x
player_pos[1] = new_y
pygame.display.flip()
clock.tick(60)
pygame.quit()