Probleme allongement du snake (Tkinter)

Oyanel -  
 Oyanel -
Bonjour,
je suis élève de terminale S en spé ISN et nous avons comme projet de fin d'année faire un Snake like en Tkinter. Nous avons cependant des contraintes comme ne pas utiliser les class, self, .. juste avec des bases en somme.
Le gros problème c'est que je n'arrive pas à faire le corps du serpent je ne peux faire qu'un seul carré comme corps.
je voudrais avoir votre avis en général sur le programme et si possible une solution pour ce problème d'allongement du serpent. (j'ai signalé les lignes qui poses problème par des ###)
Soyez indulgent je débute dans la programmation.
Merci d'avance
# -*- coding: utf-8 -*-
"""
Created on Thu Feb 20 07:18:31 2014

@author: Oyanel
"""

from tkinter import *
from random import *
from PIL import Image, ImageTk

#            ******************
#            *                                *
#            *   Fonctions              *
#            *                                *
#            ******************
# on creer une partie:
    
def newGame(): 
    global flag, pX, pY, p, flag2, flag4, score,carre1
    flag2=1
    flag4=1
    score=0
    carre1=0
    can1.delete(text1)
    pX = randrange(5, fen1.winfo_screenwidth()-150)
    pY = randrange(5, fen1.winfo_screenheight()-150)
    p=can1.create_oval(pX, pY, pX+10, pY+10,fill="green")#création d'une pomme à un endroit aléatoire
    if flag == 0:   #Si jeu n'est pas activé
        flag = 1      #Alors activation du programme
        bou2.config(state= DISABLED) #Désactiver (griser) le bouton démarrer
        Serpent_avance() #Activation de la fonction "serpent avance"
    
def Serpent_avance(): 
    "déplacement du snake" #Fonction qui permet le deplacement du snake
    global x, y, dx, dy, flag, flag2, p, pX, pY,score,var, var2, carre1 #Global: repertorie les variables utilisées dans la fonction du dessus
    if abs(x-pX) < 17 and abs(y-pY) < 17 : #Quand serpent passe sur la pomme,
        can1.delete(p)# disparition
        pX = randrange(5, fen1.winfo_screenwidth()-150) #réapparition de la pomme
        pY = randrange(5, fen1.winfo_screenheight()-150)
        p=can1.create_oval(pX, pY, pX+10, pY+10,fill="green")
        score=score+10
        if carre1==0:#crétation du corps au fur et à mesure
            var=can1.create_rectangle(x, y, x+15, y+15, width=2, fill="yellow")
       # if carre1==1:
       #     var2=can1.create_rectangle(x, y, x+15, y+15, width=2, fill="yellow") ############################ voila les lignes qui poses probleme###################
       # carre1=carre1+1
    if x >fen1.winfo_screenwidth()-100: #Quand serpent arrive sur le mur coté droit,
        x, dx, dy = 5, 15, 0            #Réapparait de l'autre coté
    if y >fen1.winfo_screenheight()-100:#IDEM mur du bas
        y, dx, dy = 5, 0, 15             #Réapparait au mur du haut
    if x <5:                           #Quand serpent arrive sur le mur coté gauche
        x, dx, dy = fen1.winfo_screenwidth()-100, -15, 0 #Réapparait mur coté droit
    if y <5:  #Quand serpent arrive sur le mur haut
        y, dx, dy = fen1.winfo_screenheight()-100, 0, -15 #Réapparait sur le mur bas
    can1.coords(rect1, x, y, x+15, y+15) #Creation du carré du snake
    can1.coords(var, x-dx, y-dy, x+15-dx, y+15-dy)
    #can1.coords(var2, x-2*dx, y-2*dy, x+15-2*dx, y+15-2*dy) #####################################et celle la qui va avec ####################
    x, y = x +dx, y + dy  # faire avancer le serpent
    if flag >0:  #Quand jeu activé
        fen1.after(50,Serpent_avance)#boucler, après 50 millisecondes (vitesse de repetition)

def avance(dx1, dy1): #Definition direction
    global x,y, dx, dy #Variables repertoriées
    dx = dx1           
    dy = dy1
    x,y =x +dx, y +dy  #Coordonnées du déplacement
    can1.coords(rect1,x, y, x+15, y+15) #Coordonnées du rectangle
def depl_gauche(event):
    global flag
    if flag==1:
        avance(-15, 0)
def depl_droite(event):
    global flag
    if flag==1:
        avance(15, 0)
def depl_haut(event):
    global flag
    if flag==1:
        avance(0, -15)
def depl_bas(event):
    global flag
    if flag==1:
        avance(0, 15) 

