IV-A. Importation et Initialisation▲
Au niveau des importations, en général, on se contente de celles qui suivent:
import pygame
import pygame.image
from pygame.locals import *
pygame.init()
pygame.font.init()L'écran du jeu est créé par la fonction pygame.display.set_mode((largeur, hauteur)). On peut aussi changer le titre de la fenêtre par l'instruction pygame.display.set_caption(MonTitre)
screen = pygame.display.set_mode((768, 544))
pygame.display.set_caption("Oh Mummy")IV-B. Chargement des images▲
Pour charger une image, il suffit d'appeler la fonction pygame.image.load(imagepath). J'ai décidé pour plus de clareté de charger toutes mes images dans un dictionnaire ImageOhMummy.
- ImageOhMummy['Gargou'] contient les différentes positions que le héros peut prendre
- ImageOhMummy['Mummy'] contient les différentes positions qu'une momie peut prendre
- ImageOhMummy['GuardianMummy'] contient la séquence d'apparition de la momie cachée
- ImageOhMummy['Trace'] contient les différentes traces que peut laisser le héros sur le sol
- ImageOhMummy['Box'] contient les différentes découvertes que le héros peut faire
- ImageOhMummy['Chiffre'] contient les chiffres pour afficher le score
- ImageOhMummy['ChiffreScroll'] contient les chiffres pour afficher le score quand le héros possède le parchemin
ImageOhMummy = {}
ImageOhMummy['Gargou'] = {}
ImageOhMummy['Gargou']['Left'] = pygame.image.load("./Image/GargouLeft.png")
...
ImageOhMummy['Mummy'] = {}
ImageOhMummy['Mummy']['Left'] = pygame.image.load("./Image/MummyLeft.png")
...
ImageOhMummy['GuardianMummy'] = {}
for i in range(1, 17):
ImageOhMummy['GuardianMummy'][i] = pygame.image.load("./Image/GuardianMummy"+str(i)+".png")
...
ImageOhMummy['Trace'] = {}
ImageOhMummy['Trace']['None'] = pygame.image.load("./Image/TraceNone.png")
ImageOhMummy['Trace']['LeftDown'] = pygame.image.load("./Image/TraceLeftDown.png")
...
ImageOhMummy['Box'] = {}
ImageOhMummy['Box']['RoyalMummy'] = pygame.image.load("./Image/RoyalMummy.png")
...
ImageOhMummy['Chiffre'] = {}
ImageOhMummy['ChiffreScroll'] = {}
ImageOhMummy['Score'] = pygame.image.load("./Image/Score.png")
ImageOhMummy['Men'] = pygame.image.load("./Image/Men.png")
ImageOhMummy['EndLife'] = pygame.image.load("./Image/EndLife.png")
ImageOhMummy['End200'] = pygame.image.load("./Image/End200.png")
ImageOhMummy['GameOver'] = pygame.image.load("./Image/GameOver.png")
for i in range(10):
ImageOhMummy['Chiffre'][i] = pygame.image.load('./Image/Chiffre'+str(i)+".png")
ImageOhMummy['ChiffreScroll'][i] = pygame.image.load('./Image/ChiffreScroll'+str(i)+".png")IV-C. Les différentes classes▲
IV-C-1. Base commune des classes▲
Les différentes classes présentées à la suite ont toutes une base commune. Tout d'abord, elles dérivent toutes
de la classe pygame.sprite.Sprite. De ce que j'en ai compris, cette classe permet de définir un objet
visuable à l'écran. La dérivation se fait de la manière suivante:
pygame.sprite.Sprite.__init__(self, self.containers) où self.containers est un tuple contenant
les groupes de sprites (dans notre cas des RenderUpdates (cf la fonction main()))
Dans la création de la classe, il y a ensuite 2 attributs à définir obligatoirement:
L'attribut image contient l'image de votre objet. Il peut par exemple correspondre à une image préalablement chargée
ou bien à une surface vide (pygame.Surface((largeur, hauteur))) que l'on pourra remplir avec la méthode fill(R, G, B) ou
blit(img, (x, y)).
L'attribut rect définit en général le rectangle englobant image. On se contente en général
de le créer de la façon suivante: self.rect = self.image.get_rect().
On pourra ensuite positionner ce rectangle dans la scène en modifiant par exemple les attributs top et left de rect.
Enfin, pour détruire un objet dérivant de la classe pygame.sprite.Sprite, il suffira de lui appliquer la méthode kill().
IV-C-2. Classe Gargou▲

