Dorian.D
10 months ago
3 changed files with 738 additions and 0 deletions
@ -0,0 +1,416 @@ |
|||||||
|
# Importation |
||||||
|
import random as rd |
||||||
|
import time |
||||||
|
from PIL import Image |
||||||
|
# Déclaration des CONSTANTES |
||||||
|
|
||||||
|
# Déclaration Classes |
||||||
|
|
||||||
|
class Monstre : |
||||||
|
|
||||||
|
def __init__(self, nom, dsc, img=None, obj=None) -> None: |
||||||
|
self.nom = nom |
||||||
|
self.dsc = dsc |
||||||
|
self.img = img |
||||||
|
self.obj = obj |
||||||
|
self.habilite = rd.randint(1,10) |
||||||
|
self.endurance_max = 15 |
||||||
|
self.endurance = self.endurance_max |
||||||
|
self.force = 2 |
||||||
|
self.courage = rd.randint(1,10) |
||||||
|
self.objet = [] |
||||||
|
|
||||||
|
if "Squelette" in self.nom: |
||||||
|
self.habilite = rd.randint(1,7) |
||||||
|
self.endurance = rd.randint(1,4) |
||||||
|
self.force = rd.randint(1,2) |
||||||
|
self.courage = rd.randint(1,10) |
||||||
|
|
||||||
|
if 'Chauve-souris' in self.nom: |
||||||
|
self.habilite = rd.randint(5,10) |
||||||
|
self.endurance = rd.randint(1,3) |
||||||
|
self.force = 1 |
||||||
|
self.courage = 10 |
||||||
|
self.objet = ['clé cadena'] |
||||||
|
self.img = "chauve-souris.jpg" |
||||||
|
|
||||||
|
if 'Limace-geante' in self.nom: |
||||||
|
self.habilite = 1 |
||||||
|
self.endurance = 7 |
||||||
|
self.force = 1 |
||||||
|
self.courage = 10 |
||||||
|
|
||||||
|
if 'Zombie' in self.nom: |
||||||
|
self.habilite = rd.randint(1,4) |
||||||
|
self.endurance = 7 |
||||||
|
self.force = 1 |
||||||
|
self.courage = 8 |
||||||
|
|
||||||
|
if 'Zombie_sur_poulet'in self.nom: |
||||||
|
self.habilite = rd.randint(4,7) |
||||||
|
self.endurance = 4 |
||||||
|
self.force = 2 |
||||||
|
self.courage = 8 |
||||||
|
|
||||||
|
if 'Hydra' in self.nom: |
||||||
|
self.habilite = rd.randint(8,10) |
||||||
|
self.endurance = 10 |
||||||
|
self.force = 3 |
||||||
|
self.courage = 10 |
||||||
|
|
||||||
|
if 'Poutine' in self.nom: |
||||||
|
self.habilite = 10 |
||||||
|
self.endurance = 12 |
||||||
|
self.force = 4 |
||||||
|
self.courage = 10 |
||||||
|
|
||||||
|
|
||||||
|
def modifier_endurance(self:'Monstre', modificateur): |
||||||
|
endurance_modifie = self.endurance + modificateur |
||||||
|
if endurance_modifie < 0: |
||||||
|
self.endurance = 0 |
||||||
|
elif endurance_modifie > self.endurance_max: |
||||||
|
self.endurance = self.endurance_max |
||||||
|
else: |
||||||
|
self.endurance = endurance_modifie |
||||||
|
|
||||||
|
def subir_degats(self:'Monstre', degats:int) -> None: |
||||||
|
if degats > 0: |
||||||
|
self.modifier_endurance(-degats) |
||||||
|
|
||||||
|
|
||||||
|
def get_description(self:'Monstre') -> str: |
||||||
|
return self.dsc |
||||||
|
|
||||||
|
def get_carac(self:'Montres') -> str: |
||||||
|
return f"{self.nom} H{self.habilite} E{self.endurance} F{self.force} C{self.courage}" |
||||||
|
|
||||||
|
def est_hs(self:'Monstre') -> bool: |
||||||
|
if self.endurance <= 0: |
||||||
|
return True |
||||||
|
else: |
||||||
|
return False |
||||||
|
class Personnage: |
||||||
|
|
||||||
|
def __init__(self, nom='Aucun'): |
||||||
|
|
||||||
|
self.nom = nom |
||||||
|
|
||||||
|
self.habilite = 5 + rd.randint(1,4) |
||||||
|
self.endurance_max = 7 + rd.randint(1,8) |
||||||
|
self.endurance = self.endurance_max |
||||||
|
self.force = 2 |
||||||
|
self.charisme = rd.randint(1,10) |
||||||
|
self.vigilance = rd.randint(1,10) |
||||||
|
self.discretion = False |
||||||
|
self.lieu = None |
||||||
|
self.lieux_precedents = [] |
||||||
|
self.objet = [] |
||||||
|
|
||||||
|
def modifier_endurance(self:'Personnage', modificateur): |
||||||
|
endurance_modifie = self.endurance + modificateur |
||||||
|
if endurance_modifie < 0: |
||||||
|
self.endurance = 0 |
||||||
|
elif endurance_modifie > self.endurance_max: |
||||||
|
self.endurance = self.endurance_max |
||||||
|
else: |
||||||
|
self.endurance = endurance_modifie |
||||||
|
|
||||||
|
def subir_degats(self:'Personnage', degats:int) -> None: |
||||||
|
if degats > 0: |
||||||
|
self.modifier_endurance(-degats) |
||||||
|
|
||||||
|
def est_hs(self:'Personnage') -> bool : |
||||||
|
if self.endurance == 0: |
||||||
|
return True |
||||||
|
else: |
||||||
|
return False |
||||||
|
|
||||||
|
def get_carac(self:'Personnage') -> str: |
||||||
|
return f"{self.nom} H{self.habilite} E{self.endurance} F{self.force} C{self.charisme} V{self.vigilance}" |
||||||
|
|
||||||
|
def combattre(self:'Personnage', adversaire:'Monstre') -> tuple: |
||||||
|
""" |
||||||
|
Effectue un combat entre le personnage et un monstre. |
||||||
|
Parameters: |
||||||
|
- self ('Personnage'): L'instance du personnage effectuant l'attaque. |
||||||
|
- adversaire ('Monstre'): L'instance du monstre contre lequel le personnage se bat. |
||||||
|
Returns: |
||||||
|
- tuple: Un tuple contenant le code de résultat et la description du combat. |
||||||
|
Code de Résultat : |
||||||
|
- 'x': Le combat n'est pas encore terminé. |
||||||
|
- 'MP': Les deux participants sont hors combat. |
||||||
|
- 'P': Le personnage est hors combat. |
||||||
|
- 'M': Le monstre est hors combat. |
||||||
|
Description : |
||||||
|
Le combat consiste en plusieurs étapes, où les scores de combat sont comparés, et des dégâts sont infligés en fonction du résultat. |
||||||
|
Les participants peuvent également subir des dégâts critiques ou être hors combat. |
||||||
|
""" |
||||||
|
score_personnage = rd.randint(1, 6) + rd.randint(1, 6) + self.habilite |
||||||
|
score_monstre = rd.randint(1, 6) + rd.randint(1, 6) + adversaire.habilite |
||||||
|
result_code = 'x' |
||||||
|
|
||||||
|
while result_code == 'x': |
||||||
|
if score_personnage == score_monstre: |
||||||
|
self.subir_degats(1) |
||||||
|
adversaire.subir_degats(1) |
||||||
|
result_code = "x" |
||||||
|
result_desc = f"{self.nom} et {adversaire.nom} se blessent mutuellement." |
||||||
|
time.sleep(1) |
||||||
|
print(result_desc) |
||||||
|
elif score_personnage > score_monstre: |
||||||
|
adversaire.subir_degats(self.force) |
||||||
|
result_code = "x" |
||||||
|
result_desc = f"{self.nom} inflige {self.force} points de dégâts au {adversaire.nom}." |
||||||
|
time.sleep(1) |
||||||
|
print(result_desc) |
||||||
|
else: |
||||||
|
self.subir_degats(adversaire.force) |
||||||
|
result_code = "x" |
||||||
|
result_desc = f"{adversaire.nom} inflige {adversaire.force} points de dégâts au {self.nom}." |
||||||
|
time.sleep(0.5) |
||||||
|
print(result_desc) |
||||||
|
if rd.randint(1, 6) == rd.randint(1, 6): |
||||||
|
double_damage = self.force * 2 |
||||||
|
adversaire.subir_degats(double_damage) |
||||||
|
result_desc += f" Coup critique ! {self.nom} inflige {double_damage} points de dégâts supplémentaires au {adversaire.nom}." |
||||||
|
time.sleep(0.5) |
||||||
|
print(result_desc) |
||||||
|
elif self.est_hs() and adversaire.est_hs(): |
||||||
|
result_code = "MP" |
||||||
|
result_desc = f"{self.nom} et {adversaire.nom} sont tous les deux hors combat." |
||||||
|
time.sleep(0.5) |
||||||
|
print(result_desc) |
||||||
|
elif self.est_hs(): |
||||||
|
result_code = "P" |
||||||
|
result_desc = f"{self.nom} est hors combat." |
||||||
|
elif adversaire.est_hs(): |
||||||
|
result_code = "M" |
||||||
|
result_desc = f"{adversaire.nom} est hors combat." |
||||||
|
time.sleep(0.5) |
||||||
|
print(result_desc) |
||||||
|
|
||||||
|
return result_code, result_desc |
||||||
|
|
||||||
|
def observer(self:'Personnage') -> str: |
||||||
|
if self.lieu: |
||||||
|
return self.lieu.decrire_lieu() |
||||||
|
|
||||||
|
|
||||||
|
def reflechir(self:'Personnage') -> str: |
||||||
|
if self.lieu: |
||||||
|
return self.lieu.decrire_actions_possibles() |
||||||
|
|
||||||
|
|
||||||
|
def combattre_monstre_actuel(self): |
||||||
|
rep = self.combattre(self.lieu.occupant) |
||||||
|
if self.lieu.occupant.est_hs(): |
||||||
|
self.lieu.set_occupant(None) |
||||||
|
return rep |
||||||
|
|
||||||
|
def aller_nord(self): |
||||||
|
if self.lieu.nord and (not self.lieu.occupant or self.lieu.occupant.est_hs()): |
||||||
|
self.lieux_precedents.append(self.lieu) |
||||||
|
self.lieu = self.lieu.nord |
||||||
|
return True |
||||||
|
else: |
||||||
|
return False |
||||||
|
|
||||||
|
def aller_sud(self): |
||||||
|
if self.lieu.sud and (not self.lieu.occupant or self.lieu.occupant.est_hs()): |
||||||
|
self.lieux_precedents.append(self.lieu) |
||||||
|
self.lieu = self.lieu.sud |
||||||
|
return True |
||||||
|
else: |
||||||
|
return False |
||||||
|
|
||||||
|
def aller_ouest(self): |
||||||
|
if self.lieu.ouest and (not self.lieu.occupant or self.lieu.occupant.est_hs()): |
||||||
|
self.lieux_precedents.append(self.lieu) |
||||||
|
self.lieu = self.lieu.ouest |
||||||
|
return True |
||||||
|
else: |
||||||
|
return False |
||||||
|
|
||||||
|
def aller_est(self): |
||||||
|
if self.lieu.est and (not self.lieu.occupant or self.lieu.occupant.est_hs()): |
||||||
|
self.lieux_precedents.append(self.lieu) |
||||||
|
self.lieu = self.lieu.est |
||||||
|
return True |
||||||
|
else: |
||||||
|
return False |
||||||
|
|
||||||
|
|
||||||
|
class Lieu: |
||||||
|
|
||||||
|
def __init__(self, nom, dsc, img) -> None: |
||||||
|
self.nom = nom |
||||||
|
self.dsc = dsc |
||||||
|
self.image = None |
||||||
|
self.nord = None |
||||||
|
self.sud = None |
||||||
|
self.est = None |
||||||
|
self.ouest = None |
||||||
|
self.occupant = None |
||||||
|
self.objets = [] |
||||||
|
self.action_supp = None |
||||||
|
|
||||||
|
|
||||||
|
def decrire_lieu(self): |
||||||
|
"""Renvoie une description de la salle et le monstre éventuellement présent |
||||||
|
|
||||||
|
:: param self(Lieu) :: une instance de Lieu |
||||||
|
:: return (str) :: un string contenant la description globale |
||||||
|
|
||||||
|
""" |
||||||
|
reponse = self.dsc |
||||||
|
|
||||||
|
if self.occupant: # cela veut dire si self.occupant existe (n'est pas 0, vide ou None) |
||||||
|
reponse = reponse + f" \nLa salle contient également un(e) {self.occupant.nom} : {self.occupant.get_description()}" |
||||||
|
return reponse |
||||||
|
|
||||||
|
def decrire_actions_possibles(self:'Lieu') -> str: |
||||||
|
"""Renvoie un string de toutes les actions possibles""" |
||||||
|
actions_possibles = "" |
||||||
|
if self.occupant: |
||||||
|
actions_possibles += "C : Combattre" |
||||||
|
actions_possibles += "F : Fuire" |
||||||
|
if self.objets: |
||||||
|
actions_possibles += "R : Ramasser" |
||||||
|
if self.nord: |
||||||
|
actions_possibles += "Z : Porte Nord" |
||||||
|
if self.sud: |
||||||
|
actions_possibles += "S : Porte Sud" |
||||||
|
if self.ouest: |
||||||
|
actions_possibles += "D : Porte Ouest" |
||||||
|
if self.est: |
||||||
|
actions_possibles += "Q : Porte Est" |
||||||
|
if self.objets: |
||||||
|
actions_possibles += "U : utiliser objet" |
||||||
|
|
||||||
|
return actions_possibles |
||||||
|
|
||||||
|
def set_occupant(self: 'Lieu', occupant: 'None|Monstre|Personnage') -> bool: |
||||||
|
'''Cette méthode permet de mettre en place un occupant dans un lieu''' |
||||||
|
if not self.occupant or (occupant and occupant.est_hs()): |
||||||
|
self.occupant = occupant |
||||||
|
return True |
||||||
|
return False |
||||||
|
|
||||||
|
|
||||||
|
def ouvrir(self:'Personnage', lieu:'Lieu'): |
||||||
|
'''permet de verifier si on a un objet dans l'inventaire pour ouvrir''' |
||||||
|
if self.objet == 'clé cadena': |
||||||
|
entree.nord = couloire_sud |
||||||
|
couloire_sud.sud = entree |
||||||
|
|
||||||
|
|
||||||
|
class Manoir: |
||||||
|
|
||||||
|
def __init__(self): |
||||||
|
|
||||||
|
self.heros = None |
||||||
|
self.depart = None |
||||||
|
self.lieux = [] |
||||||
|
self.monstres = [] |
||||||
|
|
||||||
|
def peupler_manoir(): |
||||||
|
|
||||||
|
# Création et agencement des lieux |
||||||
|
|
||||||
|
entree = Lieu("Entrée", "Une entrée délabrée et poussiéreuse. Une porte entrouverte se trouve à l'ouest. Une porte verouillée avec un cadena au nord et une petite salle a l'est.", "entree.jpg") |
||||||
|
garage = Lieu("Garage", "Un garage sans dessus-dessous avec une chauve-souris qui a une clé entre ses griffes. Une porte mène à l'est vers l'Entrée", "garage.jpg") |
||||||
|
vestibule = Lieu("Vestibule", "Une petite pièce dans la quelle est entreposée une armure rouillée. aller vers l'ouest pour retourner dans l'Entrée.", "vestibule.jpg") |
||||||
|
couloire_sud = Lieu("Couloire Sud","Un long couloir sombre et étroit qui s'étend vers le sud. Les murs sont décrépits, et il y a une faible lueur provenant d'une ampoule vacillante au plafond.", "couloir.jpg") |
||||||
|
chambre_du_gardien = Lieu("Chambre du gardien", " Une chambre poussiéreuse qui semble avoir appartenu à un gardien. Un lit défait, une vieille chaise et une étagère avec des livres usés occupent l'espace. Une fenêtre cassée laisse filtrer la lumière extérieure.", "chambre_gardien.jpg") |
||||||
|
toilette_usagée = Lieu("Toilette usagée", "Peuve toujours servir mais à vos risques", "toilette.jpg") |
||||||
|
Hub = Lieu("Jardin couvert", "Un espace central où convergent plusieurs couloirs. Un jardin intérieur avec des plantes négligées, des bancs en bois cassés et un petit bassin. Des portes mènent vers différentes parties de l'endroit.", "hub.jpg") |
||||||
|
couloire_nord = Lieu("Couloire Nord","Un couloir obscur qui s'étend vers le nord. Le son lointain de gouttes d'eau résonne, et des portes menant à d'autres zones de l'endroit sont visibles.", "couloir.jpg") |
||||||
|
couloire_est = Lieu("Couloire Est","Un couloir délabré orienté vers l'est. Des traces de moisissure s'accrochent aux murs, et des bruits étouffés provenant de salles adjacentes donnent une atmosphère mystérieuse.", "couloir.jpg") |
||||||
|
couloire_ouest = Lieu("Couloire Ouest","Un couloir sombre s'étirant vers l'ouest. Des portes fermées jalonnent les côtés, et des murmures indistincts peuvent être entendus au loin.", "couloir.jpg") |
||||||
|
cuisine = Lieu("Cuisine"," Une cuisine abandonnée avec des ustensiles rouillés et des étagères vides. Une odeur étrange flotte dans l'air, et une porte menant à une autre pièce est entrebâillée.", "cuisine.jpg") |
||||||
|
picine = Lieu("Picine","Zone de boss (hydraaaaaa)", "piscine.jpg") |
||||||
|
salle_arcade = Lieu("Salle d'arcade","Une salle remplie de vieux jeux d'arcade. Les lumières clignotent faiblement, et le son lointain des machines crée une atmosphère nostalgique.", "salle_arcade.jpg") |
||||||
|
bureau = Lieu("Bureau","Un bureau désordonné avec des piles de papiers et une vieille machine à écrire. Des étagères pleines de livres poussiéreux et des fenêtres sales complètent l'ambiance de cet endroit oublié.", "bureau.jpg") |
||||||
|
salle_NSI = Lieu("Salle de NSI","Zone de bossssss... !!!!! Un GRAND Poutine débarque...", "salle NSI.jpg") |
||||||
|
|
||||||
|
entree.ouest = garage |
||||||
|
entree.est = vestibule |
||||||
|
garage.est = entree |
||||||
|
garage.occupant = Monstre("Chauve-souris", "") |
||||||
|
vestibule.objet = ['Armure rouillée (+2 EnduranceMax)'] |
||||||
|
vestibule.ouest = entree |
||||||
|
couloire_sud.nord = Hub |
||||||
|
couloire_sud.ouest = chambre_du_gardien |
||||||
|
couloire_sud.est = toilette_usagée |
||||||
|
chambre_du_gardien.est = couloire_sud |
||||||
|
chambre_du_gardien.occupant = Monstre("Squelette", "") |
||||||
|
toilette_usagée.ouest = couloire_sud |
||||||
|
toilette_usagée.objet = ["Pièce d'or"] |
||||||
|
Hub.sud = couloire_sud |
||||||
|
Hub.est = couloire_est |
||||||
|
Hub.ouest = couloire_ouest |
||||||
|
Hub.nord = couloire_nord |
||||||
|
couloire_ouest.ouest = cuisine |
||||||
|
couloire_ouest.est = Hub |
||||||
|
cuisine.est = couloire_ouest |
||||||
|
cuisine.ouest = picine |
||||||
|
cuisine.occupant = Monstre("Limace-geante","") |
||||||
|
picine.occupant = Monstre("Hydra","") |
||||||
|
couloire_est.ouest = Hub |
||||||
|
couloire_est.est = salle_arcade |
||||||
|
couloire_est.occupant = Monstre("Zombie","") |
||||||
|
salle_arcade.ouest = couloire_est |
||||||
|
salle_arcade.nord = bureau |
||||||
|
salle_arcade.est = salle_NSI |
||||||
|
salle_arcade.occupant = Monstre("Zombie_sur_poulet","") |
||||||
|
bureau.sud = salle_arcade |
||||||
|
bureau.occupant = Monstre("Pikachu","") |
||||||
|
bureau.objet = ["bandage", "1 pièce d'or"] |
||||||
|
|
||||||
|
# Création du personnage du joueur |
||||||
|
aventurier = Personnage("Alice") |
||||||
|
aventurier.lieu = entree |
||||||
|
|
||||||
|
# Création du manoir |
||||||
|
manoir = Manoir() |
||||||
|
manoir.heros = aventurier |
||||||
|
manoir.depart = aventurier.lieu |
||||||
|
manoir.lieux.append(entree) |
||||||
|
manoir.lieux.append(garage) |
||||||
|
manoir.lieux.append(vestibule) |
||||||
|
manoir.lieux.append(couloire_sud) |
||||||
|
manoir.lieux.append(chambre_du_gardien) |
||||||
|
manoir.lieux.append(toilette_usagée) |
||||||
|
manoir.lieux.append(Hub) |
||||||
|
manoir.lieux.append(couloire_nord) |
||||||
|
manoir.lieux.append(couloire_est) |
||||||
|
manoir.lieux.append(couloire_ouest) |
||||||
|
manoir.lieux.append(cuisine) |
||||||
|
manoir.lieux.append(picine) |
||||||
|
manoir.lieux.append(salle_arcade) |
||||||
|
manoir.lieux.append(bureau) |
||||||
|
manoir.lieux.append(salle_NSI) |
||||||
|
|
||||||
|
manoir.monstres.append("Squelette") |
||||||
|
manoir.monstres.append("Chauve-souris") |
||||||
|
manoir.monstres.append("Limace-geante") |
||||||
|
manoir.monstres.append("Zombie") |
||||||
|
manoir.monstres.append("Zombie_sur_poulet") |
||||||
|
manoir.monstres.append("Hydra") |
||||||
|
manoir.monstres.append("Poutine") |
||||||
|
|
||||||
|
return manoir |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Déclaration de Fonctions |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Le corps du module en lui-même |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
m = peupler_manoir() |
@ -0,0 +1,266 @@ |
|||||||
|
|
||||||
|
# IMPORTATIONS |
||||||
|
|
||||||
|
import tkinter as tk |
||||||
|
from PIL import Image as Img |
||||||
|
from PIL import ImageTk |
||||||
|
|
||||||
|
|
||||||
|
# CONSTANTES |
||||||
|
|
||||||
|
TAILLE_IMG = 350 |
||||||
|
FOND_IMAGE = "#222222" |
||||||
|
|
||||||
|
VISUEL = { |
||||||
|
'nb caractères':80, |
||||||
|
'nb lignes':9, |
||||||
|
'fond':"#EE7722", |
||||||
|
'écriture':"black", |
||||||
|
'police': ("Courier", 16) |
||||||
|
} |
||||||
|
|
||||||
|
# DECLARATION DES CLASSES PUBLIQUES |
||||||
|
|
||||||
|
class IHM(): |
||||||
|
'''IHM basique permettant de gérer le projet Manoir Hanté |
||||||
|
|
||||||
|
Idée générale |
||||||
|
------------- |
||||||
|
Interface graphique interactive permettant d'afficher : |
||||||
|
-> Trois zones de texte : description, actions possibles et caractéristiques ? |
||||||
|
-> Deux images : une pour le lieu et une pour un monstre ou autre ? |
||||||
|
|
||||||
|
Classe IHM |
||||||
|
---------- |
||||||
|
La Classe générant l'interface graphique (GUI en anglais) |
||||||
|
L'interaction avec le programme gérant les données se fait |
||||||
|
via la méthode signaler_evenement() |
||||||
|
|
||||||
|
Méthodes disponibles |
||||||
|
-------------------- |
||||||
|
signaler_evenement(self, f) |
||||||
|
afficher_txt_1(self, texte:str) |
||||||
|
afficher_txt_2(self, texte:str) |
||||||
|
afficher_txt_3(self, texte:str) |
||||||
|
afficher_img_1(self, fichier_image:str) |
||||||
|
afficher_img_2(self, fichier_image:str) |
||||||
|
''' |
||||||
|
|
||||||
|
def __init__(self): |
||||||
|
self.interne = IHM_interne() |
||||||
|
|
||||||
|
def signaler_evenement(self, f): |
||||||
|
self.interne.signaler_evenement(f) |
||||||
|
|
||||||
|
def afficher_txt_1(self, texte:str): |
||||||
|
self.interne.afficher_txt_1(texte) |
||||||
|
|
||||||
|
def afficher_txt_2(self, texte:str): |
||||||
|
self.interne.afficher_txt_2(texte) |
||||||
|
|
||||||
|
def afficher_txt_3(self, texte:str): |
||||||
|
self.interne.afficher_txt_3(texte) |
||||||
|
|
||||||
|
def afficher_img_1(self, fichier_image:str): |
||||||
|
self.interne.afficher_img_1(fichier_image) |
||||||
|
|
||||||
|
def afficher_img_2(self, fichier_image:str): |
||||||
|
self.interne.afficher_img_2(fichier_image) |
||||||
|
|
||||||
|
|
||||||
|
# DECLARATION DES CLASSES PRIVEES (mais que je n'ai pas caché plus que cela) |
||||||
|
# Vous pouvez d'ailleurs interagir direction avec elle en notant directement |
||||||
|
# ihm =IHM_interne() plutôt que ihm = IHM() si vous voulez. |
||||||
|
|
||||||
|
class IHM_interne(tk.Tk): |
||||||
|
|
||||||
|
def __init__(self): |
||||||
|
|
||||||
|
# Création de l'application en elle-même |
||||||
|
tk.Tk.__init__(self) |
||||||
|
xmax, ymax = self.obtenir_taille_ecran() |
||||||
|
self.geometry(f"{xmax}x{ymax}") |
||||||
|
self.title("MON SUPER JEU") |
||||||
|
self.configure(bg=FOND_IMAGE) |
||||||
|
|
||||||
|
|
||||||
|
self.frame_g = self.creer_frame_g(FOND_IMAGE) |
||||||
|
self.frame_d = self.creer_frame_d(FOND_IMAGE) |
||||||
|
|
||||||
|
# Création des widgets-labels |
||||||
|
self.IMAGE_VIDE = ImageTk.PhotoImage(Img.new("RGB", (TAILLE_IMG, TAILLE_IMG), (50, 50, 50))) |
||||||
|
self.image_1 = self.IMAGE_VIDE |
||||||
|
self.image_2 = self.IMAGE_VIDE |
||||||
|
self.label_img_1 = self.creer_label_img_1(self.frame_g, None) |
||||||
|
self.label_img_2 = self.creer_label_img_2(self.frame_g, None) |
||||||
|
self.label_txt_1 = self.creer_label_txt_1(self.frame_d, "-", VISUEL) |
||||||
|
self.label_txt_3 = self.creer_label_txt_3(self.frame_d, "valeurs", VISUEL) |
||||||
|
self.label_txt_2 = self.creer_label_txt_2(self.frame_d, "-", VISUEL) |
||||||
|
|
||||||
|
# Configuration intiale des widgets (à commenter si vous ne voulez pas d'images au départ |
||||||
|
config_depart = ("Ici, on décrit la scène\nSur plusieurs lignes si nécessaire.", "Ici, on donne les choix possibles", None, None, "Caractéristiques aventurier et monstre") |
||||||
|
self.configuration_scene(config_depart) |
||||||
|
|
||||||
|
# Gestion des événements |
||||||
|
self.fonction = None |
||||||
|
self.bind('<Any-KeyPress>', self.gestion_actions) |
||||||
|
|
||||||
|
# DECLARATION DES METHODES INTERNES : ne pas utiliser depuis l'extérieur du module |
||||||
|
|
||||||
|
def obtenir_taille_ecran(self) -> tuple: |
||||||
|
xmax = self.winfo_screenwidth() |
||||||
|
ymax = self.winfo_screenheight() |
||||||
|
return xmax, ymax |
||||||
|
|
||||||
|
def creer_frame_g(self, fond): |
||||||
|
zone = tk.Frame(self, bg=fond) |
||||||
|
zone.pack(side=tk.LEFT, fill=tk.Y, padx=0, pady=0) |
||||||
|
return zone |
||||||
|
|
||||||
|
def creer_frame_d(self, fond): |
||||||
|
zone = tk.Frame(self, bg=fond) |
||||||
|
zone.pack(side=tk.RIGHT, expand=True, fill=tk.BOTH, padx=0, pady=0) |
||||||
|
return zone |
||||||
|
|
||||||
|
def creer_label_txt_1(self:tk.Tk, conteneur, texte:str, visuel:dict) -> tk.Label: |
||||||
|
auDessus = tk.Label(conteneur, text="DESCRIPTION", fg="#CCCCCC", bg="black", height=3) |
||||||
|
auDessus.configure(font=visuel['police']) |
||||||
|
auDessus.pack(side=tk.TOP, fill=tk.X, padx=10, pady=10) |
||||||
|
|
||||||
|
monLabel = tk.Label(conteneur, text=texte) |
||||||
|
monLabel.configure(fg=visuel['écriture']) |
||||||
|
monLabel.configure(bg=visuel['fond']) |
||||||
|
monLabel.configure(font=visuel['police']) |
||||||
|
monLabel.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx=10, pady=10) |
||||||
|
|
||||||
|
return monLabel |
||||||
|
|
||||||
|
def creer_label_txt_2(self:tk.Tk, conteneur, texte:str, visuel:dict) -> tk.Label: |
||||||
|
|
||||||
|
monLabel = tk.Label(conteneur, text=texte) |
||||||
|
monLabel.configure(fg=visuel['écriture']) |
||||||
|
monLabel.configure(bg=visuel['fond']) |
||||||
|
monLabel.configure(width=visuel['nb caractères']) |
||||||
|
monLabel.configure(height=visuel['nb lignes']) |
||||||
|
monLabel.configure(font=visuel['police']) |
||||||
|
monLabel.pack(side=tk.BOTTOM,fill=tk.BOTH, expand=True, padx=10, pady=10) |
||||||
|
|
||||||
|
auDessus = tk.Label(conteneur, text="ACTIONS POSSIBLES", fg="#CCCCCC", bg="black", height=3) |
||||||
|
auDessus.configure(font=visuel['police']) |
||||||
|
auDessus.pack(side=tk.BOTTOM,fill=tk.X, padx=10, pady=10) |
||||||
|
|
||||||
|
return monLabel |
||||||
|
|
||||||
|
def creer_label_txt_3(self:tk.Tk, conteneur, texte:str, visuel:dict) -> tk.Label: |
||||||
|
monLabel = tk.Label(conteneur, text=texte) |
||||||
|
monLabel.configure(fg=visuel['écriture']) |
||||||
|
monLabel.configure(bg=visuel['fond']) |
||||||
|
monLabel.configure(width=visuel['nb caractères']) |
||||||
|
monLabel.configure(height=2) |
||||||
|
monLabel.configure(font=visuel['police']) |
||||||
|
monLabel.pack(side=tk.BOTTOM, fill=tk.X, padx=10, pady=10) |
||||||
|
|
||||||
|
auDessus = tk.Label(conteneur, text="Caractéristiques", fg="#CCCCCC", bg="black", height=3) |
||||||
|
auDessus.configure(font=visuel['police']) |
||||||
|
auDessus.pack(side=tk.BOTTOM, fill=tk.X, padx=10, pady=10) |
||||||
|
|
||||||
|
return monLabel |
||||||
|
|
||||||
|
def creer_label_img_1(self:tk.Tk, conteneur, fichier_image:str) -> tk.Label: |
||||||
|
|
||||||
|
if fichier_image: |
||||||
|
objet_image_PIL = Img.open(fichier_image) |
||||||
|
objet_image_PIL = objet_image_PIL.resize( (TAILLE_IMG, TAILLE_IMG) ) |
||||||
|
objet_image_tk = ImageTk.PhotoImage(objet_image_PIL) |
||||||
|
self.image_1 = objet_image_tk |
||||||
|
else: |
||||||
|
self.image_1 = self.IMAGE_VIDE |
||||||
|
|
||||||
|
zone_image = tk.Label(conteneur, image=self.image_1) |
||||||
|
zone_image.configure(bg=FOND_IMAGE) |
||||||
|
zone_image.pack(side=tk.TOP, ipadx=10, ipady=10) |
||||||
|
|
||||||
|
return zone_image |
||||||
|
|
||||||
|
def creer_label_img_2(self:tk.Tk, conteneur, fichier_image:str) -> tk.Label: |
||||||
|
|
||||||
|
if fichier_image: |
||||||
|
objet_image_PIL = Img.open(fichier_image) |
||||||
|
objet_image_PIL = objet_image_PIL.resize( (TAILLE_IMG, TAILLE_IMG) ) |
||||||
|
objet_image_tk = ImageTk.PhotoImage(objet_image_PIL) |
||||||
|
self.image_2 = objet_image_tk |
||||||
|
else: |
||||||
|
self.image_2 = self.IMAGE_VIDE |
||||||
|
|
||||||
|
zone_image = tk.Label(conteneur, image=self.image_2) |
||||||
|
zone_image.configure(bg=FOND_IMAGE) |
||||||
|
zone_image.pack(side=tk.BOTTOM, ipadx=10, ipady=10) |
||||||
|
|
||||||
|
return zone_image |
||||||
|
|
||||||
|
def gestion_actions(self, event): |
||||||
|
if self.fonction: |
||||||
|
self.fonction(event) |
||||||
|
|
||||||
|
# DECLARATION DES METHODES D'INTERFACE |
||||||
|
|
||||||
|
def signaler_evenement(self, f): |
||||||
|
'''Lance un appel à la fonction f transmise lors de l'appui sur une touche''' |
||||||
|
self.fonction = f |
||||||
|
|
||||||
|
def configuration_scene(self, configuration_voulue:list): |
||||||
|
'''Modifie l'affichage sur le GUI''' |
||||||
|
self.afficher_txt_1(configuration_voulue[0]) |
||||||
|
self.afficher_txt_2(configuration_voulue[1]) |
||||||
|
self.afficher_img_1(configuration_voulue[2]) |
||||||
|
self.afficher_img_2(configuration_voulue[3]) |
||||||
|
self.afficher_txt_3(configuration_voulue[4]) |
||||||
|
|
||||||
|
def afficher_txt_1(self, texte:str): |
||||||
|
'''Modifie le texte visible dans la zone de texte en haut à gauche''' |
||||||
|
#largeur_max_ligne = max(map(len, texte.split('\n'))) |
||||||
|
#zone_texte.configure(width=largeur_max_ligne) |
||||||
|
self.label_txt_1.configure(text=texte) |
||||||
|
|
||||||
|
def afficher_txt_2(self, texte:str): |
||||||
|
'''Modifie le texte visible dans la zone de texte en haut à gauche''' |
||||||
|
#largeur_max_ligne = max(map(len, texte.split('\n'))) |
||||||
|
#zone_texte.configure(width=largeur_max_ligne) |
||||||
|
self.label_txt_2.configure(text=texte) |
||||||
|
|
||||||
|
def afficher_txt_3(self, texte:str): |
||||||
|
'''Modifie le texte visible dans la zone de texte en haut à gauche''' |
||||||
|
#largeur_max_ligne = max(map(len, texte.split('\n'))) |
||||||
|
#zone_texte.configure(width=largeur_max_ligne) |
||||||
|
self.label_txt_3.configure(text=texte) |
||||||
|
|
||||||
|
def afficher_img_1(self, fichier_image:str): |
||||||
|
'''Modifie le texte visible dans la zone de texte en haut à gauche''' |
||||||
|
if fichier_image: |
||||||
|
objet_image_PIL = Img.open(fichier_image) |
||||||
|
objet_image_PIL = objet_image_PIL.resize( (TAILLE_IMG, TAILLE_IMG) ) |
||||||
|
objet_image_tk = ImageTk.PhotoImage(objet_image_PIL) |
||||||
|
self.image_1 = objet_image_tk |
||||||
|
else: |
||||||
|
self.image_1 = self.IMAGE_VIDE |
||||||
|
|
||||||
|
self.label_img_1.configure(image=self.image_1) |
||||||
|
|
||||||
|
def afficher_img_2(self, fichier_image:str): |
||||||
|
'''Modifie le texte visible dans la zone de texte en haut à gauche''' |
||||||
|
if fichier_image: |
||||||
|
objet_image_PIL = Img.open(fichier_image) |
||||||
|
objet_image_PIL = objet_image_PIL.resize( (TAILLE_IMG, TAILLE_IMG) ) |
||||||
|
objet_image_tk = ImageTk.PhotoImage(objet_image_PIL) |
||||||
|
self.image_2 = objet_image_tk |
||||||
|
else: |
||||||
|
self.image_2 = self.IMAGE_VIDE |
||||||
|
|
||||||
|
self.label_img_2.configure(image=self.image_2) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# PROGRAMME PRINCIPAL |
||||||
|
|
||||||
|
if __name__ == '__main__': |
||||||
|
application = IHM() |
@ -0,0 +1,56 @@ |
|||||||
|
# Importations |
||||||
|
|
||||||
|
import interface # Dépendances : PIL(Pillow) et tkinter |
||||||
|
import donnees |
||||||
|
|
||||||
|
|
||||||
|
# Déclaration des fonctions |
||||||
|
|
||||||
|
def ihm_signale_evenement(evenement:'tkinter.Event', manoir:'Manoir', ihm:'IHM') -> None: |
||||||
|
"""Fonction où on récupère des informations sur l'événément reçu via l'IHM""" |
||||||
|
|
||||||
|
# On récupère la touche sur laquelle on vient d'appuyer |
||||||
|
touche = evenement.char |
||||||
|
print(f"\nEVENEMENT RECU : {evenement}") # Permet de voir le vrai événement |
||||||
|
print(f"CODE PERSO : {touche}") # L'IHM permet de connaitre la touche utilisée |
||||||
|
|
||||||
|
# Il faut maintenant gérer l'événement : modifier les données et redemander une affichage à l'IHM |
||||||
|
|
||||||
|
h = manoir.heros |
||||||
|
if touche == 'N' or touche == 'n': |
||||||
|
if h.aller_nord(): # Si aller au nord est possible et c'est bien passé |
||||||
|
modifier_affichage(manoir, ihm) |
||||||
|
if touche == 'S' or touche == 's': |
||||||
|
if h.aller_sud(): # Si aller au sud est possible et c'est bien passé |
||||||
|
modifier_affichage(manoir, ihm) |
||||||
|
if touche == 'Q' or touche == 'q': |
||||||
|
if h.aller_ouest(): # Si aller a l'ouest est possible et c'est bien passé |
||||||
|
modifier_affichage(manoir, ihm) |
||||||
|
if touche == 'D' or touche == 'd': |
||||||
|
if h.aller_est(): # Si aller a l'est est possible et c'est bien passé |
||||||
|
modifier_affichage(manoir, ihm) |
||||||
|
if touche == 'C' or touche == 'c': |
||||||
|
if h.combattre_monstre_actuel(): # Si combattre est possible et c'est bien passé |
||||||
|
modifier_affichage(manoir, ihm) |
||||||
|
|
||||||
|
def modifier_affichage(manoir:'Manoir', ihm:'IHM') -> None: |
||||||
|
"""Modifie les 5 champs de l'interface graphique""" |
||||||
|
h = manoir.heros |
||||||
|
ihm.afficher_txt_1( h.observer() ) # affiche le texte descriptif |
||||||
|
ihm.afficher_txt_2( h.reflechir() ) # affiche les actions possibles |
||||||
|
ihm.afficher_txt_3( h.get_carac() ) # affiche les caractéristiques du héros |
||||||
|
ihm.afficher_img_1( h.lieu.image ) # affiche l'image éventuelle du lieu |
||||||
|
if h.lieu.occupant: |
||||||
|
ihm.afficher_img_2( h.lieu.occupant.img) # affiche l'image éventuelle du monstre |
||||||
|
|
||||||
|
|
||||||
|
# PROGRAMME PRINCIPAL |
||||||
|
|
||||||
|
# Création des données et de l'interface graphique |
||||||
|
m = donnees.peupler_manoir() # Création des données du manoir |
||||||
|
ihm = interface.IHM() # Création de l'interface graphique |
||||||
|
|
||||||
|
# ihm_signale_evenement va récupérer les événements sur l'ihm |
||||||
|
ihm.signaler_evenement(lambda event: ihm_signale_evenement(event, m, ihm)) |
||||||
|
|
||||||
|
modifier_affichage(m, ihm) |
Loading…
Reference in new issue