def pause():  #Pause
    global flag, pause, flag2, flag4, score, score1
    if flag4 ==1:
        if flag == 1 and flag2 == 1:
            pause=can1.create_text(fen1.winfo_screenwidth()/2-100,fen1.winfo_screenheight()/2-5,font=('Fixedsys',18),text="PAUSE")
            score1=can1.create_text(150,150,font=('Fixedsys',18),text="Score : "+str(score))
            can1.create_text(fen1.winfo_screenwidth(),fen1.winfo_screenheight(),font=('Fixedsys',18),text=print(score))
            flag=0
        elif flag==0 and flag2 == 1:
            flag=1
            can1.delete(pause)
            can1.delete(score1)
            Serpent_avance()
            
    

def fullscreen():
    fen1.overrideredirect(1)
    fen1.geometry("%dx%d+0+0" % (w, h)) 
    

#    *********************
#    *      Programme              *
#    *       Principal                  *
#    *********************

#création de la fenêtre
fen1 = Tk()
fen1.title("Snake")

x, y = (fen1.winfo_screenheight()+250)/2, (fen1.winfo_screenwidth()-250)/2
dx, dy = 15, 0
flag =0
flag4=0#pour ne pas appuyer sur pause qi le jeu ne démarre pas

#on la met dans le canvas
can1 = Canvas(fen1,width=fen1.winfo_screenwidth()-100, height=fen1.winfo_screenheight(),background='light grey')
can1.pack()

can1.pack(side=LEFT, padx =5, pady =5)
rect1=can1.create_rectangle(x, y, x+15, y+15, width=2, fill="yellow")
text1=can1.create_text(fen1.winfo_screenwidth()/2,fen1.winfo_screenheight()-400,font=('Fixedsys',18),text="appuyer sur Démarrer")
bou2 = Button(fen1, text='Démarrer', width =8, command = newGame)
bou2.pack()
bou3= Button(fen1, text='Pause',width= 8,command= pause)
bou3.pack()
bou4 = Button(fen1, text='Quitter', width= 8, command=fen1.destroy)
bou4.pack(side=BOTTOM)
bou5 = Button(fen1, text='Plein écran', width= 8, command=fullscreen)
bou5.pack()
# Quelques exemples de touches
fen1.bind("<Up>", depl_haut)#haut
fen1.bind("<Down>", depl_bas)#bas
fen1.bind("<Left>", depl_gauche)#gauche
fen1.bind("<Right>", depl_droite)#Droite
#lancement du gestionnaire d'évènement
fen1.mainloop()