La classe Gargou permet de gérer le héros.
Les attributs x et y donne la position de héros dans le tableau représentant
le plateau (cf la classe Plate). Le personnage prenant 4 cases de ce tableau, les composantes x et y
correspondent à la position en haut à gauche du héros.
L'attribut facing donne le sens dans laquelle se déplace le héros (0: à droite, 1: en haut,
2: à gauche, 3: en bas). L'attribut moving gère les 2 positions possibles pour chaque sens de déplacement.
La fonction move gère le déplacement du personnage en fonction de la flèche sur laquelle vous avez appuyé. La fonction
vérifie tout d'abord la validité du déplacement. Chaque fois que le personnage effectue un déplacement valide, il laisse derrière lui une trace de pas qui va permettre
de dégager les boîtes. Cela sera géré par l'appel à PLATE.Update(...).
A chaque déplacement, en fonction de la valeur des attributs facing et moving, on
met à jour l'attribut image par l'image correspondante.
Enfin, l'attribut level donne le niveau du héros et permet de définir l'algorithme de déplacement
des momies. A chaque fois que le héros finit la série des 5 niveaux d'une pyramide, cet attribut augmente de 1.
Quand le héros a récupéré la clé et les restes de la momie, il peut changer de niveau en remontant à l'entrée initiale
( condition à vérifier: PLATE.Key and PLATE.RoyalMummy and self.x == 15 and self.y == 1 )
Une unique instance de cette classe est créée et est globale au jeu nommée GARGOU
class Gargou(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self, self.containers)
self.image = ImageOhMummy['Gargou']['MoveDownRight']
self.rect = self.image.get_rect()
self.x = 15
self.y = 1
self.facing = 0
self.moving = 0
self.rect.left = 320
self.rect.top = 94
self.level = 1
def move(self, direction):
try: direct = direction.index(1)
except: return
self.facing = direct
x = self.x; y = self.y
if direct == 0: x = self.x + 1
elif direct == 1: y = self.y - 1
elif direct == 2: x = self.x - 1
elif direct == 3: y = self.y + 1
if PLATE.plate[y][x] == PLATE.plate[y][x+1] == PLATE.plate[y+1][x] == PLATE.plate[y+1][x+1] == 1:
self.x = x
self.y = y
else: return
PLATE.Update(self.x, self.y, self.facing, self.moving)
if PLATE.Key and PLATE.RoyalMummy and self.x == 15 and self.y == 1:
PLATE.Level = max(1, (PLATE.Level + 1) % 6)
PLATE.ChangeLevel = True
self.moving = (self.moving + 1) % 2
self.image = ImageOhMummy['Gargou']['Face'][2 * self.facing + self.moving]
self.rect.left = 80 + 16 * self.x
self.rect.top = 78 + 16 * self.yIV-C-3. Classe Life▲

La classe Life permet de gérer à la fois le nombre restant de vies du héros et son affichage à l'écran.
La fonction Update permet de réafficher à l'écran les vies restantes du héros quand ce nombre change.
Une seule instance de cette classe sera créée en tant que variable globale et nommée LIFE pour une manipulation
plus aisée.
class Life(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self, self.containers)
self.life = 5 ## Le héros démarre avec 5 vies
self.image = pygame.Surface((320, 32))
self.rect = self.image.get_rect()
self.rect.top = 78
self.rect.left = 416
def Update(self):
self.image.fill((255, 255, 0))
self.image.blit(ImageOhMummy['Men'], (0, 0))
for i in range(0, self.life, 2):
self.image.blit(ImageOhMummy['Gargou']['MoveRight'], (64 + 32* i, 0))
for i in range(1, self.life, 2):
self.image.blit(ImageOhMummy['Gargou']['Right'], (64 + 32* i, 0))IV-C-4. Classe Score▲

