Skip to content
Binary file added Code/Mijn.mp3
Binary file not shown.
Binary file modified Code/__pycache__/entities.cpython-313.pyc
Binary file not shown.
Binary file modified Code/__pycache__/group.cpython-313.pyc
Binary file not shown.
Binary file modified Code/__pycache__/settings.cpython-313.pyc
Binary file not shown.
Binary file modified Code/__pycache__/sprites.cpython-313.pyc
Binary file not shown.
Binary file modified Code/__pycache__/support.cpython-313.pyc
Binary file not shown.
17 changes: 9 additions & 8 deletions Code/debug.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import pygame
pygame.init()
font = pygame.font.Font(None,30)
import pygame #importation de pygame
pygame.init() #initialisation de pygame pour pouvoir l'utiliser
font = pygame.font.Font(None,30) #création d'un objet de police(font) avec une taille de 30, sans police spécifique

def debug(info,y = 10, x = 10):
display_surface = pygame.display.get_surface()
debug_surf = font.render(str(info),True,'White')
debug_rect = debug_surf.get_rect(topleft = (x,y))
pygame.draw.rect(display_surface,'Black',debug_rect)
display_surface.blit(debug_surf,debug_rect)
#fonction qui affiche un texte de débogage sur la surface d'affichage
display_surface = pygame.display.get_surface() #récupere la surface d'affichage actuelle
debug_surf = font.render(str(info),True,'White') #crée une surface contenant le texte de débogage, en blanc
debug_rect = debug_surf.get_rect(topleft = (x,y)) # crée un rectangle autour du texte pour la positionner à (x,y)
pygame.draw.rect(display_surface,'Black',debug_rect) #dessine un rectangle noir autour du texte pour le rendre lisibles dans tout les cas
display_surface.blit(debug_surf,debug_rect) #affiche la surface contenant le texte sur l'ecran
116 changes: 80 additions & 36 deletions Code/entities.py
Original file line number Diff line number Diff line change
@@ -1,91 +1,135 @@
import pygame.sprite
import pygame.sprite #module pygame pour gérer les sprites

from settings import *
from settings import * #importation des paramètres globaux du jeu

#classe de base pour toutes les entités interactives du jeu
class Entity(pygame.sprite.Sprite):
def __init__(self, pos, frames, groups, regard):
super().__init__(groups)
self.z = WORLD_LAYERS['main']
#initialise une entité génrérique
super().__init__(groups) #ajoute l'entité dans le monde
self.z = WORLD_LAYERS['main'] #niveau de profondeur pour le tri d'affichage



#graphics
self.frames_indice, self.frames = 0, frames
self.regard = regard
#graphismes
self.frames_indice, self.frames = 0, frames #animation(index actuel et frames disponibles)
self.regard = regard #direction actuelle de l'entité

# Mouvemenent :
self.direction = vector()
self.speed = 1000

# sprite setup
self.image = self.frames['down'][self.frames_indice]
self.rect = self.image.get_frect(center = pos)
self.direction = vector() #direction de déplacement(vector2)
self.speed = 500 #vitesse de déplacement
self.blocked = False #indique si l'entité est bloquée (imobilisée)

# configuration du sprite
self.image = self.frames['down'][self.frames_indice] #image initiale (face vers le bas)
self.rect = self.image.get_frect(center = pos) # rectangle de position basé sur l'image
#ajuste la hitbox pour correspondre à la taille réelle de l'entité
self.hitbox = self.rect.inflate(-self.rect.width / 2, -60)
self.y_sort = self.rect.centery
self.y_sort = self.rect.centery #utilisé pour trier les entités par profondeur

def animation(self,dt):
self.frames_indice += ANIMATION_SPEED * dt
#anime l'entité en fonction de temps écoulé
self.frames_indice += ANIMATION_SPEED * dt #avance dans l'animation
#definit l'image actuelle en fonction de l'état et de l'animation en cours
self.image = self.frames[self.get_etat()][int(self.frames_indice % len(self.frames[self.get_etat()]))]

def get_etat(self):
# Déterminez l'état actuel de l'entité en fonction de son mouvement et de sa direction
#determine si l'entité est en mouvement
moving = bool(self.direction)
if moving:
if self.direction.x != 0:
self.regard = 'right' if self.direction.x > 0 else 'left'
if self.direction.y != 0:
self.regard = 'down' if self.direction.y > 0 else 'up'
return f"{self.regard}{'' if moving else '_idle'}"

# Définissez la direction basée sur le mouvement
if moving:
if self.direction.x > 0:
self.regard = 'right'
elif self.direction.x < 0:
self.regard = 'left'
elif self.direction.y > 0:
self.regard = 'down'
elif self.direction.y < 0:
self.regard = 'up'

# Genere l'etat actuel
etat = f"{self.regard}{'' if moving else '_idle'}"

# Vérifiez si l'état est valide
if etat not in self.frames:
print(f"Warning: Invalid state '{etat}' for character.") #avertissement si l'état est invalide
return f"{self.regard}_idle" # Retournez un état par défaut valide

return etat

def block(self):
#bloque l'entité, l'empêchant de bouger
self.blocked = True
self.direction = vector(0,0) #rénitialise la direction

def unblock(self):
#débloque l'entité, lui permetttant de bouger à nouveau
self.blocked = False

#classe représentant un drésseur, nune entité spécialisée
class Dresseur(Entity):
def __init__(self, pos, frames, groups, regard):
#initialise un dresseur
super().__init__(pos, frames,groups, regard)

#classe représentant le joueur une entité CONTROLABLE
class Player(Entity):
def __init__(self, pos, frames, groups, regard, collision_sprites):
#initialise le joueur
super().__init__(pos, frames, groups, regard)
self.collision_sprites = collision_sprites
self.collision_sprites = collision_sprites #liste des objets avec lesquels le joueur peut entrer en collision

