def __init__(self, window): """ Constructeur par défaut de l'interface de paramètres (Fond d'écran actif) Prend en paramètre la fenêtre """ GUI.__init__(self, window, True) # Définition des textes des boutons de (dés)activation de la musique et des effets sonores en fonction des paramètres actuels switchMusicMsg = (msgs.DISABLE_MUSIC if window.music_enabled else msgs.ENABLE_MUSIC).clone() switchSoundsMsg = (msgs.DISABLE_SOUNDS if window.sounds_enabled else msgs.ENABLE_SOUNDS).clone() # Création des boutons music = tk.Button(window, bg = utils.BUTTON_BACKGROUND, textvariable = switchMusicMsg, font = ("Plantagenet Cherokee", 30), anchor = "center", width = 22, borderwidth = 4, relief = "raise") sounds = tk.Button(window, bg = utils.BUTTON_BACKGROUND, textvariable = switchSoundsMsg, font = ("Plantagenet Cherokee", 30), anchor = "center", width = 22, borderwidth = 4, relief = "raise") changeLanguage = tk.Button(window, bg = utils.BUTTON_BACKGROUND, textvariable = msgs.CHANGE_LANGUAGE, font = ("Plantagenet Cherokee", 30), anchor = "center", width = 22, borderwidth = 4, relief = "raise", command = msgs.switchLanguage) controls = tk.Button(window, bg = utils.BUTTON_BACKGROUND, textvariable = msgs.CHANGE_CONTROLS, font = ("Plantagenet Cherokee", 30), anchor = "center", width = 22, borderwidth = 4, relief = "raise", command = lambda : Controls(window)) back = tk.Button(window, bg = utils.BUTTON_BACKGROUND, textvariable = msgs.BACK, font = ("Plantagenet Cherokee", 30), anchor = "center", width = 15, borderwidth = 4, relief = "groove", command = lambda : guis.back(window)) # Affichage des boutons music.place(relx = .025, rely = .25, relwidth = .42, relheight = .11) sounds.place(relx = .025, rely = .37, relwidth = .42, relheight = .11) changeLanguage.place(relx = .025, rely = .49, relwidth = .42, relheight = .11) controls.place(relx = .025, rely = .61, relwidth = .42, relheight = .11) back.place(relx = .74, rely = .88, relwidth = .26, relheight = .12) def switchMusicState(): """ Change l'état d'activation de la musique La musique est lancée dans le sous-module audio """ if window.music_enabled: switchMusicMsg.switch(msgs.ENABLE_MUSIC) else: switchMusicMsg.switch(msgs.DISABLE_MUSIC) window.music_enabled ^= True saveSettings() def switchSoundsState(): """ Change l'état d'activation des effets sonores """ if window.sounds_enabled: switchSoundsMsg.switch(msgs.ENABLE_SOUNDS) else: switchSoundsMsg.switch(msgs.DISABLE_SOUNDS) window.sounds_enabled ^= True saveSettings() # Affectation des évenements de clics music.config(command = switchMusicState) sounds.config(command = switchSoundsState) # Ajout des enfants self.appendChild(music) self.appendChild(sounds) self.appendChild(changeLanguage) self.appendChild(controls) self.appendChild(back)
def __init__(self, window): """ Constructeur par défaut de l'interface du menu multijoueur Prend comme argument la fenêtre Ce menu n'est absolument pas encore travaillé et n'est là qu'en prévision """ GUI.__init__(self, window, True) # Création des boutons local = tk.Button(window, textvariable=msgs.LOCAL, font=("Plantagenet Cherokee", 30), anchor="center", width=15, borderwidth=4, bg=utils.BUTTON_BACKGROUND, relief="raise", command=lambda: utils.showMessageDialog( msgs.SOON, msgs.FUTURE_FEATURE)) online = tk.Button(window, textvariable=msgs.ONLINE, font=("Plantagenet Cherokee", 30), anchor="center", width=15, borderwidth=4, bg=utils.BUTTON_BACKGROUND, relief="raise", command=lambda: utils.showMessageDialog( msgs.SOON, msgs.FUTURE_FEATURE)) backBtn = tk.Button(window, textvariable=msgs.BACK, font=("Plantagenet Cherokee", 30), anchor="center", width=15, borderwidth=4, bg=utils.BUTTON_BACKGROUND, relief="raise", command=lambda: back(window)) # Affichage et positionnement des boutons sur l'interface local.place(relx=.025, rely=.37, relwidth=.42, relheight=.11) online.place(relx=.025, rely=.49, relwidth=.42, relheight=.11) backBtn.place(relx=.74, rely=.88, relwidth=.26, relheight=.12) # Ajout des boutons comme enfants self.appendChild(local) self.appendChild(online) self.appendChild(backBtn)
def init_globals(): g.randomizer = Randomizer() g.debug = Debugger() g.console = Console() g.analyzer = Analyzer() g.modeller = Modeller(g.analyzer) g.gui = GUI(plotter, g.analyzer, g.modeller) g.output_file_formatter = OutputFileFormatter()
def __init__(self, window: tk.Tk, gameBuilder: GameBuilder): """ Constructeur par défaut du sélecteur de voiture Prend comme argument la fenêtre et le constructeur de partie """ GUI.__init__(self, window) self.builder = gameBuilder # master représente un cadre dans lequel sera incorporé le sélecteur ainsi que les barres de défilement master = tk.Frame(window, width=window.winfo_screenwidth(), height=window.winfo_screenheight()) master.place(x=0, y=0, relwidth=1, relheight=1) self.appendChild(master) # Création des barres de défilement vscrollbar = tk.Scrollbar(master, orient=tk.VERTICAL) hscrollbar = tk.Scrollbar(master, orient=tk.HORIZONTAL) vscrollbar.pack(side=tk.RIGHT, fill=tk.Y, expand=tk.FALSE) hscrollbar.pack(side=tk.BOTTOM, fill=tk.X, expand=tk.FALSE) self.appendChild(vscrollbar) self.appendChild(hscrollbar) # Afin de pouvoir déplacer la fenêtre, nécessité de passer par un canevas # x(y)scrollcommand : Contrôle la taille des barres de défilement # scrollregion : Définit la zone de défilement (pour des raisons obscrures, nécessité de définir cela de façon statique) canvas = tk.Canvas(master, xscrollcommand=hscrollbar.set, yscrollcommand=vscrollbar.set, width=window.winfo_screenwidth(), height=window.winfo_screenheight(), scrollregion="0 0 %s %s" % (window.winfo_screenwidth() + 54, window.winfo_screenheight() - 100)) # Création du cadre dans lequel seront déposés les composants frame = tk.Frame(canvas, width=window.winfo_screenwidth(), height=window.winfo_screenheight()) # Placement du cadre dans le canevas canvas.create_window(0, 0, window=frame, anchor=tk.NW) # Placement du canevas canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=tk.FALSE) canvas.xview_moveto(0) canvas.yview_moveto(0) # Définition de l'action des barres de défilement (déplacer le canevas) vscrollbar.config(command=canvas.yview) hscrollbar.config(command=canvas.xview) for i in range(len(cars.CARS)): # Pour chaque voiture, affichae d'une ligne d'informations car = cars.CARS[i] # Chargement de l'image de miniature grâce au module PIL image = Image.open("images/thumbnails/" + car.thumbnail_file) # Redimensionnement de l'image en 100x100 avec anti-crénelage image = image.resize((100, 100), Image.ANTIALIAS) # Remplacement de l'image image.save("images/thumbnails/" + car.thumbnail_file, car.thumbnail_file[-3:]) # Conversion de l'image en Tkinter thumbnail = tk.PhotoImage(file="images/thumbnails/" + car.thumbnail_file) # Passage de l'image en Label et placement dans l'interface thumbnailLabel = tk.Label(frame, image=thumbnail) thumbnailLabel.image = thumbnail thumbnailLabel.grid(row=5 * i, column=0, rowspan=4) # Affichage du nom de la voiture label = tk.Label(frame, textvariable=car.name, font=("Plantagenet Cherokee", 30)) label.grid(row=5 * i, column=1, rowspan=4) # Affichage de la vitesse de la voiture speedLabel = tk.Label(frame, textvariable=msgs.MAX_SPEED.format( car.max_speed), font=("Plantagenet Cherokee", 16)) speedLabel.grid(row=5 * i, column=2) # Affichage de la capacité d'accélération de la voiture accelerateLabel = tk.Label(frame, textvariable=msgs.ACCELERATION.format( 60 * car.acceleration), font=("Plantagenet Cherokee", 16)) accelerateLabel.grid(row=5 * i + 1, column=2) # Affichage de la taille de la voiture sizeLabel = tk.Label(frame, textvariable=msgs.SIZE.format( car.width, car.height), font=("Plantagenet Cherokee", 16)) sizeLabel.grid(row=5 * i + 2, column=2) # Affichage de la maniabilité de la voiture (présenté comme unité arbitraire sans réellement en être une) maniabilityLabel = tk.Label(frame, textvariable=msgs.MANIABILITY.format( 2 * car.maniability), font=("Plantagenet Cherokee", 16)) maniabilityLabel.grid(row=5 * i + 3, column=2) # Affichage du bouton de sélection choose = tk.Button(frame, textvariable=msgs.CHOOSE, bg=utils.BUTTON_BACKGROUND, font=("Plantagenet Cherokee", 22)) choose.grid(row=5 * i, column=3, rowspan=4) # Si la voiture a déjà été choisie (pour modification), affichage d'un check à côté if self.builder.car == car: ok = tk.Label(frame, text="ü", font=("Wingdings", 42)) ok.grid(row=5 * i, column=4, rowspan=4) self.appendChild(ok) # Si ce n'est pas la dernière voiture, affichage d'une ligne grisée if i < len(cars.CARS) - 1: canvas = tk.Canvas(frame, width=window.winfo_screenwidth(), height=5, bg="lightgray") canvas.grid(row=5 * i + 4, columnspan=4) self.appendChild(canvas) # Inscription de l'écouteur pour le click du bouton de sélection self.registerChooseListener(window, choose, car) # Ajout de tous les composants comme enfants self.appendChild(frame) self.appendChild(thumbnailLabel) self.appendChild(label) self.appendChild(speedLabel) self.appendChild(accelerateLabel) self.appendChild(sizeLabel) self.appendChild(maniabilityLabel) self.appendChild(choose) # Ajout du bouton retour backBtn = tk.Button(frame, textvariable=msgs.BACK, bg=utils.BUTTON_BACKGROUND, font=("Plantagenet Cherokee", 30), anchor="center", width=20, borderwidth=10, relief="groove", command=lambda: back(window)) backBtn.grid(row=5 * (len(cars.CARS) + 1), columnspan=4, pady=100) self.appendChild(backBtn) # Configuration des poids (rapports de longueur) de chaque colonne frame.columnconfigure(0, weight=1) frame.columnconfigure(1, weight=2) frame.columnconfigure(2, weight=3) frame.columnconfigure(3, weight=2) frame.columnconfigure(4, weight=1) # Mise à jour de la zone de scroll lorsque le cadre est redimensionné # En apparence mystérieusement non fonctionnel # noinspection PyUnusedLocal def _configure_frame(eventf): size = (frame.winfo_reqwidth(), frame.winfo_reqheight()) canvas.config(scrollregion="0 0 %s %s" % size) frame.bind("<Configure>", _configure_frame)
def __init__(self, window: tk.Tk, gameBuilder: GameBuilder): """ Constructeur par défaut du sélecteur de carte Prend comme argument la fenêtre et le constructeur de partie """ GUI.__init__(self, window) self.builder = gameBuilder for i in range(len(maps.MAPS)): # Pour chaque carte, affiche une ligne d'informations et de sélection map = maps.MAPS[i] # Lecture de l'image de miniature grâce au module PIL image = Image.open("images/thumbnails/" + map.thumbnail) # Redimensionnement de l'image en 100x100 avec anti-crénelage image = image.resize((100, 100), Image.ANTIALIAS) # Remplacement de l'ancien fichier image.save("images/thumbnails/" + map.thumbnail, map.thumbnail[-3:]) # Conversion de l'image en image Tkinter thumbnail = tk.PhotoImage(file="images/thumbnails/" + map.thumbnail) # Placement de l'image dans un label et positionnement dans l'interface thumbnailLabel = tk.Label(window, image=thumbnail) thumbnailLabel.image = thumbnail thumbnailLabel.grid(row=i, column=0, rowspan=1) # Affichage du nom de la carte label = tk.Label(window, textvariable=map.name, font=("Plantagenet Cherokee", 30)) label.grid(row=i, column=1, rowspan=1) # Affichage de la taille (en pixels) de la carte sizeLabel = tk.Label(window, textvariable=msgs.SIZE.format( map.width, map.height), font=("Plantagenet Cherokee", 22)) sizeLabel.grid(row=i, column=2) # Affichage du bouton de sélection de la carte choose = tk.Button(window, textvariable=msgs.CHOOSE, bg=utils.BUTTON_BACKGROUND, font=("Plantagenet Cherokee", 22)) choose.grid(row=i, column=3, rowspan=1) # Si une carte était déjà sélectionné, affichage d'un check à côté if self.builder.map == map: ok = tk.Label(window, text="ü", font=("Wingdings", 42)) ok.grid(row=i, column=4, rowspan=1) self.appendChild(ok) # Inscription de l'écouteur pour le clic du bouton self.registerChooseListener(window, choose, map) # Ajout des enfants self.appendChild(thumbnailLabel) self.appendChild(label) self.appendChild(sizeLabel) self.appendChild(choose) # Configuration des poids des colonnes window.columnconfigure(0, weight=1) window.columnconfigure(1, weight=2) window.columnconfigure(2, weight=3) window.columnconfigure(3, weight=2) window.columnconfigure(4, weight=1) # Affichage du bouton retour backBtn = tk.Button(window, textvariable=msgs.BACK, font=("Plantagenet Cherokee", 30), bg=utils.BUTTON_BACKGROUND, anchor="center", width=20, borderwidth=10, relief="groove", command=lambda: back(window)) backBtn.grid(row=len(cars.CARS) * 2 + 1, column=0, columnspan=5, pady=100) self.appendChild(backBtn)
def __init__(self, window): """ Constructeur par défaut de l'interface du menu un joueur Prend comme argument la fenêtre """ GUI.__init__(self, window, True) # builder représente le constructeur de partie actuel (créé si inexistant) builder = GameBuilder.CURRENT_GAME_BUILDER if builder is None: builder = GameBuilder.CURRENT_GAME_BUILDER = GameBuilder( GameBuilder.SINGLE_PLAYER_MODE) # Création des boutons car = tk.Button(window, textvariable=msgs.CAR_CHOICE, font=("Plantagenet Cherokee", 30), anchor="center", width=15, borderwidth=4, bg=utils.BUTTON_BACKGROUND, relief="raise", command=lambda: CarChooser(window, builder)) chooseMap = tk.Button(window, textvariable=msgs.MAP_CHOICE, font=("Plantagenet Cherokee", 30), anchor="center", width=15, borderwidth=4, bg=utils.BUTTON_BACKGROUND, relief="raise", command=lambda: MapChooser(window, builder)) start = tk.Button(window, textvariable=msgs.START, font=("Plantagenet Cherokee", 30), anchor="center", width=15, borderwidth=4, bg=utils.BUTTON_BACKGROUND, relief="raise", state=tk.DISABLED if builder.car is None or builder.map is None else tk.NORMAL, command=lambda: builder.start(window)) backBtn = tk.Button(window, textvariable=msgs.BACK, font=("Plantagenet Cherokee", 30), anchor="center", width=15, borderwidth=4, bg=utils.BUTTON_BACKGROUND, relief="raise", command=lambda: back(window)) # Positionnement des boutons sur l'interface car.place(relx=.025, rely=.25, relwidth=.42, relheight=.11) chooseMap.place(relx=.025, rely=.37, relwidth=.42, relheight=.11) start.place(relx=.025, rely=.49, relwidth=.42, relheight=.11) backBtn.place(relx=.74, rely=.88, relwidth=.26, relheight=.12) # Ajout des boutons comme enfants self.appendChild(car) self.appendChild(chooseMap) self.appendChild(start) self.appendChild(backBtn)
def __init__(self, window : tk.Tk): """ Constructeur par défaut du menu de scores Prend comme argument la fenêtre et le constructeur de partie """ GUI.__init__(self, window) # Création du bouton retour backBtn = tk.Button(window, textvariable = msgs.BACK, font = ("Plantagenet Cherokee", 30), anchor = "center", width = 15, borderwidth = 4, bg = utils.BUTTON_BACKGROUND, relief = "groove", command = lambda : back(window)) backBtn.place(relx = .74, rely = .88, relwidth = .26, relheight = .12) self.appendChild(backBtn) # Détermination du nombre de colonnes (1 colonne pour la carte, 1 colonne pour le temps, 1 colonne pour la voiture, autant de colonnes qui il y a de tours au maximum columns = 3 for map in maps.MAPS: columns = max(columns, map.max_laps + 3) # Définition du poids de chaque colonne à 1 for i in range(columns): window.columnconfigure(i, weight = 1) # Définition et affichage des en-têtes total_time_label = tk.Label(window, textvariable = msgs.TOTAL_TIME, font = ("Plantagenet Cherokee", 18, "bold"), relief = "groove") total_time_label.grid(row = 0, column = 1, sticky = "nsew") self.appendChild(total_time_label) car_label = tk.Label(window, textvariable = msgs.CAR, font = ("Plantagenet Cherokee", 18, "bold"), relief = "groove") car_label.grid(row = 0, column = columns - 1, sticky = "nsew") self.appendChild(car_label) # Affichage des en-têtes des temps par tour for lap in range(0, columns - 3): lap_time_label = tk.Label(window, textvariable = msgs.LAP_TIME.format(lap + 1), font = ("Plantagenet Cherokee", 18, "bold"), relief = "groove") lap_time_label.grid(row = 0, column = lap + 2, sticky = "nsew") self.appendChild(lap_time_label) # Curseur donnant la ligne actuelle du tableau row_index = 1 for map_index in range(len(maps.MAPS)): # Pour chaque carte, récupérer la liste des scores triés par le temps effectués sur cette carte map = maps.MAPS[map_index] map_scores = list() for score in utils.SCORES: if score.map == map: map_scores.append(score) map_scores.sort() # Afficher le nom de la carte à gauche mapLabel = tk.Label(window, textvariable = map.name, font = ("Plantagenet Cherokee", 18, "bold"), relief = "groove") mapLabel.grid(row = row_index, column = 0, rowspan = max(1, len(map_scores)), sticky = "nsew") self.appendChild(mapLabel) for score in map_scores: # Pour chaque score, afficher le temps total et la voiture utilisée total_time_label = tk.Label(window, text = score.total_time, font = ("Plantagenet Cherokee", 18), relief = "groove") total_time_label.grid(row = row_index, column = 1, sticky = "nsew") self.appendChild(total_time_label) car_label = tk.Label(window, textvariable = score.car.name, font = ("Plantagenet Cherokee", 18), relief = "groove") car_label.grid(row = row_index, column = columns - 1, sticky = "nsew") self.appendChild(car_label) for lap in range(map.max_laps): # Pour chaque tour, afficher le temps effectué lap_time_label = tk.Label(window, text = score.laps_time[lap], font = ("Plantagenet Cherokee", 18), relief = "groove") lap_time_label.grid(row = row_index, column = lap + 2, sticky = "nsew") self.appendChild(lap_time_label) # Incrémenter le compteur de ligne row_index += 1
def __init__(self, window, builder): """ Constructeur par défaut de l'interface de jeu Prend en paramètres la fenêtre ainsi que le constructeur de partie """ GUI.__init__(self, window) # Affectation de quelques constantes self.window = window self.raw_car = builder.car self.map = builder.map # Création du canevas à la taille de la fenêtre self.width, self.height = window.winfo_width(), window.winfo_height() if window.state() == "zoomed": self.width, self.height = window.winfo_screenwidth( ), window.winfo_screenheight() self.canvas = tk.Canvas(window, width=window.winfo_screenwidth(), height=window.winfo_screenheight(), bg="green") # Ouverture du fond de carte par le module PIL img_temp = Image.open("images/maps/" + self.map.img_file) # Convertit si nécessaire la carte en RGBA (Rouge-Vert-Bleu-Alpha) img_temp = img_temp.convert("RGBA") # Redimensionne le fond à la taile de la fenêtre img_temp = img_temp.resize((self.width, self.height), Image.ANTIALIAS) # Conversion de l'image en image Tkinter self.background_img = ImageTk.PhotoImage(img_temp) # Création de l'image dans le canevas self.background = self.canvas.create_image(self.width, self.height, image=self.background_img, anchor=tk.NW) # Affichage du canevas et positionnement self.canvas.focus_set() self.canvas.pack() # Lorsque la fenêtre est reconfigurée redimensionnée, réduite, ...), invocation de la fonction on_resize(voir plus bas) window.bind("<Configure>", lambda event: self.on_resize(event)) # Affichage du chronomètre self.time_label = tk.Label(window, text="00:00:00.000", font=("Plantagenet Cherokee", 24), fg="white", bg="black") self.time_label.place(x=0, y=0) self.appendChild(self.time_label) # Affichage du compte-tours self.lap = 0 self.lap_label = tk.Label(window, text=msgs.LAP_NUMBER.get().format( self.lap, self.map.max_laps), font=("Plantagenet Cherokee", 24), fg="white", bg="black") self.lap_label.place(x=0, y=self.time_label.winfo_reqheight(), width=self.time_label.winfo_reqwidth()) self.appendChild(self.lap_label) # Création de l'objet Voiture (qui se déplacera sur la carte, ne contennant plus que les infos de base) self.car = Car(window, self) # Initialisation du temps de course à -1, il se mettra à 0 dès la première action de l'utilisateur self.time = -1 # Ajout du canevas comme enfant self.appendChild(self.canvas) # Actualisation de la fenêtre window.config(width=window.winfo_width())