I'm working on the pygame code for a game. I have a problem with the characters in my game: I can't instantiate characters (npcs) that aren't in the main map. As my other maps are not loaded at launch, my code gives me an error saying that the characters (npcs) of my code do not exist. How can I instantiate the characters of another map than the main one, so as not to have an error?.
Here is my code, thanks a lot for your help!
from dataclasses import dataclass
import playsound as playsound
import pygame, pytmx, pyscroll
from src.player import NPC
#dataclass
class Portal:
from_world: str
origin_point: str
target_world: str
teleport_point: str
#dataclass
class Music:
musicCarte: str # cette data classe permet de ranger les musqiue dans une liste , pareil pour les portails en haut
#dataclass
class Map:
name: str
walls: list[pygame.Rect]
group: pyscroll.PyscrollGroup
tmx_data: pytmx.TiledMap
portail: list[Portal]
# création des listes
npcs: list[NPC]
music: str
class MapManager:
def __init__(self, screen, player,):
self.maps = dict() # "house -> Map("House", walls, group)
self.screen = screen # permet davoir le screen des cartes pour l'afficher
self.player = player # donne accées au joueur
self.current_map = "CrapouliWolrd"
self.map2 = "village"
self.register_map("CrapouliWolrd", portail=[
Portal(from_world="CrapouliWolrd", origin_point="enter_house", target_world="Maison_perso",
teleport_point="spawn_house", ),
# ici on rentre les nouvelles maps avec leurs musique et leurs portails
Portal(from_world="CrapouliWolrd", origin_point="enter_Foret", target_world="Foret",
teleport_point="spawn_Foret", )],
npcs=[
NPC("Perso", nb_points=2)],
music="../music/scandinavianz-nature-7504.mp3"
)
self.register_map("Maison_perso", portail=[
Portal(from_world="Maison_perso", origin_point="exit_house", target_world="CrapouliWolrd",
teleport_point="spawn_sortie",)
], music="../music/mercantile-the-legend-of-zelda-the-wind-waker-hd-ost.mp3")
self.register_map("village", portail=[
Portal(from_world="village", origin_point="entrer_house", target_world="Maison_perso",
teleport_point="spawn_house", ),
Portal(from_world="village", origin_point="exit_village", target_world="Foret",
teleport_point="spawn_Foret", )
] , npcs=[
NPC("paul", nb_points=4),
NPC("robin", nb_points=1)
]
)
self.register_map("Foret", portail=[
Portal(from_world="Foret", origin_point="exit_foret", target_world="CrapouliWolrd",
teleport_point="spawn_zone1", ),
Portal(from_world="Foret", origin_point="enter_village", target_world="village",
teleport_point="spawn_village"),
], # music="../music/mercantile-the-legend-of-zelda-the-wind-waker-hd-ost.mp3"
)
self.teleport_player("Player")
self.teleport_npcs()
def check_collisions(self):
# portails
for Portal in self.get_map().portail:
if Portal.from_world == self.current_map:
point = self.get_object(Portal.origin_point)
rect = pygame.Rect(point.x, point.y, point.width, point.height)
if self.player.feet.colliderect(rect):
copy_portal = Portal
self.current_map = Portal.target_world
self.teleport_player(copy_portal.teleport_point)
# collision
for sprite in self.get_group().sprites():
if sprite.feet.collidelist(self.get_walls()) > -1:
sprite.move_back()
def teleport_player(self, name,):
point = self.get_object(name)
self.player.position[0] = point.x
self.player.position[1] = point.y
self.player.save_location()
#pygame.mixer.Sound(self.get_map().music).play()
def register_map(self, name, portail=[],
npcs=[], music=[]): # oublie pas de remettre la musique # on renseigne les listes ici
tmx_data = pytmx.util_pygame.load_pygame(
f"../Map/{name}.tmx") # PERMET DOUVRIR LA MAP SUIVANT SON NOM ! grace a f""
map_data = pyscroll.data.TiledMapData(tmx_data)
map_layer = pyscroll.orthographic.BufferedRenderer(map_data, self.screen.get_size())
map_layer.zoom = 3
# DEFINIt la liste des rectangle de collision
walls = [] ##et donc plus besoisn davoir self.walls pouisque le self est initialisé au debut
for obj in tmx_data.objects:
if obj.type == "colision":
walls.append(pygame.Rect(obj.x, obj.y, obj.width, obj.height))
# dessiner le groupe de calques
group = pyscroll.PyscrollGroup(map_layer=map_layer, default_layer=6)
group.add(self.player) # ici on instancie le joueur dans les calques
# RECUPERER TOUT LES NPCS POUR LES AJOUTER AU GROUPE
for npc in npcs:
group.add(npc)
# cree un onjet map
self.maps[name] = Map(name, walls, group, tmx_data, portail, npcs, music)
def get_map(self):
return self.maps[self.current_map] # CETTE FONCTIOn permet d'afficher l'actuelle carte qui est en currentmap soit ici CrapouliWOrld
def get_group(self):
return self.get_map().group # recupere le joueur dans la carte
def get_walls(self):
return self.get_map().walls # recupere les murs de la maps
def get_object(self, name):
return self.get_map().tmx_data.get_object_by_name(name)
def teleport_npcs(self):
for map in self.maps:
map_data = self.maps[map]
npcs = map_data.npcs
for npc in npcs:
npc.load_points(self)
npc.teleport_spawn()
# permet de rentrer simplement get_object pour faire allusion a un objet du decors
def draw(self):
self.get_group().draw(self.screen)
self.get_group().center(self.player.rect.center)
def update(self):
self.get_group().update()
self.check_collisions()
for npc in self.get_map().npcs:
npc.move()
Error: KeyError: 'paul_path1'
Related
Is there any data structures in python that would enable me to implement a priority queue based on a basic priority and the time passed in queue ?
It would help me avoid that some element in this queue starve.
From what I know the object Queue is only based on the time element enter in it, and the object PriorityQueue is only based on a priority so it will possibly lead to starving element.
As I couldn't find what I wanted, I created this little class to meet my needs.
class PriorityQueue(object):
"""
PriorityQueue supportant des objets de type dict.
Cette Queue base sa priorité sur deux éléments.
Le premier est une priorité de base.
Le second est une priorité qui se contruit au fur et à mesure du temps passé
dans la queue.
"""
import time
def __init__(self, seconde_pour_augmenter_priorite:int = 5):
"""
param :
seconde_pour_augmenter_priorite :
Variable qui permet de savoir le nombre de seconde nécessaire passé
dans la queue pour augmenter le niveau de priorité
"""
self.queue = []
self.spap = seconde_pour_augmenter_priorite
def __str__(self):
"""
toString
"""
return ' '.join([str(i) for i in self.queue])
def sizeq(self):
return len(self.queue)
def isEmpty(self):
"""
Vérifier si la queue est vide
"""
return len(self.queue) == 0
def insert(self, data):
"""
Insérer un élément dans la queue
"""
data["temps-entre-queue"] = self.time.time()
self.queue.append(data)
def __calculer_priorite(self, data:dict, temps:float):
return data["priorite"] + (temps - data["temps-entre-queue"]) / self.spap
def pop(self):
"""
Pour retirer de la file d'attente l'élément avec la plus haute priorité
"""
try:
temps = self.time.time()
max_val = 0
for i in range(len(self.queue)):
if self.__calculer_priorite(self.queue[i], temps) > self.__calculer_priorite(self.queue[max_val], temps):
max_val = i
item = self.queue[max_val]
del self.queue[max_val]
return item
except IndexError:
print()
exit()
so i have this script but i dont know how it worsk can someone please explain it to me , all what i know is that we have two types pf used super user and normal user each one got many taskss
that we excecute after extracting from a file.txt
# Permet de mieux gérer le typing (définition des types lors de la signature fonction)
from future import annotations
# Permet de créer des classes héritant d'énum pour réaliser des énumérations
from enum import Enum
# Gère le multithreading
import threading
# Mise en pause du programme via time.sleep()
import time
# Lecture de la mémoire utilisée
import os, psutil
# Interface graphique
import turtle
import tkinter as tk
from tkinter import ttk
# Shuffle permet de mélanger une liste (utilisé pour la liste des story)
from random import shuffle
__FILENAME__ = "stories.txt"
__KO_SIZE_BYTE__ = 1024
__TIME_TASK_S__ = 5
__NUMBER_BLOCKS_BY_TASK__ = 5
# Booléen permettant de savoir si un super utilisateur a pris la main (mise en pause automatique des utilisateurs normaux)
is_locked_for_super_user = False
### Définition de la classe Block ###
# number_of_block : Nombre de block alloué
# state : status du block (Block.State.FREE ou Block.State.BUSY)
# data : data que le block va stocker (story)
# next_block : reférence du prochaine block
class Block:
_SIZE_ = 512 * __KO_SIZE_BYTE__
class State(Enum):
FREE = 0
BUSY = 1
def __init__(self, number_of_blocks : int, state : Block.State, data : str, next_block : Block = None):
self.number_of_blocks = number_of_blocks
self.state = state
self.data = bytearray(data, encoding="utf-8")
self.data.extend(bytearray(int((Block._SIZE_ * number_of_blocks )- len(data)), ))
self.next_block = next_block
def add(self,next_block : Block, index : int = 1) -> int:
if self.next_block:
return self.next_block.add(next_block, index + 1)
else:
self.next_block = next_block
return index
### Définition d'une classe MemoryBlock qui représente une liste chainée ###
# block : premier block de la liste chainée
class MemoryBlock:
def __init__(self, block : Block = None ):
self.block = block
def __getitem__(self, key):
if key == 0:
return self.block
item = self.block.next_block
for _ in range(1, key):
item = item.next_block
return item
def add(self, block : Block) -> int:
# manage empty block
if not self.block:
self.block = block
return 0
return self.block.add(block)
def remove(self, key):
if key == 0:
self.block = self.block.next_block
else:
self[key - 1].next_block = self[key].next_block
def size(self) -> int:
if not self.block:
return 0
size = 1
current_block = self.block
while current_block.next_block:
current_block = current_block.next_block
size+= 1
return size
### Classe Task ###
# lib_task : Libellé de la tache
# time_task : Temps d'éxécution de la tache en seconde
# mem_task : taille allouée à la tache
# level_task : Priorité de la tache (Task.Priority.HIGH ou Task.Priority.LOW)
# state_task : Etat de la tache (Task.State.ACTIVE ou Task.State.SLEEPING)
# treeView : arbre de l'interface graphique qui affiche l'éxécution des taches
# story : Chaine de caractère à afficher par la tâche en time_task secondes
# block_memory : liste chainée de block
class Task(threading.Thread):
class Priority(Enum):
HIGH = 0
LOW = 1
class State(Enum):
ACTIVE = 0
SLEEPING = 1
def __init__(self, lib_task : str, time_task : int, mem_task : int, level_task : Priority, state_task : State, treeview : ttk.Treeview, story : str, block_memory : MemoryBlock):
self.lib_task = lib_task
self.time_task = time_task
self.index_block = block_memory.add(Block(number_of_blocks=int(mem_task / Block._SIZE_), state= Block.State.BUSY, data = story))
self.story = story
self.block_memory = block_memory
self.level_task = level_task
self.state_task = state_task
self.treeview = treeview
self.block_memory = block_memory
threading.Thread.__init__(self)
def run(self):
self.state_task = Task.State.ACTIVE
data_to_display = self.block_memory[self.index_block].data.decode()[0:len(self.story)]
nb_to_display_each_sec = int(len(data_to_display) / self.time_task)
self.treeview.insert("",'end', text=self.lib_task, values = (self.lib_task, ""))
total_display_chars = nb_to_display_each_sec
global is_locked_for_super_user
for i in range(0, self.time_task + 1):
while self.level_task == Task.Priority.LOW and is_locked_for_super_user:
time.sleep(0.5)
for item in self.treeview.get_children():
if self.treeview.item(item)["text"] == self.lib_task:
self.treeview.item(item, values = (self.lib_task, data_to_display[0:total_display_chars]))
total_display_chars += nb_to_display_each_sec
break
time.sleep(1)
self.treeview.item(item, values = (self.lib_task, data_to_display))
self.state_task = Task.State.SLEEPING
self.block_memory[self.index_block].state = Block.State.FREE
### Thread permettant de gérer l'éxécution de toutes les taches ###
# memoryBlock : liste chainée de block
# stories : liste de chaine de caractères que les taches executerons
# treeView : arbre de l'interface graphique qui affiche l'éxécution des taches
class TaskManager(threading.Thread):
def __init__(self, memoryBlock: MemoryBlock, stories, priority : Task.Priority, treeView : ttk.Treeview):
self.memoryBlock = memoryBlock
self.stories = stories
self.priority = priority
self.treeView = treeView
threading.Thread.__init__(self)
def run(self):
global is_locked_for_super_user
while self.priority == Task.Priority.LOW and is_locked_for_super_user:
time.sleep(0.5)
# launch tasks
shuffle(self.stories)
tasks = []
for index, story in enumerate(self.stories):
task = Task(lib_task="task " + str(index), time_task=__TIME_TASK_S__, mem_task=Block._SIZE_ * __NUMBER_BLOCKS_BY_TASK__, level_task=self.priority, state_task=Task.State.SLEEPING, treeview=self.treeView, story=story, block_memory=self.memoryBlock)
task.start()
tasks.append(task)
# une tache dormante, une fois arrivé son tour d’exécution, elle donne la main à la suivante.
while task.state_task == Task.State.SLEEPING:
time.sleep(0.1)
# Wait until tasks are finished
for t in tasks:
t.join()
### Récupère la mémoire utilisée ###
# Retourne la mémoire utilisée en Mo
def get_memory_usage():
return psutil.Process(os.getpid()).memory_info().rss / __KO_SIZE_BYTE__ / 1024 # Mo
### Lancée par Thread dans le but de superviser le lancement des taches ###
# memoryBlock : liste chainée de block
# stories : liste de chaine de caractères que les taches executerons
# treeView : arbre de l'interface graphique qui affiche l'éxécution des taches
def launch_task_manager(memoryBlock : MemoryBlock, stories, priority : Task.Priority, treeView : ttk.Treeview):
# Clear treeview
for row in treeView.get_children():
treeView.delete(row)
global is_locked_for_super_user
if priority == Task.Priority.HIGH:
is_locked_for_super_user = True
taskManager = TaskManager(memoryBlock, stories, priority, treeView)
taskManager.start()
taskManager.join()
# garbage collector
for i in range(memoryBlock.size() -1, -1, -1):
if memoryBlock[i].state == Block.State.FREE:
memoryBlock.remove(i)
if priority == Task.Priority.HIGH:
is_locked_for_super_user = False
### Extrait toutes les lignes à partir d'un fichier ###
# filename : chemin vers le fichier à lire
# Retourne une liste des lignes lues
def read_stories(filename : str):
story = open(filename, 'r')
return [line.rstrip("\n") for line in story.readlines()]
### Supervise la mémoire utilisée et de met à jour l'interface ###
# memory_bar : Jauge de mémoire de l'interface
# memory_desc : Champs label de l'interface descrivant la mémoire utilisé
def monitor_interface(memory_bar : ttk.Progressbar, memory_desc : tk.Text):
try:
max_bar = 0
memory_bar["maximum"] = int(get_memory_usage())
while True:
memory_usage = memory_usage = int(get_memory_usage())
memory_bar["value"] = memory_usage
if memory_usage >= max_bar:
max_bar = memory_usage
memory_bar["maximum"] = max_bar
memory_desc["text"] = str(memory_usage) + ' Mo utilisés / ' + str(max_bar) + ' Mo maximum utilisés'
time.sleep(1)
except Exception:
return
def main():
# initialize head list empty
memoryBlock = MemoryBlock()
# Read story file
stories = read_stories(__FILENAME__)
turtle.title("Garbage Collector")
turtle.ht()
window = turtle.getscreen()
window.setup(800, 600)
# Create Super user Tasks field
canvas = window.getcanvas()
super_tasks_field = ttk.Treeview(canvas.master, columns=["Label", "Execution"], show="headings", height=20)
super_tasks_field.heading('Label', text='Label')
super_tasks_field.column("Label",minwidth=50,width=75)
super_tasks_field.heading('Execution', text='Execution')
super_tasks_field.column("Execution",minwidth=100,width=250)
canvas.create_window(-200, 0, window=super_tasks_field)
# Create super user button
canvas = window.getcanvas()
button = tk.Button(canvas.master, text="Super utilisateur", command=lambda: threading.Thread(target=launch_task_manager, args= (memoryBlock, stories, Task.Priority.HIGH, super_tasks_field)).start(), height=2, width=30)
canvas.create_window(-200, -250, window=button)
# Create user Tasks field
canvas = window.getcanvas()
tasks_field = ttk.Treeview(canvas.master, columns=["Label", "Execution"], show="headings", height=20)
tasks_field.heading('Label', text='Label')
tasks_field.column("Label",minwidth=50,width=75)
tasks_field.heading('Execution', text='Execution')
tasks_field.column("Execution",minwidth=100,width=250)
canvas.create_window(200, 0, window=tasks_field)
# Create user button
canvas = window.getcanvas()
button = tk.Button(canvas.master, text="Utilisateur ordinaire", command=lambda: threading.Thread(target=launch_task_manager, args= (memoryBlock, stories, Task.Priority.LOW, tasks_field)).start(), height=2, width=30)
canvas.create_window(200, -250, window=button)
# Create progress bar for memory usage
canvas = window.getcanvas()
memory_usage = ttk.Progressbar(canvas.master, orient='horizontal',mode='determinate', length=750, value=get_memory_usage(), maximum=100)
canvas.create_window(0,250, window=memory_usage)
# Create text description for memory usage
canvas = window.getcanvas()
memory_usage_description = tk.Label(canvas.master, text="", background="white")
canvas.create_window(0,275, window=memory_usage_description)
# Lancement d'un thread permettant de supervisier la mémoire utilisée
interface_monitoring_th = threading.Thread(target=monitor_interface, args=(memory_usage, memory_usage_description), daemon= False)
interface_monitoring_th.start()
window.mainloop()
if __name__ == '__main__':
main()
I've made a bot that can play audio through discord but what i want to do now is to make him to say the url in the chat.
#bot.command(pass_context = True)
async def play(ctx,*,query : str):
opts = {'default_search': 'auto','quiet': True,} #options pour youtube-dl que je comprends pas
if voice == None: #si le bot n'a pas encore été connecté à un channel
await bot.say('Summon me in your channel first (!summon)')
elif query[:3] == 'url':
try:
n = int(query[4])
await bot.say(videos[n][0])
except Exception as e:
await bot.say (e)
elif len(query) != 1: #si le joueur essaie de taper !play recherche et non !play 1/2/3/4
videos = yt.recherche(query,4) #on charge les informations des vidéos avec le module yt
for i in range(4): #on affiche les 4 résultas avec un emebed contenant un apercu de chaque vidéo
em = discord.Embed(title=videos[i][1], colour=0xff0000, type = 'rich')
em.set_thumbnail(url='https://i.ytimg.com/vi/'+videos[i][0][32:]+'/hqdefault.jpg?sqp=-oaymwEXCNACELwBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLDBtpHoodvOvDCPjzg9t7PzSljI3A')
await bot.send_message(ctx.message.channel,None,embed=em)
await bot.say('Make your choice! (!play 1/2/3/4)')
else: #si le joueur essaie de choisir une video avec !play 1/2/3/4
try:
if player != None: #si le bot joue déjà une chanson, on stoppe la précédente avant de commencer la suivante (sinon ca plante)
player.stop()
query = int(query) #on convertit en entier : str -> int
player = await voice.create_ytdl_player(videos[query-1][0],ytdl_options=opts) #on initialise le player audio dans la varialble globale
player.volume = 0.2 #on fixe le volume
player.start() #on démarre la lecture
except Exception as e: #exception atteinte en général si on a pas réussi à faire query = int(query), c'est à dire que le joueur à fait une faute de frappe
await bot.say(e)
my problem is when i want to change the elif query:3 to something else to shorter the "url" i wanted to put like .play -u .... but i can't make it work
import requests #librairie de base permettant d'ouvrir une page web dans la console en gros
def recherche(query,nb):
query = query.replace(' ','+')
url = 'https://www.youtube.com/results?search_query='+query
r = requests.get(url).text
balise = 'data-context-item-id="' #balise signalant l'élément manquant dans le code source
liste_videos = []
for e in range(nb): #on ajoute les url de chaque video
liste_videos.append([])
i = r.index(balise) #renvoie la position de la balise dans le code
liste_videos[-1].append('https://www.youtube.com/watch?v='+r[i+22:i+22+11])
r = r[i+100:] #on coupe le début du code pour aller chercher dans la suite plus facilement
for vid in range(nb): #puis leurs titre
url = liste_videos[vid][0] #on prend l'url d'une video
r = requests.get(url).text #on ouvre la page correspondante
title = r[r.index('<title>')+7:r.index('</title>')] #et on cherche le titre dedans
liste_videos[vid].append(title) #puis on met le titre dans le tableau video
u = liste_videos[vid][0]
return liste_videos #on finit par renvoyer ce tableau
hacky: suppose you call the bot with "play u1"
elif query[0] == 'u':
try:
n = int(query[1])
await bot.say(videos[n][0])
essentially query is string which can be accesd like a list. Have a look here:
How to get char from string by index?
Hi people from the forum,
I'm currently a beginner in python and programming in general so please don't shout on me :) I know I have to much global variable and made a lot of mistake.
I am facing a terrible non ending loop problem that doesn't really affect my tkinter window itself, but when closing it is a shame to see this Exception in tkinter callback problem.
Actually I don't know why my batman variable in Valider() function doesn't end all these loops
Can someone help me with this one ?
Ps: sorry for French language in the code
Thanks
Here is the source code:
from tkinter import*
from random import*
import time
from tkinter import messagebox
from tkinter import ttk
#Initialisation des variables
bonne_reponse=0
mauvaise_reponse=0
nbr_total=0
batman=False
nbr_q=10 # 10 question
t=10 # t est definit le temps que l'utilisateur a pour repondre a la question
#_______________Fonction qui genere 2 nombres au hasard dans des intervalles differents selon la difficultee choisie__________________________#
def Division ():
nbr1 = randint (1,9)
nbr2 = randint (1,9)
div=nbr1*nbr2
calcul_affiche = ("CALCUL : " + str(div) + "/" + str(nbr2) + " =")
label1.configure(text=calcul_affiche)
calcul=nbr1
return calcul
##### Fonction qui demarre le programme et donc qui lance la barre de progression lors du clic sur "Demarrer".
def Démarrer():
global reponse_final
global batman
batman=False
reponse_final=Division()
start_time=time.time()
# defini un temps de demarrage car le module time compte le temps depuis 1974
while batman==False:
now =t-((time.time())-(start_time))
root.update()
#Redefini la valeur de la barre de progression
wq=(now/t)*100
progress["value"] = wq
# Fausse le resultat apres le temps ecoule (avec un calcul improbable)
if wq<=0:
batman=True
if batman==True:
Valider()
##### Fonction de validation
def Valider():
global bonne_reponse
global mauvaise_reponse
global nbr_total
global batman
utilisateur_reponse=entryWidget.get() #recupere la valeur de la boite d'entree
entryWidget.delete(0, END) #supprime ce qu'il y a dans la barre d'entree
# empeche l'utlisateur d'entrer des lettres dans la boite d'entrée
batman=True
try:
if reponse_final != int(utilisateur_reponse):
titre="Réponse"
bon_rep=str("Mauvaise réponse ! La bonne réponse était: "+str(reponse_final))
messagebox.showinfo(titre, bon_rep)
mauvaise_reponse+=1
nbr_total+=1
elif reponse_final== int(utilisateur_reponse):
#messagebox.showinfo("Réponse", "Bonne réponse!")
bonne_reponse+=1
nbr_total+=1
except:
messagebox.showerror("Boite d'entrée", "Temps ecoulé ou Entrez uniquement des nombres")
mauvaise_reponse+=1
nbr_total+=1
#on arrete le jeux lorsque le nombre de question souhaité est atteint
if nbr_total==nbr_q:
exitnote()
Démarrer()
######################Création fenetre principale Tkinter "root" ###################
root = Tk()
root.title("Calcul Mental")
root.configure(bg="gainsboro")
root["padx"] = 60
root["pady"] = 40
# On definit un style et un theme pour les widgets
s = ttk.Style()
s.theme_use('clam')
# Creation du label correspondant a la consigne en debut de page
consigne= ("Cliquez sur démarrer pour commencer. Un nombre illimité de calculs va vous être proposé.")
instructions = ttk.Label(root, text=consigne)
instructions.pack()
label_trait4= ttk.Label(root, text="--------------------------------------------------------------------------------------------------")
label_trait4.pack()
# Création de la barre de progression
s.configure("blue.Horizontal.TProgressbar", foreground='aquamarine3', background='aquamarine3')
progress = ttk.Progressbar(root, style="blue.Horizontal.TProgressbar", orient="horizontal", length=500, mode="determinate")
progress["maximum"] = 100
progress.pack()
### Création d'une boite de texte pour un label texte et la boite d'entree
text_boite= Frame(root)
# Création du label de calcul
label1 = ttk.Label(text_boite, background="white", width=15)
label1["text"] = ""
label1.pack(side=LEFT)
# Création d'un Entry Widget dans text_boite
entryWidget = ttk.Entry(text_boite)
entryWidget['width'] = 50
entryWidget.pack(side=RIGHT)
text_boite.pack()
# Bouton valider
root.bind("<Return>", lambda event: Valider())
btn_valider = ttk.Button(root, text="Valider", command=Valider)
# fait en sorte que quand l'utilisateur appui sur la touche entrer ca lance la fonction valider.
# On rend inutilisable le bouton demarrer apres le 1er clic
def btndemarrer():
btn_démarrer.config(state=DISABLED)
instructions.destroy()
Démarrer()
btn_démarrer = ttk.Button(root, text="Démarrer", command = btndemarrer)
btn_démarrer.pack()
# Affiche la note dans une boite et detruit la fenetre
def exitnote():
global batman
batman=True
try:
note=(bonne_reponse*20/nbr_total)
w=("Votre note est de "+str(note)+"/20.0 ")
messagebox.showinfo("Voici votre note",str(w))
root.destroy()
# Si note n'est pas definit car l'utilisateur n'a pas encore appuye sur Entrer, on affiche le message suivant:
except:
messagebox.showinfo("DEVNOTE","Je respecte votre choix mais vous n'avez meme pas essayé.")
root.destroy()
btn_valider.pack()
btn_arret = ttk.Button(root, text="Arrêt", command=exitnote)
btn_arret.pack()
# On lance la boucle Tkinter qui s'interompt lors de la fermeture de la fenetre
root.mainloop()
Here is the exception :
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python34\lib\tkinter\__init__.py", line 1487, in __call__
return self.func(*args)
File "C:\Users\Thierry\Google Drive\Calcul_Mentalsimple.py", line 145, in <lambda>
root.bind("<Return>", lambda event: Valider())
File "C:\Users\Thierry\Google Drive\Calcul_Mentalsimple.py", line 94, in Valider
Démarrer()
File "C:\Users\Thierry\Google Drive\Calcul_Mentalsimple.py", line 55, in Démarrer
progress["value"] = wq
File "C:\Python34\lib\tkinter\__init__.py", line 1275, in __setitem__
self.configure({key: value})
File "C:\Python34\lib\tkinter\__init__.py", line 1268, in configure
return self._configure('configure', cnf, kw)
File "C:\Python34\lib\tkinter\__init__.py", line 1259, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: invalid command name ".59022192"
OK, two things here:
1) Your Valider() function needs no arguments according to your code above so you could just simply bind without using lambda
root.bind('<Return>', Valider)
2) When the button/return is triggered and your Valider() is called a reference to the triggering event is passed as far as I know (at least in wxPython it's done this way and short googling gave me the same for tkinter).
That means your triggered function, in this case Valider(), has to take care of that reference as well. According to this your Valider() definition should look like this:
def Valider(event=None):
Defining your Valider() this way handles an incoming reference to an event that triggered the function but gives you the possibility to call the function directly using
Valider()
as the event parameter has a default value set as None
Hope that helps.
Greetz :-)
I'm making a RPG with Python and pygame for a school project. In order to create the few maps, I have chosen the Tile Mapping techniques I have seen in some tutorials, using a *.txt file.
However, I have to cut some sprites (trees, houses, ...) into several pieces. The problem is that I'm running out of characters to represent them all!
I also remember that it's possible to take several characters as one (ex : take "100" as one an not as one "1" and two "0"s) and/or to put spaces between characters in the file (e.g. "170 0 2 5 12 48" which is read as six sprites).
But I really don't know how to adapt my program to do this way. I'm pretty sure that I need to modify the way the file is read, but how?
Here's the reading function :
class Niveau:
def __init__(self, fichier):
self.fichier = fichier
self.structure = 0
def generer(self):
"""Méthode permettant de générer le niveau en fonction du fichier.
On crée une liste générale, contenant une liste par ligne à afficher"""
#On ouvre le fichier
with open(self.fichier, "r") as fichier:
structure_niveau = []
#On parcourt les lignes du fichier
for ligne in fichier:
ligne_niveau = []
#On parcourt les sprites (lettres) contenus dans le fichier
for sprite in ligne:
#On ignore les "\n" de fin de ligne
if sprite != '\n':
#On ajoute le sprite à la liste de la ligne
ligne_niveau.append(sprite)
#On ajoute la ligne à la liste du niveau
structure_niveau.append(ligne_niveau)
#On sauvegarde cette structure
self.structure = structure_niveau
def afficher(self, fenetre):
"""Méthode permettant d'afficher le niveau en fonction
de la liste de structure renvoyée par generer()"""
#Chargement des images (seule celle d'arrivée contient de la transparence)
Rocher = pygame.image.load(image_Rocher).convert()
Buisson = pygame.image.load(image_Buisson).convert()
#On parcourt la liste du niveau
num_ligne = 0
for ligne in self.structure:
#On parcourt les listes de lignes
num_case = 0
for sprite in ligne:
#On calcule la position réelle en pixels
x = (num_case+0.5) * taille_sprite
y = (num_ligne+1) * taille_sprite
if sprite == 'R': #R = Rocher
fenetre.blit(Rocher, (x,y))
if sprite == 'B':
fenetre.blit(Buisson,(x,y))
num_case += 1
num_ligne += 1
I think what you want is str.split():
for ligne in fichier:
ligne_niveau = []
#On parcourt les sprites (lettres) contenus dans le fichier
for sprite in ligne.split(): # note split here
ligne_niveau.append(sprite) # no need to check for line end
#On ajoute la ligne à la liste du niveau
structure_niveau.append(ligne_niveau)
split without any arguments will join all consecutive whitespace (including tabs '\t' and newlines '\n') into a single split. For example:
"\ta 13 b \t22 6e\n".split() == ['a', '13', 'b', '22', '6e']
Note that the "sprites" don't have to be the same length, so there's no need for fill characters like extra 0s or *s. You can also simplify using a list comprehension:
def generer(self):
with open(self.fichier) as fichier:
self.structure = [ligne.split() for ligne in fichier]
Alternatively, consider using a comma-separated value format - Python has a whole module (csv) for that:
a,13,b,22,6e