Below is a Python code for my "Snake Project" (with Turtle and Tkinter).
The purpose of this program is to create a chain of turtles, called followers, that follow each other, with the first turtle in the chain following a special turtle: the leader. The leader itself follows the movement of the mouse.
It removes the last follower from the chain when the "Del" key is pressed.
Since it is not possible to physically delete Followers from memory, when the last Follower in the chain is removed, it is added in the first position of another chain that contains all the "deleted" Followers.
When a new Follower needs to be added to the chain, we first check if there are any in the deleted list and reuse one if available; otherwise, a new one must be created.
However, with my Python code, only the last Turtle is deleted when I click on the "Del" key, even if I press it several times. (Normally, it should delete each time the last follower).
I think the problem has to do with the method:
remove_last_follower(self, event)
of the "Leader" class.
Do you have any idea how to resolve this problem? Thanks a lot for you support.
My Python code:
from turtle import Turtle, Screen, window_width, window_height # Importation du module Turtle
D = 30 # Distance entre les tortues
screen = Screen()
class Follower(Turtle):
def __init__(self, name):
Turtle.__init__(self)
self.shape("circle")
self.color("lightblue")
self.penup()
self.Prev = None
self.Next = None
self.Name = "T" + str(name)
self.coucou = False
def move(self, x, y):
angle = self.towards(x, y)
self.setheading(angle)
self.setposition(x,y)
self.back(20)
if self.Next:
x, y = self.pos()
self.Next.move(x,y)
class Leader(Follower):
def __init__(self):
super().__init__('tkz')
self.shape("turtle")
self.color("lightgreen")
self.Last = None
self.is_moving = False
self.freeze = False
self.deleted_followers = []
def freeeze(self, event):
self.freeze = not self.freeze
def add_follower(self, name):
if self.deleted_followers:
new_follower = self.deleted_followers.pop()
new_follower.showturtle()
new_follower.goto(new_follower.Prev.pos())
new_follower.setheading(new_follower.Prev.heading())
else:
new_follower = Follower(name)
if self.Last == None:
self.Last = new_follower
self.Next = new_follower
new_follower.Prev = self
else:
self.Last.Next = new_follower
self.Last = new_follower
new_follower.Prev = self.Last
new_follower.Next = None
def move(self, event):
if self.freeze == False:
x, y = event.x - window_width()/2, -event.y + window_height()/2
angle = self.towards(x, y)
self.setheading(angle)
self.goto(x, y)
#self.forward(-20)
if self.Next:
self.Next.move(x, y)
def on_move(self, event):
if self.is_moving:
return
self.is_moving = True
self.move(event)
self.is_moving = False
def remove_last_follower(self, event):
if self.Last:
last_follower = self.Last
if last_follower.Prev:
self.Last = last_follower.Prev
self.Last.Next = None
else:
self.Last = None
self.Next = None
last_follower.hideturtle()
self.deleted_followers.append(last_follower)
screen.delay(0)
try:
le = Leader()
except:
le = Leader()
screen.cv.bind("<Button-1>", le.add_follower)
screen.cv.bind("<Button-3>", le.freeeze)
screen.cv.bind("<Delete>", le.remove_last_follower)
screen.cv.bind("<Motion>", le.on_move)
screen.listen()
screen.mainloop()
The linked list in add_follower
isn't updated correctly.
Change:
self.Last.Next = new_follower
self.Last = new_follower # self.Last updated
new_follower.Prev = self.Last # should be the *old* version of self.Last
To:
self.Last.Next = new_follower
temp = self.Last # save previous Last
self.Last = new_follower # assign new Last
new_follower.Prev = temp # assign previous correctly
Or even:
self.Last.Next = new_follower
self.Last, new_follower.Prev = new_follower, self.Last