Python Tkinter - 蛇头跟随蛇身的问题

时间:2020-12-24 12:35:41

标签: python tkinter

我正在尝试仅使用 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()

1 个答案:

答案 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])

这会产生:

snake

那么绘制顺序应该改变,现在它在头顶绘制蛇身。因为矩形大小是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()

如果您不想看到矩形,请为矩形参数添加轮廓颜色。

snake tkinter

相关问题