Reputation: 11
from tkinter import *
import random
GAME_WIDTH = 700
GAME_HEIGHT = 700
SPEED = 75
SPACE_SIZE = 50
BODY_PARTS = 3
SNAKE_COLOR = "lime green"
BACKGROUND_COLOR = "black"
class Snake:
def __init__(self):
self.body_size = BODY_PARTS
self.coordinates = []
self.squares = []
for i in range(0, BODY_PARTS):
self.coordinates.append([0, 0])
for x, y in self.coordinates:
square = canvas.create_rectangle(x, y, x + SPACE_SIZE, y + SPACE_SIZE, fill=SNAKE_COLOR, tag="snake")
self.squares.append(square)
class Food:
def __init__(self):
x = random.randint(0, (GAME_WIDTH/SPACE_SIZE)-1) * SPACE_SIZE
y = random.randint(0, (GAME_HEIGHT/SPACE_SIZE)-1) * SPACE_SIZE
self.coordintes = [x,y]
canvas.create_oval(x, y, x + SPACE_SIZE, y + SPACE_SIZE, fill = "red", tag = "food")
def next_turn(snake, food):
x, y = snake.coordinates[0]
if direction == "up":
y -= SPACE_SIZE
elif direction == "down":
y += SPACE_SIZE
elif direction == "left":
x -= SPACE_SIZE
elif direction == "right":
x += SPACE_SIZE
snake.coordinates.insert(0, (x, y))
square = canvas.create_rectangle(x, y, x + SPACE_SIZE, y + SPACE_SIZE, fill=SNAKE_COLOR)
snake.squares.insert(0, square)
if x == food.coordintes[0] and y == food.coordintes[1]:
global score
score += 1
label.config(text = "score: " + str(score))
canvas.delete("food")
food = Food()
else:
del snake.coordinates[-1]
canvas.delete(snake.squares[-1])
del snake.squares[-1]
if check_collisions(snake):
game_over()
else:
window.after(SPEED, next_turn, snake, food)
def change_direction(new_direction):
global direction
if new_direction == "left":
if direction != "right":
direction = new_direction
elif new_direction == "right":
if direction != "left":
direction = new_direction
elif new_direction == "up":
if direction != "down":
direction = new_direction
elif new_direction == "down":
if direction != "up":
direction = new_direction
def check_collisions(snake):
x, y = snake.coordinates[0]
if x < 0 or x >= GAME_WIDTH:
return True
elif y < 0 or y >= GAME_HEIGHT:
return True
for body_part in snake.coordinates[1:]:
if x == body_part[0] and y == body_part[1]:
return True
return False
def game_over():
global text
canvas.delete(ALL)
text = canvas.create_text(canvas.winfo_width()/2, canvas.winfo_height()/2,
font = "Times 70 bold", text = "Game Over", fill = "red")
def play_again():
global score
score = 0
label.config(text="score: " + str(score))
BODY_PARTS = 3
canvas = Canvas(window, bg=BACKGROUND_COLOR, height=GAME_HEIGHT, width=GAME_WIDTH)
canvas.pack()
snake = Snake()
food = Food()
next_turn(snake, food)
window = Tk()
window.title("snake game")
score = 0
direction = "right"
label = Label(window,
text = "Score: "+ str(score),
font = "Times 40 bold",
)
label.pack()
canvas = Canvas(window, bg = BACKGROUND_COLOR, height = GAME_HEIGHT, width = GAME_WIDTH)
canvas.pack()
window.update()
window_width = window.winfo_width()
window_height = window.winfo_height()
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
x = int((screen_width/2) - (window_width/2))
y = int((screen_height/2) - (window_height/2))
window.geometry(f"{window_width}x{window_height}+{x}+{y}")
window.bind("<Left>", lambda event: change_direction("left"))
window.bind("<Right>", lambda event: change_direction("right"))
window.bind("<Up>", lambda event: change_direction("up"))
window.bind("<Down>", lambda event: change_direction("down"))
window.bind("<f>", lambda event: play_again(), canvas.delete("text"))
snake = Snake()
food = Food()
next_turn(snake, food)
window.mainloop()
I'm not sure how to remove the game over text and I'm not sure why canvas.delete("text") doesn't remove it, what mistake am I making. Whenever I press the f key the game replays but the game over text remains image of the game over text remaining when the game replays above is the full code of the program
Upvotes: 0
Views: 203
Reputation: 1
Check the identifier of the text and use it to delete text. Your identifier must be a variable due to printing text many times, this means you'll add to the identifier variable one or more (depending on your shapes' you have and it's place in the code). Example:
import time
import tkinter as tk
WIDTH = 300
HEIGHT = 50
t = tk.Tk()
c = tk.Canvas(width=WIDTH,height=HEIGHT)
c.pack()
t.title('clock')
t.resizable(0, 0)
t.wm_attributes('-topmost', 1)
x = 0
def loop():
c.create_text(WIDTH/2,HEIGHT/2.5,text=f"time in your place is: {time.asctime()}")
t.update()
if (loop):
return
loop()
while loop:
c.delete(x)
x += 1
loop()
loop()
t.mainloop()
Here, I use an identifier variable(x) to delete text many times. I delete text and write it again with a new identifier to delete it again in an endless loop.
Upvotes: -1
Reputation: 11009
You are not deleting the canvas.text object, which you have put in the global variable text
. The expression:
canvas.delete("text")
deletes all of the objects in the canvas that have the tag "text". There are no such objects, because you haven't used the tag feature; but that's not an error. To delete the object represented by the global variable text
, do this:
canvas.delete(text)
On top of that, you seem to be trying to bind two different functions to the "f" key at the same time. The way to do that is like this:
window.bind("<f>", lambda event: play_again())
window.bind("<f>", lambda event: canvas.delete(text), add='+')
Also, your play_again
function creates an entirely new canvas, but that object is bound to a local variable named canvas
which will hide the global variable of the same name. That is something you need to fix as well.
Upvotes: 3