Browse Source

Upload files to 'projet_final'

master
Dorian.D 10 months ago
parent
commit
d7f208c6f7
  1. 266
      projet_final/interface.py
  2. 105
      projet_final/jeu.py
  3. BIN
      projet_final/limace.jpg
  4. BIN
      projet_final/manoir-hante.jpg
  5. BIN
      projet_final/piscine.jpg

266
projet_final/interface.py

@ -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()

105
projet_final/jeu.py

@ -0,0 +1,105 @@
# Importations
import interface # Dépendances : PIL(Pillow) et tkinter
import donnees
import sys
import pickle
# Déclaration des fonctions pour la sauvegarde
def sauvegarder_jeu(manoir, fichier):
with open(fichier, 'wb') as f:
pickle.dump(manoir, f)
def charger_jeu(fichier):
with open(fichier, 'rb') as f:
return pickle.load(f)
# Déclaration des fonctions pour le fichier texte
def rediriger_sortie_vers_fichier(fichier_sortie: str):
"""Redirige la sortie de la console vers un fichier texte."""
sys.stdout = open(fichier_sortie, "a")
sys.stderr = sys.stdout
def restaurer_sortie_console():
"""Restaure la sortie de la console après la redirection vers un fichier."""
sys.stdout.close()
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
# 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 == 'X' or touche == 'x':
sauvegarder_jeu(manoir, "sauvegarde_jeu.pkl")
print("Jeu sauvegardé.")
elif touche == 'V' or touche == 'v':
try:
manoir = charger_jeu("sauvegarde_jeu.pkl")
modifier_affichage(manoir, ihm)
print("Jeu chargé.")
except FileNotFoundError:
print("Aucune sauvegarde trouvée.")
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)
if touche == 'F' or touche == 'f':
if h.fuire(): # Si fuire est possible
modifier_affichage(manoir, ihm)
if touche == 'U' or touche == 'u':
if h.ouvrir(manoir): # Si l'utilisation de la cle fonctionne
modifier_affichage(manoir, ihm)
if touche == 'R' or touche == 'r':
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.img ) # 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
#rediriger_sortie_vers_fichier("sortie_console.txt")
# 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)

BIN
projet_final/limace.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
projet_final/manoir-hante.jpg

Binary file not shown.

BIN
projet_final/piscine.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Loading…
Cancel
Save