我正在尝试仅使用 tkinter 制作蛇游戏。我目前被困在游戏的“生成蛇身”功能上, 主要问题是“蛇身”没有跟随“蛇头”。我似乎无法指出为什么会发生这种情况,逻辑似乎应该可以工作,每个“蛇”对象都会在每次迭代时更新到最后一个“蛇”对象的位置。
希望对代码有任何帮助或建议,谢谢。
这是我目前的代码:
from tkinter import *
from time import time, sleep
from random import randint as rand
def move_snake_up():
canvas.move(snake_head, 0, -5)
def move_snake_down():
canvas.move(snake_head, 0, 5)
def move_snake_left():
canvas.move(snake_head, -5, 0)
def move_snake_right():
canvas.move(snake_head, 5, 0)
def snake_up(event):
global snake_direction
snake_direction = "up"
def snake_down(event):
global snake_direction
snake_direction = "down"
def snake_left(event):
global snake_direction
snake_direction = "left"
def snake_right(event):
global snake_direction
snake_direction = "right"
def increase_snake_size():
global snake
snake_tail_position = canvas.coords(snake[len(snake) - 1])
if snake_direction == "up":
snake.append(
canvas.create_rectangle(snake_tail_position[0], snake_tail_position[3], snake_tail_position[0] + 20,
snake_tail_position[3] + 20, fill="white"))
if snake_direction == "down":
snake.append(
canvas.create_rectangle(snake_tail_position[0], snake_tail_position[1] - 20, snake_tail_position[0] + 20,
snake_tail_position[1], fill="white"))
if snake_direction == "left":
snake.append(
canvas.create_rectangle(snake_tail_position[2], snake_tail_position[1], snake_tail_position[2] + 20,
snake_tail_position[1] + 20, fill="white"))
if snake_direction == "right":
snake.append(
canvas.create_rectangle(snake_tail_position[0] - 20, snake_tail_position[1], snake_tail_position[0],
snake_tail_position[1] + 20, fill="white"))
def food_collision():
pass
def main_game():
global snake_size
global positions
global snake
if snake_direction == "up":
move_snake_up()
if snake_direction == "down":
move_snake_down()
if snake_direction == "right":
move_snake_right()
if snake_direction == "left":
move_snake_left()
if snake_size < 5:
increase_snake_size()
snake_size += 1
for i in range(len(snake)):
positions.append(canvas.coords(snake[i]))
for i in range(len(snake) - 1):
canvas.coords(snake[i + 1], positions[i][0], positions[i][1], positions[i][2], positions[i][3])
canvas.after(10, main_game)
window = Tk()
canvas = Canvas(window, width=1280, height=720, bg="black")
canvas.pack()
snake_size = 1
snake = []
positions = []
snake_direction = "right"
snake_head = canvas.create_rectangle(100, 20, 120, 40, fill="white")
snake.append(snake_head)
canvas.focus_set()
canvas.bind("<Right>", snake_right)
canvas.bind("<Left>", snake_left)
canvas.bind("<Up>", snake_up)
canvas.bind("<Down>", snake_down)
main_game()
window.mainloop()
答案 0 :(得分:0)
错误在位置绘制部分。而不是这个
for i in range(len(snake) - 1):
canvas.coords(snake[i + 1], positions[i][0], positions[i][1], positions[i][2], positions[i][3])
改为
for i in range(len(positions) - 1):
canvas.coords(snake[i + 1], positions[i][0], positions[i][1], positions[i][2], positions[i][3])
这会产生:
那么绘制顺序应该改变,现在它在头顶绘制蛇身。因为矩形大小是20,所以我把步长改成了20。
我删除了一个循环以加快游戏周期,将一些 if
更改为 elif
。但过一段时间它仍然变慢。 for 循环减慢绘图速度
# draw past positions of snake
for i in range(1,len(positions)):
canvas.create_rectangle(positions[i][0], positions[i][1], positions[i][0]+20, positions[i][1]+20, fill="white")
因为你不清除屏幕,所以你可以只画最后一个位置,加快游戏速度。
# speed fix
if len(positions) >= 2:
lastpos = len(positions) -1
canvas.create_rectangle(positions[lastpos][0], positions[lastpos][1],
positions[lastpos][0]+20, positions[lastpos][1]+20, fill="white")
我不确定 tkinter 是否有任何类型的硬件加速,但这个技巧可以加快速度。回到我使用 OpenGL 的那一天。您可以使用 PyGame 来加快绘图/游戏过程。
from tkinter import *
from time import time, sleep
from random import randint as rand
def move_snake_up():
canvas.move(snake_head, 0, -20)
def move_snake_down():
canvas.move(snake_head, 0, 20)
def move_snake_left():
canvas.move(snake_head, -20, 0)
def move_snake_right():
canvas.move(snake_head, 20, 0)
def snake_up(event):
global snake_direction
snake_direction = "up"
def snake_down(event):
global snake_direction
snake_direction = "down"
def snake_left(event):
global snake_direction
snake_direction = "left"
def snake_right(event):
global snake_direction
snake_direction = "right"
def increase_snake_size():
global snake
snake_tail_position = canvas.coords(snake[len(snake) - 1])
if snake_direction == "up":
snake.append(
canvas.create_rectangle(snake_tail_position[0], snake_tail_position[3], snake_tail_position[0] + 20,
snake_tail_position[3] + 20, fill="white"))
elif snake_direction == "down":
snake.append(
canvas.create_rectangle(snake_tail_position[0], snake_tail_position[1] - 20, snake_tail_position[0] + 20,
snake_tail_position[1], fill="white"))
elif snake_direction == "left":
snake.append(
canvas.create_rectangle(snake_tail_position[2], snake_tail_position[1], snake_tail_position[2] + 20,
snake_tail_position[1] + 20, fill="white"))
elif snake_direction == "right":
snake.append(
canvas.create_rectangle(snake_tail_position[0] - 20, snake_tail_position[1], snake_tail_position[0],
snake_tail_position[1] + 20, fill="white"))
def food_collision():
pass
def main_game():
global snake_size
global snake_head
global positions
global snake
global index
# draw past positions of snake
#for i in range(1,len(positions)):
# canvas.create_rectangle(positions[i][0], positions[i][1], positions[i][0]+20, positions[i][1]+20, fill="white")
# speed fix
if len(positions) >= 2:
lastpos = len(positions) -1
canvas.create_rectangle(positions[lastpos][0], positions[lastpos][1],
positions[lastpos][0]+20, positions[lastpos][1]+20, fill="white")
# game logic
if snake_direction == "up":
move_snake_up()
elif snake_direction == "down":
move_snake_down()
elif snake_direction == "right":
move_snake_right()
elif snake_direction == "left":
move_snake_left()
positions.append(canvas.coords(snake_head))
canvas.after(10, main_game)
window = Tk()
canvas = Canvas(window, width=1280, height=720, bg="black")
canvas.pack()
snake_size = 1
snake = []
positions = []
index = 0
snake_direction = "right"
snake_head = canvas.create_rectangle(100, 20, 120, 40, fill="white")
snake.append(snake_head)
canvas.focus_set()
canvas.bind("<Right>", snake_right)
canvas.bind("<Left>", snake_left)
canvas.bind("<Up>", snake_up)
canvas.bind("<Down>", snake_down)
main_game()
window.mainloop()
如果您不想看到矩形,请为矩形参数添加轮廓颜色。