Python tkinter 贪吃蛇游戏绘图延迟
Python tkinter snake game drawing lag
#example snake snake = [[1, 2], [1, 3], [2, 3]]
def draw():
canvas.delete('all')
for segment in snake:
y = segment[0] * 10
x = segment[1] * 10
canvas.create_rectangle(x, y, x + 10, y + 10, fill="red")
canvas.update()
我在 python 中使用 tkinter 创建了一个简单的贪吃蛇游戏,但是当蛇数组包含 30 多个矩形时,移动速度会迅速减慢,所以我想知道是否有更好的方法来绘制对象以便它工作得更快而不是不断地调用这个绘制函数?
另一个可能的问题是移动函数的效率低下:
def move_right(event):
global left, right, up, down
if right != True:
left, right, up, down = False, True, False, False
while right == True:
if snake[0][1] >= snake[1][1]:
for x in range(len(snake) - 1, 0, -1):
snake[x] = snake[x - 1]
snake[0] = [snake[0][0], snake[0][1] + 1]
draw()
time.sleep(0.05)
这是我的第一个真正的游戏所以不要杀了我:(。
您不必删除 canvas 中的所有矩形。您只需删除最后一个矩形并添加新的头部矩形。
要在 snake 列表中添加新的 x,y,您不必移动所有元素 - 您只需要 snake.insert(0, [new_x, new_y])
您可以使用 root.after
代替 while
循环和 sleep
示例 - 不检查碰撞
import tkinter as tk
# === constants ===
BLOCK_SIZE = 10
TIME = 50
# === functions ===
# create all rectangles on canvas
def create_snake(canvas, snake):
snake_rect = []
for x, y in snake:
x1 = x * BLOCK_SIZE
y1 = y * BLOCK_SIZE
x2 = x1 + BLOCK_SIZE
y2 = y1 + BLOCK_SIZE
rect = canvas.create_rectangle(x1,y1,x2,y2, fill='red')
snake_rect.append(rect)
return snake_rect
# move snake - add first rectangle and remove last one
def move(canvas, snake, snake_rect, remove_last=True):
# get head
x, y = snake[0]
# new head position
if direction == 'up':
y = y-1
elif direction == 'down':
y = y+1
elif direction == 'left':
x = x-1
elif direction == 'right':
x = x+1
# add first - new head
snake.insert(0, [x, y])
x1 = x * BLOCK_SIZE
y1 = y * BLOCK_SIZE
x2 = x1 + BLOCK_SIZE
y2 = y1 + BLOCK_SIZE
rect = canvas.create_rectangle(x1,y1,x2,y2, fill='red')
snake_rect.insert(0, rect)
# remove last - tail (if snake doesn't eat 'apple')
if remove_last:
del snake[-1]
canvas.delete(snake_rect[-1])
del snake_rect[-1]
# call `move` function again after TIME miliseconds
root.after(TIME, move, canvas, snake, snake_rect)
# change direction
def change_direction(new_direction):
global direction
#print(new_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
# === main ===
direction = 'up'
# ---
root = tk.Tk()
canvas = tk.Canvas(root)
canvas.pack()
# create long (curved) snake
snake = [[x,25] for x in range(10,35)] + [[35, y] for y in range(25, 1, -1)] + [[x, 1] for x in range(35, 1, -1)]
snake_rect = create_snake(canvas, snake)
# call `move` function after TIME miliseconds
root.after(TIME, move, canvas, snake, snake_rect)
# bind arrows to change snake direction
root.bind('<Left>', lambda event:change_direction('left'))
root.bind('<Right>', lambda event:change_direction('right'))
root.bind('<Up>', lambda event:change_direction('up'))
root.bind('<Down>', lambda event:change_direction('down'))
# start program
root.mainloop()
#example snake snake = [[1, 2], [1, 3], [2, 3]]
def draw():
canvas.delete('all')
for segment in snake:
y = segment[0] * 10
x = segment[1] * 10
canvas.create_rectangle(x, y, x + 10, y + 10, fill="red")
canvas.update()
我在 python 中使用 tkinter 创建了一个简单的贪吃蛇游戏,但是当蛇数组包含 30 多个矩形时,移动速度会迅速减慢,所以我想知道是否有更好的方法来绘制对象以便它工作得更快而不是不断地调用这个绘制函数?
另一个可能的问题是移动函数的效率低下:
def move_right(event):
global left, right, up, down
if right != True:
left, right, up, down = False, True, False, False
while right == True:
if snake[0][1] >= snake[1][1]:
for x in range(len(snake) - 1, 0, -1):
snake[x] = snake[x - 1]
snake[0] = [snake[0][0], snake[0][1] + 1]
draw()
time.sleep(0.05)
这是我的第一个真正的游戏所以不要杀了我:(。
您不必删除 canvas 中的所有矩形。您只需删除最后一个矩形并添加新的头部矩形。
要在 snake 列表中添加新的 x,y,您不必移动所有元素 - 您只需要 snake.insert(0, [new_x, new_y])
您可以使用 root.after
代替 while
循环和 sleep
示例 - 不检查碰撞
import tkinter as tk
# === constants ===
BLOCK_SIZE = 10
TIME = 50
# === functions ===
# create all rectangles on canvas
def create_snake(canvas, snake):
snake_rect = []
for x, y in snake:
x1 = x * BLOCK_SIZE
y1 = y * BLOCK_SIZE
x2 = x1 + BLOCK_SIZE
y2 = y1 + BLOCK_SIZE
rect = canvas.create_rectangle(x1,y1,x2,y2, fill='red')
snake_rect.append(rect)
return snake_rect
# move snake - add first rectangle and remove last one
def move(canvas, snake, snake_rect, remove_last=True):
# get head
x, y = snake[0]
# new head position
if direction == 'up':
y = y-1
elif direction == 'down':
y = y+1
elif direction == 'left':
x = x-1
elif direction == 'right':
x = x+1
# add first - new head
snake.insert(0, [x, y])
x1 = x * BLOCK_SIZE
y1 = y * BLOCK_SIZE
x2 = x1 + BLOCK_SIZE
y2 = y1 + BLOCK_SIZE
rect = canvas.create_rectangle(x1,y1,x2,y2, fill='red')
snake_rect.insert(0, rect)
# remove last - tail (if snake doesn't eat 'apple')
if remove_last:
del snake[-1]
canvas.delete(snake_rect[-1])
del snake_rect[-1]
# call `move` function again after TIME miliseconds
root.after(TIME, move, canvas, snake, snake_rect)
# change direction
def change_direction(new_direction):
global direction
#print(new_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
# === main ===
direction = 'up'
# ---
root = tk.Tk()
canvas = tk.Canvas(root)
canvas.pack()
# create long (curved) snake
snake = [[x,25] for x in range(10,35)] + [[35, y] for y in range(25, 1, -1)] + [[x, 1] for x in range(35, 1, -1)]
snake_rect = create_snake(canvas, snake)
# call `move` function after TIME miliseconds
root.after(TIME, move, canvas, snake, snake_rect)
# bind arrows to change snake direction
root.bind('<Left>', lambda event:change_direction('left'))
root.bind('<Right>', lambda event:change_direction('right'))
root.bind('<Up>', lambda event:change_direction('up'))
root.bind('<Down>', lambda event:change_direction('down'))
# start program
root.mainloop()