2 réponses

  1. BigBrother_ Messages postés 54 Statut Membre 4
     
    salut,
    tu devrait stocker ton snake dans une liste de liste, chaque élement de la liste représentant un morceau du snake décrit par ses coordonnées : tu aurais un truc du genre :
    snake = [[0,0],[0,1],[0,2]]

    et comme ça tu peut juste faire un snake.insert(0, [nouvelle position de la tete])
    et snake.pop() pour enlever la "queue" ou pas si tu veux qu'il grandisse..
    j'espère que ça t'aide
    0
    1. Oyanel
       
      merci pour la réponse mais ca m'oblige a tout refaire non ?
      0
    2. BigBrother_ Messages postés 54 Statut Membre 4
       
      possible oui
      0
  2. Oyanel
     
    Salut c'est nouveau moi
    j'ai tenté de le refaire du moins le début mais le carré du snake ne veut pas bougé et je ne comprends pas pourquoi. :/
    # -*- coding: utf-8 -*-
    """
    Created on Thu Feb 20 07:18:31 2014
    
    @author: Therence.Brune
    """
    
    from tkinter import *
    from random import *
    from PIL import Image, ImageTk
    
    #            ******************
    #            *                *
    #            *   Fonctions    *
    #            *                *
    #            ******************
    # on creer une partie:
        
    def newGame(): 
        global flag, pX, pY, p, flag2, flag4, score,carre1
        can1.delete(text1)
        can1.delete(img1)
        flag2=1
        flag4=1
        score=0
        pX = randrange(10, fen1.winfo_screenwidth()-150)
        pY = randrange(10, fen1.winfo_screenheight()-150)
        p=can1.create_oval(pX, pY, pX+10, pY+10,fill="green")#création d'une pomme à un endroit aléatoire
        if flag == 0:   #Si jeu n'est pas activé
            flag = 1      #Alors activation du programme
            bou2.config(state= DISABLED) #Désactiver (griser) le bouton démarrer
            Serpent_avance() #Activation de la fonction "serpent avance"
            
    def Serpent_avance(): 
        "déplacement du snake" #Fonction qui permet le deplacement du snake
        global x, y, dx, dy, flag, flag2, p, pX, pY,score,var, pause #Global: repertorie les variables utilisées dans la fonction du dessus
        if abs(snake[0]-pX) < 17 and abs(snake[1]-pY) < 17 : #Quand serpent passe sur la pomme,
            can1.create_oval(x, y, x+20, y+20, fill="black")
            fen1.after(100,trou)        
            can1.delete(p)# disparition
            pX = randrange(10, fen1.winfo_screenwidth()-150) #réapparition de la pomme
            pY = randrange(10, fen1.winfo_screenheight()-150)
            p=can1.create_oval(pX, pY, pX+10, pY+10,fill="green")
            score=score+10
            
        if snake[0] > fen1.winfo_screenwidth()-100: #Quand serpent arrive sur le mur coté droit,
            snake[0]=10
            snake[2]=30                             #Réapparait de l'autre coté        
        if snake[1] > fen1.winfo_screenheight()-5:  #IDEM mur du bas
            snake[1]=10
            snake[3]=30                             #Réapparait au mur du haut
        if snake[0] < 5:                            #Quand serpent arrive sur le mur coté gauche
            snake[0]=fen1.winfo_screenwidth()-100
            snake[2]=fen1.winfo_screenwidth()-120   #Réapparait mur coté droit
        if snake[1] < 5:                            #Quand serpent arrive sur le mur haut
            snake[1]=fen1.winfo_screenheight()-10   #Réapparait sur le mur bas
            snake[3]=fen1.winfo_screenheight()-30
               
        snake[0]=snake[0]+dx                        # faire avancer le serpent automatiquement
        snake[1]=snake[1]+dx
        snake[2]=snake[0]+20
        snake[3]=snake[1]+20  
        
        can1.coords(Serpent, snake[0], snake[1], snake[2], snake[3])    # coordonées du snake
        
        if flag >0:                                                     #Quand jeu activé
            fen1.after(50,Serpent_avance)                               #boucler, après 50 millisecondes (vitesse de repetition)
    
    def depl_gauche(event):
        global flag, dx, dy
        if flag==1:
            dx, dy = -20, 0
            
    def depl_droite(event):
        global flag, dx, dy
        if flag==1:
            dx, dy = 20, 0 
            
    def depl_haut(event):
        global flag, dx, dy
        if flag==1:
            dx, dy = 0, -20
            
    def depl_bas(event):
        global flag, dx, dy
        if flag==1:
            dx, dy = 0, 20
    
    def pause():  #Pause
        global flag, pause, flag2, flag4, score, score1
        if flag4 ==1:
            if flag == 1 and flag2 == 1:
                pause=can1.create_text(fen1.winfo_screenwidth()/2-100,fen1.winfo_screenheight()/2-5,font=('Fixedsys',18),text="PAUSE")
                score1=can1.create_text(150,150,font=('Fixedsys',18),text="Score : "+str(score))
                can1.create_text(fen1.winfo_screenwidth(),fen1.winfo_screenheight(),font=('Fixedsys',18),text=print(score))
                flag=0
            elif flag==0 and flag2 == 1:
                flag=1
                can1.delete(pause)
                can1.delete(score1)
                Serpent_avance()
                
        
    
    def fullscreen():
        fen1.overrideredirect(1)
        fen1.geometry("%dx%d+0+0" % (w, h)) 
        
    
    #    *********************
    #    *      Programme    *
    #    *       Princal     *
    #    *********************
    
    #création de la fenêtre
    fen1 = Tk()
    fen1.title("Snake")
    
    x, y = (fen1.winfo_screenheight()+250)/2, (fen1.winfo_screenwidth()-250)/2
    dx, dy = 20, 0
    flag =0
    flag4=0                                                 #pour ne pas appuyer sur pause qi le jeu ne démarre pas
    
    image_tk2= ImageTk.PhotoImage(Image.open("serpent.jpg"))
    
    image_tk = ImageTk.PhotoImage(Image.open("image.jpg"))  #on la transforme pour tk
    
    #on la met dans le canvas
    can1 = Canvas(fen1,width=fen1.winfo_screenwidth()-100, height=fen1.winfo_screenheight())
    can1.pack()
    img  = can1.create_image(0,0, anchor = NW, image=image_tk)
    
    can1.pack(side=LEFT, padx =10, pady =10)
    snake=[x, y, x+20, y+20]
    Serpent=[can1.create_rectangle(snake[0], snake[1], snake[2], snake[3], fill="yellow")]
    img1  = can1.create_image(0,0, anchor = NW, image=image_tk2)
    text1=can1.create_text(fen1.winfo_screenwidth()/2,fen1.winfo_screenheight()-400,font=('Fixedsys',18),text="appuyer sur Démarrer")
    
    bou2 = Button(fen1, text='Démarrer', width =8, command = newGame)
    bou2.pack()
    bou3= Button(fen1, text='Pause',width= 8,command= pause)
    bou3.pack()
    bou4 = Button(fen1, text='Quitter', width= 8, command=fen1.destroy)
    bou4.pack(side=BOTTOM)
    bou5 = Button(fen1, text='Plein écran', width= 8, command=fullscreen)
    bou5.pack()
    # Quelques exemples de touches
    fen1.bind("<Up>", depl_haut)#haut
    fen1.bind("<Down>", depl_bas)#bas
    fen1.bind("<Left>", depl_gauche)#gauche
    fen1.bind("<Right>", depl_droite)#Droite
    #lancement du gestionnaire d'évènement
    fen1.mainloop()
    

    merci pour votre réponse =)
    0