def input(self):
keys = pygame.key.get_pressed()
input_vector = vector()
#gere les entrées utilisateur pour définir la direction de déplacement
keys = pygame.key.get_pressed() #verifie les touches pressées
input_vector = vector() #direction basée sur les entrées
if keys[pygame.K_UP]:
input_vector.y -= 1
input_vector.y -= 1 #haut
if keys[pygame.K_DOWN]:
input_vector.y += 1
input_vector.y += 1 # bas
if keys[pygame.K_LEFT]:
input_vector.x -= 1
input_vector.x -= 1 # gauche
if keys[pygame.K_RIGHT]:
input_vector.x += 1
self.direction = input_vector
input_vector.x += 1 #droite
#normalise le vecteur de direction pour éviter les déplacements irréguliers
self.direction = input_vector.normalize() if input_vector else input_vector


def mouvement(self, dt):
#gère le déplacement du joueur en prenant en compte le temps et les collisions
#deplace horizontalement
self.rect.centerx += self.direction.x * self.speed * dt
self.hitbox.centerx = self.rect.centerx
self.collisions('horizontale')

#deplace verticalement
self.rect.centery += self.direction.y * self.speed * dt
self.hitbox.centery = self.rect.centery
self.collisions('verticale')

def collisions(self, axis):
#gère les collisions entre le joueur et les objets de collisions
for sprite in self.collision_sprites:
if sprite.hitbox.colliderect(self.hitbox):
if sprite.hitbox.colliderect(self.hitbox): #detecte une collision
if axis == 'horizontale':
#corrige la position selon la direction horizontale
if self.direction.x > 0: # Déplacement à droite
self.hitbox.right = sprite.hitbox.left
if self.direction.x < 0: # Déplacement à gauche
self.hitbox.left = sprite.hitbox.right
self.rect.centerx = self.hitbox.centerx # Synchronisation
else:
#corrige la position selon la direction verticale
if self.direction.y > 0: # Déplacement vers le bas
self.hitbox.bottom = sprite.hitbox.top
if self.direction.y < 0: # Déplacement vers le haut
self.hitbox.top = sprite.hitbox.bottom
self.rect.centery = self.hitbox.centery # Synchronisation

def update(self, dt):
self.y_sort = self.rect.centery
self.input()
self.mouvement(dt)
self.animation(dt)
#met a jour l'état du joueur à chaque frame
self.y_sort = self.rect.centery #mise a jour du tri
if not self.blocked: #si le joueur n'est pas bloqué
self.input() #gestion des entrées
self.mouvement(dt) #gestion des mouvements
self.animation(dt) #mise a jour de l'animation
32 changes: 20 additions & 12 deletions Code/group.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
import pygame.sprite

from settings import *
from support import import_image
from entities import *
from settings import * #importation de constantes et configurations
from support import import_image #importation de la fonction pour charger une image
from entities import * #importation des entités

#classe allsprites qui hérite de pygame.sprite.group
class AllSprites(pygame.sprite.Group):
def __init__(self):
super().__init__()
self.display_surface = pygame.display.get_surface()
self.offset = vector()
self.ombre_surf = import_image('..', 'graphics', 'other', 'ombre')
super().__init__() #appel du constructeur parent pour initialiser un groupe d'entités
self.display_surface = pygame.display.get_surface() #recuperation de la surface d'affichage de la fenêtre
self.offset = vector() #initialisation de l'offset pour le déplacement de la vue
self.ombre_surf = import_image('..', 'graphics', 'other', 'ombre') # chargement de l'image d'ombre

#méthode pour dessiner les sprites à l'écran en fonction de la position du joueur
def draw(self, player_center):
self.offset.x = -(player_center[0] - WINDOW_WIDTH /2)
self.offset.y = -(player_center[1] - WINDOW_HEIGHT /2)
#calcul de l'offset pour centrer l'écran sur le joueur
self.offset.x = -(player_center[0] - WINDOW_WIDTH /2) #decalage x
self.offset.y = -(player_center[1] - WINDOW_HEIGHT /2)#decalage y

bg_sprite = [sprite for sprite in self if sprite.z < WORLD_LAYERS['main']]
main_sprite = sorted([sprite for sprite in self if sprite.z == WORLD_LAYERS['main']], key=lambda sprite: sprite.y_sort)
fg_sprite = [sprite for sprite in self if sprite.z > WORLD_LAYERS['main']]
#séparation des sprites selon leur profondeur dans le monde (couches)
bg_sprite = [sprite for sprite in self if sprite.z < WORLD_LAYERS['main']] #sprites d'arrière plan
main_sprite = sorted([sprite for sprite in self if sprite.z == WORLD_LAYERS['main']], key=lambda sprite: sprite.y_sort) #sprites principaux triés par position verticale
fg_sprite = [sprite for sprite in self if sprite.z > WORLD_LAYERS['main']] #sprites au premier plan

#dessin des sprites par couche
for layer in (bg_sprite, main_sprite, fg_sprite):
for sprite in layer:
#si le sprite est un joueur, on lui ajoute une ombre
if isinstance(sprite, Player):
self.display_surface.blit(self.ombre_surf, sprite.rect.topleft + self.offset + vector(25, 120))
#si le sprite est un dresseur, on lui ajoute aussi une ombre
if isinstance(sprite, Dresseur):
self.display_surface.blit(self.ombre_surf, sprite.rect.topleft + self.offset + vector(40, 110))
#dessine le sprite à l'ecran
self.display_surface.blit(sprite.image, sprite.rect.topleft + self.offset)
Loading