PAC-MAN est un jeu vidéo d'arcade emblématique créé par Tōru Iwatani et publié par Namco en 1980. Il est devenu l’un des jeux les plus populaires de l’histoire du jeu vidéo grâce à son gameplay simple, addictif et son design unique.
Le joueur contrôle PAC-MAN, un personnage jaune en forme de cercle partiellement ouvert, qui doit :
Manger tous les points (appelés pac-dots) dispersés dans un labyrinthe.
Éviter les fantômes qui patrouillent le labyrinthe et essaient de le capturer.
Gagner des points en collectant des pac-dots, des fruits bonus, et en mangeant des fantômes sous certaines conditions.
Ce projet consiste à recréer le célèbre jeu PAC-MAN, adapté pour être contrôlé par une carte ESP32, affiché sur un écran LCD I2C, et joué à l'aide d'une manette (joystick ou boutons). Voici les éléments clés du gameplay, des fonctionnalités, et de la logique du jeu :
Objectif : Contrôler PAC-MAN pour collecter tous les points (ou "pac-dots") dans le labyrinthe tout en évitant les fantômes.
Conditions de Victoire : Collecter tous les points sans se faire attraper par un fantôme.
Conditions de Défaite : Si PAC-MAN est touché par un fantôme sans avoir mangé de super-capsule (power pellet).
Logique du Jeu (gérée par l’ESP32) :
1- Lire les entrées de la manette.
2- Mettre à jour la position de PAC-MAN.
3- Déplacer les fantômes avec des comportements définis (aléatoires ou semi-intelligents).
4- Détecter les collisions (PAC-MAN/fantômes, PAC-MAN/murs, PAC-MAN/points).
5- Mettre à jour l’écran LCD.
6- Jouer des sons via le buzzer (manger des points, danger, etc.).
Carte ESP32
La carte ESP32 est le cerveau du système, elle exécute le code du jeu, gère la logique de PAC-MAN, les déplacements des fantômes, la détection des collisions, etc.
Afficheur LCD I2C
L'écran LCD affiche du labyrinthe de PAC-MAN, des personnages, des points à collecter etc.
Manette (Joystick ou Boutons de Direction)
La manette contrôle des déplacements de PAC-MAN (haut, bas, gauche, droite).
Buzzer
Le buzzer génére des Effets sonores (bruits de PAC-MAN mangeant des points, sons de collision, etc.).
Câble de connexion
Vous aurez besoin d'un câble pour connecter l'afficheur LCD et la manette (Joystick) à la carte ESP32.
Plaque d'essai (Breadboard) :
On utilise la plaque d'essai pour faciliter le câblage des différents composants.
1- Joystick :
Connecter les axes X et Y aux entrées analogiques de la carte ESP32 (exemple : GPIO34
et GPIO35
).
Connecter le bouton poussoir (si utilisé) à une entrée de la carte ESP32 (exemple GPIO33
).
Connecter la broche 5V
à la broche 3V3
de la carte ESP32.
Connecter la broche GND
à la broche GND
de la carte ESP32.
2- Afficheur LCD :
Si un module I2C est utilisé, connecter les broches :
SCL
→ GPIO22(ESP32)
SDA
→ GPIO21(ESP32)
VCC
→ 5V(ESP32)
GND
→ GND(ESP32)
3- Buzzer :
Connecter la broche (+)
à la broche GPIO23
de la carte ESP32.
Connecter la broche (-)
à la broche GND
de la carte ESP32.
Voici un programme en MicroPython pour un jeu PAC-MAN simplifié, conçu pour une carte ESP32, une manette (joystick ou boutons), et un afficheur LCD I2C.
1- vous devez disposer d'un environnement MicroPython installé sur votre ESP32.
2- Flashez votre ESP32 avec MicroPython en utilisant Firmware esp32-20210902-v1.17.bin.
3- Importer les bibliothèques "i2c_lcd" et "lcd_api" dédiées à l'écran LCD I2C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
from machine import Pin, I2C, ADC, PWM from time import sleep from lcd_api import LcdApi from i2c_lcd import I2cLcd import random # === Configuration de l'afficheur LCD I2C === I2C_ADDR = 0x27 # Adresse I2C de l'écran LCD I2C_SCL = 22 # Broche SCL de l'ESP32 I2C_SDA = 21 # Broche SDA de l'ESP32 # Initialisation de l'I2C et du LCD i2c = I2C(0, scl=Pin(I2C_SCL), sda=Pin(I2C_SDA), freq=400000) lcd = I2cLcd(i2c, I2C_ADDR, 4, 20) # Écran 20x4 # === Configuration du joystick === joystick_x = ADC(Pin(34)) # Axe X du joystick joystick_y = ADC(Pin(35)) # Axe Y du joystick joystick_btn = Pin(33, Pin.IN, Pin.PULL_UP) # Bouton intégré du joystick # Calibration du joystick joystick_x.atten(ADC.ATTN_11DB) joystick_y.atten(ADC.ATTN_11DB) # === Configuration du buzzer === buzzer = PWM(Pin(23)) # === Labyrinthe Simplifié === maze = [ "####################", "#........#.........#", "#.####.#.#.####.#..#", "#.................#", "####################" ] # Position initiale de PAC-MAN et du fantôme pacman_x = 1 pacman_y = 1 ghost_x = 18 ghost_y = 3 # Score score = 0 # === Fonctions === def play_sound(frequency, duration): buzzer.freq(frequency) buzzer.duty(512) # Volume sleep(duration) buzzer.duty(0) def display_maze(): lcd.clear() for row in range(4): lcd.move_to(0, row) lcd.putstr(maze[row][:20]) # Afficher PAC-MAN lcd.move_to(pacman_x, pacman_y) lcd.putstr("P") # Afficher le fantôme lcd.move_to(ghost_x, ghost_y) lcd.putstr("G") # Afficher le score lcd.move_to(0, 3) lcd.putstr(f"Score: {score}") def move_pacman(dx, dy): global pacman_x, pacman_y, score new_x = pacman_x + dx new_y = pacman_y + dy # Vérification des collisions avec les murs if maze[new_y][new_x] != '#': if maze[new_y][new_x] == '.': score += 10 # Gagner des points en mangeant des points play_sound(1000, 0.1) # Son pour collecter des points maze[new_y] = maze[new_y][:new_x] + ' ' + maze[new_y][new_x+1:] pacman_x, pacman_y = new_x, new_y def move_ghost(): global ghost_x, ghost_y directions = [(0,1), (0,-1), (1,0), (-1,0)] random.shuffle(directions) for dx, dy in directions: new_x = ghost_x + dx new_y = ghost_y + dy if maze[new_y][new_x] != '#': ghost_x, ghost_y = new_x, new_y break def read_joystick(): x_val = joystick_x.read() y_val = joystick_y.read() threshold = 2000 # Seuil de sensibilité dx = 0 dy = 0 if x_val < 1000: dx = -1 # Gauche elif x_val > 3000: dx = 1 # Droite if y_val < 1000: dy = -1 # Haut elif y_val > 3000: dy = 1 # Bas return dx, dy # === Boucle principale === display_maze() while True: dx, dy = read_joystick() if dx != 0 or dy != 0: move_pacman(dx, dy) move_ghost() display_maze() sleep(0.3) # Vérifier la collision avec le fantôme if pacman_x == ghost_x and pacman_y == ghost_y: play_sound(200, 0.5) # Son de fin de partie lcd.clear() lcd.putstr("Game Over!") lcd.move_to(0, 1) lcd.putstr(f"Score: {score}") break |
Explication du Code
1- Initialisation de l’écran LCD :
1 2 3 |
I2C_ADDR = 0x27 i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000) lcd = I2cLcd(i2c, I2C_ADDR, 4, 20) |
L’écran est configuré en mode I2C avec l’adresse 0x27
.
L’écran est un modèle 20x4 caractères.
2- Joystick :
1 2 3 |
joystick_x = ADC(Pin(34)) joystick_y = ADC(Pin(35)) joystick_btn = Pin(33, Pin.IN, Pin.PULL_UP) |
La manette (Joystick) lit les mouvements horizontaux et verticaux pour contrôler PAC-MAN.
3- Buzzer :
1 |
buzzer = PWM(Pin(23)) |
Le Buzzer produit des sons pour les interactions importantes : points collectés ou fin de partie.
4- Création du Labyrinthe
1 2 3 4 5 6 7 |
maze = [ "####################", "#........#.........#", "#.####.#.#.####.#..#", "#.................#", "####################" ] |
Le labyrinthe est représenté par des chaînes de caractères :
#
= murs
.
= points à collecter
5- Déplacement de PAC-MAN
Lecture du joystick :
1 2 3 |
def read_joystick(): x_val = joystick_x.read() y_val = joystick_y.read() |
La carte ESP32 détecte les mouvements dans 4 directions : haut, bas, gauche, droite.
Mise à jour de la position :
1 2 3 4 5 |
def move_pacman(dx, dy): if maze[new_y][new_x] != '#': if maze[new_y][new_x] == '.': score += 10 play_sound(1000, 0.1) |
La carte ESP32 vérifie les collisions avec les murs (#
). Si PAC-MAN trouve un point (.
), il le mange (+10 points) avec un bip sonore.
6- Mouvement des Fantômes
1 2 3 |
def move_ghost(): directions = [(0,1), (0,-1), (1,0), (-1,0)] random.shuffle(directions) |
Les fantômes se déplacent aléatoirement dans des directions valides sans traverser les murs.
7- Affichage et Score
1 2 |
lcd.move_to(0, 3) lcd.putstr(f"Score: {score}") |
Le score s'affiche sur la dernière ligne de l’écran LCD, mis à jour après chaque mouvement.
8- Conditions de Fin de Partie
1 2 3 |
if pacman_x == ghost_x and pacman_y == ghost_y: play_sound(200, 0.5) lcd.putstr("Game Over!") |
Si PAC-MAN touche un fantôme, un son d'alerte retentit et le jeu s’arrête. Le score final est affiché.
9. Gestion des Sons (Buzzer)
1 2 3 4 5 |
def play_sound(frequency, duration): buzzer.freq(frequency) buzzer.duty(512) sleep(duration) buzzer.duty(0) |
- Collecte de points : Bip aigu (1000 Hz, 0.1 sec)
- Game Over : Son grave (200 Hz, 0.5 sec)
La robotique éducative joue un rôle important dans l'éducation des enfants et des jeunes en les aidant à acquérir des compétences en science et technologie.
Dans ce cadre notre site web représente une excellente ressource pour les parents, les enseignants et les enfants qui souhaitent découvrir la robotique.
Zaouiet Kontech-Jemmel-Monastir-Tunisie
+216 92 886 231
medaliprof@gmail.com
Site robotique réalisé par Mohamed Ali-Prof Info