La classe Score permet de gérer le score du héros ainsi que son affichage à l'écran. Il y a de même
une unique fonction Update appelée chaque fois que le score change. Si le héros a découvert le parchemin
et qu'il ne l'a pas encore utilisé, le score est affiché en inversant les couleurs jaune et bleu.
Une seule instance de cette classe sera créée en tant que variable globale et nommée SCORE pour une manipulation
plus aisée.
class Score(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self, self.containers)
self.score = 0
self.image = pygame.Surface((176, 16))
self.image.fill((255, 255, 0))
self.rect = self.image.get_rect()
self.rect.top = 78
self.rect.left = 96
self.image.blit(ImageOhMummy['Score'], (0, 0))
for i in range(5):
self.image.blit(ImageOhMummy['Chiffre'][0], (96 + 16* i, 0))
def Update(self):
scorestr = str(self.score).zfill(5) ## Récupération du score sous forme d'une chaînes de caractères de longueur 5
b = 0
for i in scorestr:
if PLATE.Scroll: self.image.blit(ImageOhMummy['ChiffreScroll'][int(i)], (96+16 * b, 0))
else: self.image.blit(ImageOhMummy['Chiffre'][int(i)], (96+16 * b, 0))
b += 1IV-C-5. Classe Mummy▲

La classe Mummy permet de gérer les momies (mouvement et affichage à l'écran). Toutes les momies du jeu sont
contenues dans la liste globale MUMMY. Une instance de Mummy possède les mêmes attributs qu'une
instance de Gargou à savoir x, y, facing et moving et ont la
même signification.
L'attribut supplémentaire movable permet de gérer la vitesse de déplacement de la momie pour que celle-ci ne se déplace pas trop vite.
On distingue ici 3 fonctions movevalable, move et Initialize.
La fonction Initialize permet de repositionner chaque momie encore vivante au changement de niveau.
La fonction movevalable retourne toutes les cases sur laquelle une momie peut se déplacer à partir de sa position.
La fonction move gère le déplacement de la momie. Ce déplacement va dépendre du niveau atteint par le héros. Les momies
seront ainsi de plus en plus "intelligentes" et chercheront à force à se déplacer en direction du héros.
class Mummy(pygame.sprite.Sprite):
def __init__(self, x, y):
pygame.sprite.Sprite.__init__(self, self.containers)
self.image = ImageOhMummy['Mummy']['MoveRight']
self.rect = self.image.get_rect()
self.x = x
self.y = y
self.facing = 0
self.moving = 0
self.rect.left = 80 + x * 16
self.rect.top = 78 + y * 16
self.movable = 0
def movevalable(self):
res = []
if PLATE.plate[self.y][self.x+2] == 1 and PLATE.plate[self.y+1][self.x+2] == 1: res.append(0)
if PLATE.plate[self.y-1][self.x] == 1 and PLATE.plate[self.y-1][self.x+1] == 1: res.append(1)
if PLATE.plate[self.y][self.x-1] == 1 and PLATE.plate[self.y+1][self.x-1] == 1: res.append(2)
if PLATE.plate[self.y+2][self.x] == 1 and PLATE.plate[self.y+2][self.x+1] == 1: res.append(3)
return res
def move(self):
self.movable = (self.movable + 1 ) % 3
if self.movable == 0:
if GARGOU.level == 1: direct = random.randint(0, 3)
elif GARGOU.level == 2: direct = random.choice([0, 1, 2, 3, self.facing, self.facing])
elif GARGOU.level == 3: direct = random.choice(self.movevalable())
elif GARGOU.level == 4:
m = self.movevalable()
m.extend([self.facing, self.facing, self.facing])
direct = random.choice(m)
elif GARGOU.level == 5:
m = []
if self.x == GARGOU.x:
if self.y - GARGOU.y < 0: direct = 3
elif self.y - GARGOU.y > 0: direct = 1
elif self.y == GARGOU.y:
if self.x - GARGOU.x < 0: direct = 0
elif self.x - GARGOU.x > 0: direct = 2
else:
m = self.movevalable()
m.extend([self.facing, self.facing, self.facing])
direct = random.choice(m)
elif GARGOU.level >= 6:
m = []
if self.x - GARGOU.x < 0: m.append(0)
elif self.x - GARGOU.x > 0: m.append(2)
if self.y - GARGOU.y < 0: m.append(3)
elif self.y - GARGOU.y > 0: m.append(1)
direct = random.choice(m)
self.facing = direct
x = self.x; y = self.y
if direct == 0: x = self.x + 1
elif direct == 1: y = self.y - 1
elif direct == 2: x = self.x - 1
elif direct == 3: y = self.y + 1
if PLATE.plate[y][x] == PLATE.plate[y][x+1] == PLATE.plate[y+1][x] == PLATE.plate[y+1][x+1] == 1:
for mum in MUMMY:
if self != mum and abs(x-mum.x) <= 1 and abs(y -mum.y) <= 1:
return
else:
self.x = x
self.y = y
else: return
self.moving = (self.moving + 1) % 2
self.image = ImageOhMummy['Mummy']['Face'][2 * self.facing + self.moving]
self.rect.left = 80 + 16 * self.x
self.rect.top = 78 + 16 * self.y
def Initialize(self, x, y):
self.x = x
self.y = y
self.facing = 0
self.moving = 0
self.rect.left = 80 + x * 16
self.rect.top = 78 + y * 16
self.movable = 0IV-C-6. Classe GuardianMummy▲

La classe GuardianMummy permet de gérer la naissance de la momie cachée dans une des boîtes.
Sa position dans sa boîte va dépendre de la position du héros au moment où celui-ci a dégagé entièrement la boîte de
telle sorte que cette position soit la plus proche de la position du dégagement. Là encore, il n'y a qu'une fonction
utile, la fonction Update. Celle-ci va gérer l'apparition régulière de la momie.
Il y a 16 vues avant que la momie soit entièrement apparue. Une fois ce nombre atteint, on rajoute donc une momie
dans la liste globale MUMMY. la case de naissance de la momie devenant une case sur laquelle le héros et les autres
momies peuvent se déplacer, on met à jour le tableau PLATE.plate. Enfin, on vide la liste globale GUARDIANMUMMY
(qui ne peut contenir au maximum qu'un élément) et on tue l'instance de la classe GuardianMummy.
class GuardianMummy(pygame.sprite.Sprite):
def __init__(self, x, y):
## x et y corresponde au numéro de la boîte sachant que 0<=x<=4 et 0<=y<=3
pygame.sprite.Sprite.__init__(self, self.containers)
self.view = 0
self.image = pygame.Surface((0,0)) ## On part d'une image vide
self.rect = self.image.get_rect()
## Définition de la position de naissance de la Momie
if GARGOU.x < 3 + 7 * x: self.x = 3 + 7 * x
elif GARGOU.x > 6 + 7 * x: self.x = 6 + 7 * x
else: self.x = GARGOU.x
if GARGOU.y < 5 + 5 * y: self.y = 5 + 5 * y
elif GARGOU.y > 6 + 5 * y: self.y = 6 + 5 * y
else: self.y = GARGOU.y
self.movable = 0
def Update(self):
self.movable = (self.movable + 1 ) % 6
if self.movable == 0:
self.view += 1
self.image = ImageOhMummy['GuardianMummy'][self.view]
self.rect = self.image.get_rect()
self.rect.top = 110 + 16 * self.y - 2 * self.view
self.rect.left = 80 + 16 * self.x
if self.view == 16:
MUMMY.append(Mummy(self.x, self.y))
PLATE.plate[self.y][self.x] = 1
PLATE.plate[self.y+1][self.x] = 1
PLATE.plate[self.y][self.x+1] = 1
PLATE.plate[self.y+1][self.x+1] = 1
PLATE.image.blit(ImageOhMummy['Trace']['None'], (16 * self.x - 16, 16 * self.y - 16))
PLATE.image.blit(ImageOhMummy['Trace']['None'], (16 * (self.x+1) - 16, 16 * self.y - 16))
PLATE.image.blit(ImageOhMummy['Trace']['None'], (16 * self.x - 16, 16 * (self.y+1) - 16))
PLATE.image.blit(ImageOhMummy['Trace']['None'], (16 * (self.x+1) - 16, 16 * (self.y+1) - 16))
GUARDIANMUMMY.pop()
self.kill()IV-C-7. Classe Plate▲
La classe Plate gère le plateau de jeu.
L'attribut plate est un tableau à 2 dimensions représentant les cases possibles de déplacement, 1 étant
une case accessible et 0 une non accesible (bord ou une partie d'une boîte). Comme on le voit sur la figure ci-dessus,
les cases jaunes représentent une partie d'un mur, les cases blanches une partie d'une boîte et les cases noires représentent
le chemin sur lequel peut mouvoir le héros.
L'attribut trace est un tableau à 2 dimensions donnant les cases sur lesquelles le héros s'est déjà déplacé et
permettant de savoir si une boîte à été entièrement dégagée. Il a donc les mêmes dimensions que l'attribut plate.
L'attribut box est un tableau à 2 dimensions donnant l'état des boîtes à découvrir (au départ toutes sont à
NonTested).
L'attribut boxchoice est un tableau à 1 dimension de même taille que box qui contient toutes
les découvertes à faire, chaque découverte étant aléatoirement reliée à une case de box.
L'attribut Key détermine si la clé a été découverte.
L'attribut Scroll détermine si le héros possède le parchemin.
L'attribut RoyalMummy détermine si les restes de la momie ont été découvertes.
L'attribut Level détermine le niveau dans la pyramide dans lequel évolue le héros (1 <= Level <= 5)
L'attribut ChangeLevel indique si le héros doit changer de niveau dans la pyramide.
Une case du plateau de jeu représente une surface de 16x16 à l'écran. Ainsi les personnages prennent 2x2 cases sur le jeu.
Une boîte contient 5x3 cases. On se retrouve ainsi avec un total de 39x26 cases sachant que la bordure du tableau
plate représentent le mur extérieur (d'épaisseur une case). Il y a ainsi tout une gymnastique pour se répérer
à l'intérieur de ce tableau.
Chaque fois qu'on initialise le plateau (c'est à dire qu'on change de niveau), une momie supplémentaire apparaît
(MUMMY.append(Mummy(1, 23))) que l'on place en bas à gauche de l'écran, les momies survivantes sont
repositionnées à côté.
La fonction Update (appelée lors du mouvement du héros) permet de mettre à jour et d'afficher le tableau
des traces de pas puis appelle la fonction UpdateBox pour vérifier si une boîte a été ou non entièrement
dégagée. Celle-ci appelle elle-même la fonction UpdateClose en spécifiant la boîte test.
Si une boîte est dégagée, on effectue le résultat de la boîte (augmentation du score, apparition d'une momie, découverte
d'un objet, ...).
De même que la plupart des autres classes, une seule instance globale est créée et nommée PLATE, ce qui permet
d'y avoir accès facilement dans les autres classes.
class Plate(pygame.sprite.Sprite):
def __init__(self, level):
pygame.sprite.Sprite.__init__(self, self.containers)
self.Initialize(level)
def Initialize(self, level):
self.plate = [39 * [0] for i in range(26)]
self.trace = [39 * [0] for i in range(26)]
self.box = [5 * ['NonTested'] for i in range(4)]
l = str(level)
self.boxchoice = ['Treasure', 'Treasure', 'Treasure', 'Treasure', 'Treasure', 'Treasure', 'Treasure', 'Treasure', 'Treasure', 'Treasure',
'GuardianMummy'+l, 'Key', 'RoyalMummy', 'Scroll', 'Empty'+l, 'Empty'+l, 'Empty'+l, 'Empty'+l, 'Empty'+l, 'Empty'+l]
random.shuffle(self.boxchoice)
self.Key = False
self.Scroll = False
self.RoyalMummy = False
self.Level = level
self.ChangeLevel = False
for i in range(3, 24, 5):
for j in range(1, 38):
self.plate[i][j] = 1
self.plate[i+1][j] = 1
for j in range(1, 37, 7):
for i in range(3, 25):
self.plate[i][j] = 1
self.plate[i][j+1] = 1
self.plate[1][15] = 1
self.plate[1][16] = 1
self.plate[2][15] = 1
self.plate[2][16] = 1
self.image = pygame.Surface((592, 384))
self.image.fill((255, 255, 0))
self.rect = self.image.get_rect()
self.rect.left = 96
self.rect.top = 94
## Affichage du plateau
for i in range(1, 25):
for j in range(1, 38):
if self.plate[i][j] == 1:
self.image.blit(ImageOhMummy['Trace']['None'], (16 * j - 16, 16 * i - 16))
for i in range(4):
for j in range(5):
self.image.blit(ImageOhMummy['Box']['NonTested'+l], (32 + 16 * 7 * j, 64 + 16 * 5 * i))
LIFE.Update()
MUMMY.append(Mummy(1, 23))
i = 1
for mum in MUMMY:
mum.Initialize(1 + 2 * i, 23)
i += 1
def Update(self, x, y, facing, moving):
## Mise à jour des traces
if facing == 0:
self.trace[y][x-1] = 1
self.trace[y+1][x-1] = 1
if moving == 0: self.image.blit(ImageOhMummy['Trace']['DownRight'], (16 * x - 32, 16 * y - 16))
else: self.image.blit(ImageOhMummy['Trace']['UpRight'], (16 * x - 32, 16 * y - 16))
elif facing == 1:
self.trace[y+2][x] = 1
self.trace[y+2][x+1] = 1
if moving == 0: self.image.blit(ImageOhMummy['Trace']['LeftUp'], (16 * x - 16, 16 * y + 16))
else: self.image.blit(ImageOhMummy['Trace']['RightUp'], (16 * x - 16, 16 * y + 16))
elif facing == 2:
self.trace[y][x+2] = 1
self.trace[y+1][x+2] = 1
if moving == 0: self.image.blit(ImageOhMummy['Trace']['DownLeft'], (16 * x + 16 , 16 * y - 16))
else: self.image.blit(ImageOhMummy['Trace']['UpLeft'], (16 * x + 16, 16 * y - 16))
elif facing == 3:
self.trace[y-1][x] = 1
self.trace[y-1][x+1] = 1
if moving == 0: self.image.blit(ImageOhMummy['Trace']['LeftDown'], (16 * x - 16, 16 * y - 32))
else: self.image.blit(ImageOhMummy['Trace']['RightDown'], (16 * x - 16 , 16 * y - 32 ))
## Mise à jour des cases
if y>2: self.UpdateBox(x, y)
def UpdateBox(self, x, y):
xx1 = min(4, max(0, (x - 3) // 7))
yy1 = min(3, max(0, (y - 5) // 5))
xx2 = min(4, (x - 1 )// 7)
yy2 = min(3, (y - 3) // 5)
if self.box[yy1][xx1] == 'NonTested': self.UpdateClose(xx1, yy1)
if self.box[yy1][xx2] == 'NonTested': self.UpdateClose(xx2, yy1)
if self.box[yy2][xx1] == 'NonTested': self.UpdateClose(xx1, yy2)
if self.box[yy2][xx2] == 'NonTested': self.UpdateClose(xx2, yy2)
def UpdateClose(self, x, y):
for i in range(3 + 5 * y, 10 + 5 * y):
for j in range(1 + 7 * x, 10 + 7 * x):
if self.plate[i][j] == 1 and self.trace[i][j] == 0: return False
self.box[y][x] = self.boxchoice[5 * y + x]
self.image.blit(ImageOhMummy['Box'][self.box[y][x]], (32 + 112 * x, 64 + 80 * y))
if self.box[y][x] == 'Treasure': SCORE.score += 5
elif self.box[y][x] == "RoyalMummy":
SCORE.score +=50
self.RoyalMummy = True
elif self.box[y][x] == "Scroll":
self.Scroll = True
SCORE.Update()
elif self.box[y][x] == "Key":
self.Key = True
elif self.box[y][x] == "GuardianMummy"+str(self.Level):
GUARDIANMUMMY.append(GuardianMummy(x, y))
SCORE.Update()IV-D. Fonction main()▲
La fonction main va nous permettre d'initialiser toutes nos variables et de gérer les évènements
clavier et le rafraîchissement de l'écran.
clock = pygame.time.Clock() permet de créer une horloge qui permettra ensuite de fixer le nombre d'images à la seconde que
générera le jeu. Ce nombre est alors défini par la fonction clock.tick(fps) où fps est le
nombre d'images par seconde.
On définit ensuite les différents groupes de sprite (all, plate, endgame) de type
ici pygame.sprite.RenderUpdates qui géreront l'affichage à l'écran, lesquels sont attribués aux différentes classes
(Plate.containers = plate, Score.containers = all, ...).
Enfin nos différentes variables sont créées et définies de manière globale. Puis on affiche un arrière plan sur l'écran de jeu ( screen.blit(background, (0, 0)))
et on force le rafraîchissement entier de la fenêtre de jeu (pygame.display.flip())
def main():
clock = pygame.time.Clock()
background = pygame.Surface(SCREENRECT.size)
background = background.convert()
background.fill((255,255,0))
all = pygame.sprite.RenderUpdates()
plate = pygame.sprite.RenderUpdates()
endgame = pygame.sprite.RenderUpdates()
Plate.containers = plate
Score.containers = all
Gargou.containers = all
Life.containers = all
Mummy.containers = all
GuardianMummy.containers = all
global PLATE
global SCORE
global GARGOU
global LIFE
global MUMMY
global GUARDIANMUMMY
SCORE = Score()
LIFE = Life()
MUMMY = []
GUARDIANMUMMY = []
GARGOU = Gargou()
GARGOU.level = 1
PLATE = Plate(1)
screen.blit(background, (0, 0))
pygame.display.flip()
On définit enfin une boucle infinie dans laquelle sera contrôlé le jeu.
Cette boucle commence par une condition qui teste les évènements reçus par Pygame (pygame.event.get()).
Si le joueur a appuyé sur la touche Escape (évènement de type KEYDOWN) ou bien qu'un évènement de type QUIT
a été généré, on quitte le jeu.
On effectue alors les actions des différents personnages:
- On récupère les touches sur lesquelles le joueur a appuyé en ne considérant que les flèches et on effectue les
déplacement du héros (GARGOU.move(direction)).
- Si une momie est en train de naître, guardian.Update() met à jour son évolution.
- Pour chaque momie du jeu, on effectue un déplacement (mum.move()). Puis on vérifie qu'une fois
déplacée, elle n'entre pas en collision avec le héros. Si le héros perd sa dernière vie, on affiche l'image GameOver
( screen.blit(ImageOhMummy['GameOver'], (208, 238)) ) et on attend que le joueur quitte le jeu ou recommence
une partie en appuyant sur la touche 'c' ou 'C'.
Si le joueur a fini un tableau (condition PLATE.ChangeLevel à vérifier), on réinitialise le tout.
Enfin, à la fin de la boucle, on réaffiche en dessinant nos groupes de sprite sur la scène (pl = plate.draw(screen) et
dirty = all.draw(screen) ) et en effectuant le raffraîchissement à l'écran ( pygame.display.update(pl) et
pygame.display.update(dirty) ), le tout en forçant le nombre de frames par seconde ( clock.tick(12) )
goon = True
while goon:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): return
keystate = pygame.key.get_pressed()
direction = [keystate[K_RIGHT], keystate[K_UP], keystate[K_LEFT], keystate[K_DOWN]]
GARGOU.move(direction)
for guardian in GUARDIANMUMMY: guardian.Update()
for mum in MUMMY:
mum.move()
if abs(mum.x - GARGOU.x) <= 1 and abs(mum.y - GARGOU.y) <= 1:
if not PLATE.Scroll:
LIFE.life -= 1
LIFE.Update()
if LIFE.life == 0:
goon = False
screen.blit(ImageOhMummy['GameOver'], (208, 238))
while True:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): return
keystate = pygame.key.get_pressed()
if keystate[ord('c')] or keystate[ord('C')]:
return main()
pygame.display.flip()
clock.tick(10)
else:
PLATE.Scroll = False
SCORE.Update()
mum.kill()
MUMMY.remove(mum)
if PLATE.ChangeLevel:
if PLATE.Level == 1:
if random.randint(0, 1) == 0 and LIFE.life < 9:
background.blit(ImageOhMummy['EndLife'], (0, 0))
LIFE.life += 1
else:
background.blit(ImageOhMummy['End200'], (0, 0))
SCORE.score += 200
screen.blit(background, (0, 0))
for mum in MUMMY: mum.kill()
MUMMY = []
GARGOU.level += 1
while True:
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE): return
keystate = pygame.key.get_pressed()
if keystate[ord('c')] or keystate[ord('C')]: break
pygame.display.flip()
clock.tick(10)
for mum in GUARDIANMUMMY: mum.kill()
GUARDIANMUMMY = []
background.fill((255,255,0))
screen.blit(background, (0, 0))
pygame.display.flip()
PLATE.Initialize(PLATE.Level)
SCORE.Update()
#draw the scene
pl = plate.draw(screen)
dirty = all.draw(screen)
pygame.display.update(pl)
pygame.display.update(dirty)
clock.tick(12)
pygame.time.wait(1000)


