IndexError: list index out of range sur tkinter
BienLeBonjour
-
yg_be Messages postés 23541 Date d'inscription Statut Contributeur Dernière intervention -
yg_be Messages postés 23541 Date d'inscription Statut Contributeur Dernière intervention -
Bonjour,
Dans le cadre d'une activité, je suis actuellement en train de faire un jeu sur tkinter dans lequel un joueur évite des balles qui ont un déplacement aléatoire.
Pour gérer les collisions j'utilise find.overlapping (ligne 162).
Mon programme fonctionne plutôt bien et a un fond d'écran mais malheureusement je n'arrive pas à remplacer la balle(du joueur) par une image, en effet la fonction qui fait déplacer les balles ne démarre pas et la console affiche l'erreur suivante :
if len(can.find_overlapping(can.coords(player)[0],can.coords(player)[1],can.coords(player)[2],can.coords(player)[2]))>2:
IndexError: list index out of range
Voici mon code
Merci à ceux qui voudront bien prendre le temps de m'aider.
Dans le cadre d'une activité, je suis actuellement en train de faire un jeu sur tkinter dans lequel un joueur évite des balles qui ont un déplacement aléatoire.
Pour gérer les collisions j'utilise find.overlapping (ligne 162).
Mon programme fonctionne plutôt bien et a un fond d'écran mais malheureusement je n'arrive pas à remplacer la balle(du joueur) par une image, en effet la fonction qui fait déplacer les balles ne démarre pas et la console affiche l'erreur suivante :
if len(can.find_overlapping(can.coords(player)[0],can.coords(player)[1],can.coords(player)[2],can.coords(player)[2]))>2:
IndexError: list index out of range
Voici mon code
from tkinter import *
from random import randint
from tkinter.messagebox import *
from time import *
time()
x,y=700,400
x1,y1=10,10
x2,y2=10,10
x3,y3=10,10
x4,y4=10,10
x5,y5=10,10
x6,y6=10,10
x7,y7=10,10
x8,y8=10,10
x9,y9=10,10
x10,y10=10,10
dx1,dy1=10,10
dx2,dy2=10,10
dx3,dy3=10,10
dx4,dy4=10,10
dx5,dy5=10,10
dx6,dy6=10,10
dx7,dy7=10,10
dx8,dy8=10,10
dx9,dy9=10,10
dx10,d10=10,10
flag=0
def start(event):#fonction qui déclenche le déplacement et le timer
global debut,flag,dx1,dy1,dx2,dy2,dx3,dy3,dx4,dy4,dx5,dy5,dx6,dy6,dx7,dy7,dx8,dy8,dx9,dy9,dx10,dy10
dx1,dy1,dx2,dy2,dx3,dy3,dx4,dy4,dx5,dy5,dx6,dy6,dx7,dy7,dx8,dy8,dx9,dy9,dx10,dy10,flag=randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),randint(-11,11),1
move()
debut=time()
def stop():#fonction qui permet au joueur d'arrêter le déplacement des balles
global dx,dy,flag
dx1,dy1,dx2,dy2,dx3,dy3,dx4,dy4,dx5,dy5,dx6,dy6,dx7,dy7,dx8,dy8,dx9,dy9,dx10,dy10,flag=0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
def move():#déplacement aléatoire des balles puis arrêt en cas de collisions
global debut,x1,y1,dx1,dy1,x2,y2,dx2,dy2,x3,y3,dx3,dy3,x4,y4,dx4,dy4,x5,y5,dx5,dy5,x6,y6,dx6,dy6,x7,y7,dx7,dy7,x8,y8,dx8,dy8,x9,y9,dx9,dy9,x10,y10,dx10,dy10
x1,y1=x1+dx1,y1+dy1
if x1>1580:
dx1=-dx1
if x1<-10:
dx1=-dx1
if y1<-10:
dy1=-dy1
if y1>970:
dy1=-dy1
x1=x1+dx1
y1=y1+dy1
x2,y2=x2+dx2,y2+dy2
if x2>1580:
dx2=-dx2
if x2<-10:
dx2=-dx2
if y2<-10:
dy2=-dy2
if y2>970:
dy2=-dy2
x2=x2+dx2
y2=y2+dy2
x3,y3=x3+dx3,y3+dy3
if x3>1580:
dx3=-dx3
if x3<-10:
dx3=-dx3
if y3<-10:
dy3=-dy3
if y3>970:
dy3=-dy3
x3=x3+dx3
y3=y3+dy3
x4,y4=x4+dx4,y4+dy4
if x4>1580:
dx4=-dx4
if x4<-10:
dx4=-dx4
if y4<-10:
dy4=-dy4
if y4>970:
dy4=-dy4
x4=x4+dx4
y4=y4+dy4
x5,y5=x5+dx5,y5+dy5
if x5>1580:
dx5=-dx5
if x5<-10:
dx5=-dx5
if y5<-10:
dy5=-dy5
if y5>970:
dy5=-dy5
x5=x5+dx5
y5=y5+dy5
x6,y6=x6+dx6,y6+dy6
if x6>1580:
dx6=-dx6
if x6<-10:
dx6=-dx6
if y6<-10:
dy6=-dy6
if y6>970:
dy6=-dy6
x6=x6+dx6
y6=y6+dy6
x7,y7=x7+dx7,y7+dy7
if x7>1580:
dx7=-dx7
if x7<-10:
dx7=-dx7
if y7<-10:
dy7=-dy7
if y7>970:
dy7=-dy7
x7=x7+dx7
y7=y7+dy7
x8,y8=x8+dx8,y8+dy8
if x8>1580:
dx8=-dx8
if x8<-10:
dx8=-dx8
if y8<-10:
dy8=-dy8
if y8>970:
dy8=-dy8
x8=x8+dx8
y8=y8+dy8
x9,y9=x9+dx9,y9+dy9
if x9>1580:
dx9=-dx9
if x9<-10:
dx9=-dx9
if y9<-10:
dy9=-dy9
if y9>970:
dy9=-dy9
x9=x9+dx9
y9=y9+dy9
x10,y10=x10+dx10,y10+dy10
if x10>1580:
dx10=-dx10
if x10<-10:
dx10=-dx10
if y10<-10:
dy10=-dy10
if y10>970:
dy10=-dy10
x10=x10+dx10
y10=y10+dy10
if len(can.find_overlapping(can.coords(player)[0],can.coords(player)[1],can.coords(player)[2],can.coords(player)[3]))>2:
dy1=-dy1
dy2=-dy2
dy3=-dy3
dy4=-dy4
dy5=-dy5
dy6=-dy6
dy7=-dy7
dy8=-dy8
dy9=-dy9
dy10=-dy10
fin=time()
msg=askquestion('','GAME OVER ! Vous avez tenu '+str(round(fin-debut))+' secondes.'+' Voulez vous recommencer ?')
if msg=='yes':
stop()
showinfo('','Déplacez vous vers un endroit safe puis appuyez sur la touche entrée')
else:
stop()
showinfo('','Appuyez sur quitter')
can.move(balle1,dx1,dy1)
can.move(balle2,dx2,dy2)
can.move(balle3,dx3,dy3)
can.move(balle4,dx4,dy4)
can.move(balle5,dx5,dy5)
can.move(balle6,dx6,dy6)
can.move(balle7,dx7,dy7)
can.move(balle8,dx8,dy8)
can.move(balle9,dx9,dy9)
can.move(balle10,dx10,dy10)
if flag==1:
fenetre.after(40,move)
#fonctions déplacement joueur
def gauche(event):
global x,y
if x>=20:
can.move(player,-20,0)
x=x-20
return
def droite(event):
global x,y
if x<=760:
can.move(player,20,0)
x=x+20
return
def bas(event):
global x,y
if y<=470:
can.move(player,0,20)
y=y+20
return
def haut(event):
global x,y
if y>=20:
can.move(player,0,-20)
y+=-20
return
fenetre = Tk()
fenetre.configure(bg="black")
fenetre.geometry("600x500")
photo=PhotoImage(master=fenetre,file="C:/Users/./Documents/Lycée/1G1/NSI/espace2.gif")
can = Canvas(fenetre,bg="black",highlightbackground="black",height=500, width=800)
can.create_image(250,250,image=photo)
can.pack(side=LEFT,padx=50,pady=5)
image = PhotoImage(master=fenetre,file = 'C:/Users/./Documents/Lycée/1G1/NSI/vaisseau.gif')
player=can.create_image(700,400,anchor=NW,image=image)
can.focus_set()
balle1=can.create_oval(x1,y1,x1+10,y1+10,width=3,fill="orange",outline="red")
balle2=can.create_oval(x2,y2,x2+10,y2+10,width=3,fill="orange",outline="red")
balle3=can.create_oval(x3,y3,x3+10,y3+10,width=3,fill="orange",outline="red")
balle4=can.create_oval(x4,y4,x4+10,y4+10,width=3,fill="orange",outline="red")
balle5=can.create_oval(x5,y5,x5+10,y5+10,width=3,fill="orange",outline="red")
balle6=can.create_oval(x6,y6,x6+10,y6+10,width=3,fill="orange",outline="red")
balle7=can.create_oval(x7,y7,x7+10,y7+10,width=3,fill="orange",outline="red")
balle8=can.create_oval(x8,y8,x8+10,y8+10,width=3,fill="orange",outline="red")
balle9=can.create_oval(x9,y9,x9+10,y9+10,width=3,fill="orange",outline="red")
balle10=can.create_oval(x10,y10,x10+10,y10+10,width=3,fill="orange",outline="red")
fenetre.bind("<Up>", haut)
fenetre.bind("<Down>",bas)
fenetre.bind("<Left>", gauche)
fenetre.bind("<Right>", droite)
fenetre.bind("<Return>",start)
bouton_Pause = Button(fenetre, text='PAUSE', width =9, command=stop,bg="red")
bouton_Pause.pack(side=BOTTOM)
Bouton_Quitter=Button(fenetre, text ='Quitter',width =9,command=fenetre.destroy,bg="red")
Bouton_Quitter.pack(side=BOTTOM)
fenetre.mainloop()
Merci à ceux qui voudront bien prendre le temps de m'aider.
Configuration: Windows / Chrome 89.0.4389.82
A voir également:
- Indexerror: image index out of range
- Input signal out of range - Forum Matériel & Système
- Intitle index of ✓ - Forum Téléchargement
- Problème signal out of range - Forum Windows
- Supprimez les composantes rouge et verte de cette image. quel mot apparaît ? - Forum Word
- Hdmi out - Forum Format et connectique vidéo
3 réponses
yg_be
Messages postés
23541
Date d'inscription
Statut
Contributeur
Dernière intervention
Ambassadeur
1 584
bonjour,
si tu ne comprends pas d'où vient l'erreur, décompose l'instruction qui provoque l'erreur, afin de déterminer quel index cause l'erreur.
si tu ne comprends pas d'où vient l'erreur, décompose l'instruction qui provoque l'erreur, afin de déterminer quel index cause l'erreur.
Salut,
Je suis à distance ce fil. Je vais essayer de faire ton jeu. Mais, tu étais obligé d'utiliser tkinter ? Je trouve que pygame est davantage adapté.
J'utilise tkinter pour des applis fenêtrées, et pygame pour des petits jeux 2D.
Bon, mon défi, c'est de faire le jeu avec tkinter. Ne connaissant pas bien la classe Canvas, c'est vraiment galère. Tu auras, je l'espère, fait mieux et fini avant moi.
Je suis à distance ce fil. Je vais essayer de faire ton jeu. Mais, tu étais obligé d'utiliser tkinter ? Je trouve que pygame est davantage adapté.
J'utilise tkinter pour des applis fenêtrées, et pygame pour des petits jeux 2D.
Bon, mon défi, c'est de faire le jeu avec tkinter. Ne connaissant pas bien la classe Canvas, c'est vraiment galère. Tu auras, je l'espère, fait mieux et fini avant moi.
Merci à tous pour les informations que vous m'avez donné !
Je vais devoir rendre ce devoir dans peu de temps cependant mon problème pour insérer une image et la faire bouger sans que mon jeu ne bug reste toujours présent.
Je ne le rajouterai donc pas dans mon travail mais si quelqu'un a la réponse je serais toujours content de la connaître.
Bonne chance à toi Dachiasse pour ce programme sur tkinter et n'hésite pas à l'envoyer pour que je puisse le voir.
PS: c'était un travail sur tkinter alors non je ne pouvais pas utiliser pygame.
Je vais devoir rendre ce devoir dans peu de temps cependant mon problème pour insérer une image et la faire bouger sans que mon jeu ne bug reste toujours présent.
Je ne le rajouterai donc pas dans mon travail mais si quelqu'un a la réponse je serais toujours content de la connaître.
Bonne chance à toi Dachiasse pour ce programme sur tkinter et n'hésite pas à l'envoyer pour que je puisse le voir.
PS: c'était un travail sur tkinter alors non je ne pouvais pas utiliser pygame.
Salut,
Pour qu'on soit bien d'accord sur les règles.
Le joueur est une boule qu'on déplace avec les touches fléchées du clavier. Il y a des balles qui se déplacent. Le chrono se lance, on se déplace en évitant les balles et dès qu'il y a contact on arrête le chrono et on l'affiche.
C'est bien ça ? Ou j'ai raté quelque chose.
Pour ton bug de l'image, bien que tu n'utilises pas pygame, tu pourrais t'en inspirer, au moins, au niveau de la méthode. Dans Pygame, il y a une classe Surface où l'on insère un objet (rectangle, image, autre) et avec la classe Rect on peut conserver les coordonnées pour "figer" l'image à la surface. Ainsi, à chaque déplacement, l'image est figée.
Car on dirait que ton problème, c'est que l'image sort de son cadre ou qu'elle ne bouge pas du tout.
Pour qu'on soit bien d'accord sur les règles.
Le joueur est une boule qu'on déplace avec les touches fléchées du clavier. Il y a des balles qui se déplacent. Le chrono se lance, on se déplace en évitant les balles et dès qu'il y a contact on arrête le chrono et on l'affiche.
C'est bien ça ? Ou j'ai raté quelque chose.
Pour ton bug de l'image, bien que tu n'utilises pas pygame, tu pourrais t'en inspirer, au moins, au niveau de la méthode. Dans Pygame, il y a une classe Surface où l'on insère un objet (rectangle, image, autre) et avec la classe Rect on peut conserver les coordonnées pour "figer" l'image à la surface. Ainsi, à chaque déplacement, l'image est figée.
Car on dirait que ton problème, c'est que l'image sort de son cadre ou qu'elle ne bouge pas du tout.
Salut,
J'ai récupéré ton code. J'ai modifié l'image car je n'y ai pas accès. J'ai mis un rectangle à la place. J'ai dû retirer des configurations de
J'ai testé la méthode find_overlapping de tk.Canvas, je l'ai comprise. Dans ton jeu, on perd si le joueur entre en collision avec au moins 2 balles on dirait.
J'ai récupéré ton code. J'ai modifié l'image car je n'y ai pas accès. J'ai mis un rectangle à la place. J'ai dû retirer des configurations de
fenetrepour accéder aux boutons.
J'ai testé la méthode find_overlapping de tk.Canvas, je l'ai comprise. Dans ton jeu, on perd si le joueur entre en collision avec au moins 2 balles on dirait.
Bonjour,
Le problème est que si je change le joueur en image les balles qui ont un déplacement aléatoire ne se lancent pas. Alors que si le joueur est une balle le programme se lance et fonctionne correctement même si c'est un rectangle.
PS: je pense qu' il y a une erreur car sur le mien le programme s'arrête dès qu'une balle touche le joueur.
Le problème est que si je change le joueur en image les balles qui ont un déplacement aléatoire ne se lancent pas. Alors que si le joueur est une balle le programme se lance et fonctionne correctement même si c'est un rectangle.
PS: je pense qu' il y a une erreur car sur le mien le programme s'arrête dès qu'une balle touche le joueur.
En fait, comme j'ai dit, je n'ai pas ton image, donc j'ai réadapté en mettant un rectangle à la place. Et j'ai remarqué que la collision ne se traite que dans le canvas. Ce qui est logique.
Je ne peux pas te faire de dessin, mais imagine le canvas en haut à gauche de la fenêtre Tk, en agrandissant la fenêtre, je peux déplacer la boule hors du canvas, les balles en sortent également, et il n'y a jamais collision même si visuellement oui. Par contre, dans le canvas, s'il y a collision c'est game over.
Même s'il y a le très dégueulasse mot clé global, tu peux t'inspirer de : https://tarball69.developpez.com/tutoriels/python/isn-passe-ton-faq/#LIII-C-7
Il y a plein de fonctions. Logiquement, il faut éviter les boucles for ou while mais, dans son jeu, ce n'est absolument pas bloquant. En tout cas, au niveau de l'utilisateur ça ne l'est pas.
Dans ton code, tu devrais faire une liste de X et de Y, pareil pour les Dx et Dy. Et tu as des répétitions de code pour le déplacement des balles. Fais plutôt une fonction.
Tu remplaces :
par :
Comme ça, le jour où tu veux mettre 1000 balles, ça te fera 990 lignes en plus et non 990 x 10 lignes. D'ailleurs, une liste serait un meilleur choix.
Je ne peux pas te faire de dessin, mais imagine le canvas en haut à gauche de la fenêtre Tk, en agrandissant la fenêtre, je peux déplacer la boule hors du canvas, les balles en sortent également, et il n'y a jamais collision même si visuellement oui. Par contre, dans le canvas, s'il y a collision c'est game over.
Même s'il y a le très dégueulasse mot clé global, tu peux t'inspirer de : https://tarball69.developpez.com/tutoriels/python/isn-passe-ton-faq/#LIII-C-7
Il y a plein de fonctions. Logiquement, il faut éviter les boucles for ou while mais, dans son jeu, ce n'est absolument pas bloquant. En tout cas, au niveau de l'utilisateur ça ne l'est pas.
Dans ton code, tu devrais faire une liste de X et de Y, pareil pour les Dx et Dy. Et tu as des répétitions de code pour le déplacement des balles. Fais plutôt une fonction.
Tu remplaces :
if x10>1580: dx10=-dx10 if x10<-10: dx10=-dx10 if y10<-10: dy10=-dy10 if y10>970: dy10=-dy10 x10=x10+dx10 y10=y10+dy10
par :
def deplacerBalle(x,y,dx,dy): if x<-10 or x>1580: dx = -dx if y<-10 or y>970: dy = -dy x = x+dx y = y+dy # puis deplacerBalle(x10,y10,dx10,dy10)
Comme ça, le jour où tu veux mettre 1000 balles, ça te fera 990 lignes en plus et non 990 x 10 lignes. D'ailleurs, une liste serait un meilleur choix.
Pourriez vous m'expliquer qu'est-ce qui doit changer dans le programme après avoir remplacé la balle par une image ?
tu écris "quand j'enlève un des can.coords je me retrouve avec une autre erreur": montre-nous les deux versions du programme.
comme j'ai compris que tu avais écrit avoir des erreurs avec cette ligne de code
j'ai simplement suggéré de décomposer cette instruction, de façon à déterminer quelle partie provoque le problème?
as-tu essayé de décomposer?
si tu ne comprends pas , n'hésite pas à poser des questions.
Ducoup je joins l'ancien programme (quand le joueur est une balle et que le programme tourne)
je précise que juste 2 lignes sont changées pour le nouveau programme.
De plus je ne vois pas trop ce que vous voulez dire par décomposer l'instruction.
Et pour la méthode avec can.coords je l'ai trouvé sur internet et c'est la seule que j'ai essayé.
(Au fait cette année est ma première en programmation alors mes connaissances sont un peu limités.)
si je ne me suis pas trompé, ce groupe d'instructions devrait faire la même chose que ton instruction, et il te sera plus simple de déterminer où précisément l'erreur se produit.