蛇头为什么跳来跳去



我一直在用tkinter在python中制作蛇游戏,我已经完成了很多,但最近遇到了一个问题。我试图定义,如果用户按下其中一个方向按钮(箭头键或A、W、S、D(,蛇的运动将继续,这就是它应该的样子。它是有效的,但当看到用户改变当前方向时,蛇的头部会跳来跳去,出现故障。现在在游戏中抓水果是一种挑战,因为蛇头跳得太多了。也因为跳跃,游戏导致游戏结束的场景要容易得多。我该怎么做?我的代码:

from tkinter import *
from tkinter import ttk
import random
root = Tk()
style = ttk.Style()
style.configure("TLabel", font=('Helvetica', 40, 'bold'))
root.geometry("737x300")
root.resizable(0, 0)
def StartGame(lbl_txt: str, btn_txt: str, canvas=None, score_lbl=None):
# Just a function for the start of the game and the gameover
pass

def game():
main_x, main_y = 200, 160
key = ""
velocity = 20
can_w, can_h = 600, 300
grid_x, grid_y = [gx for gx in range(0, can_w, velocity)], [gy for gy in range(0, can_h, velocity)]
cords_list = [[main_x, main_y]]
tales = {}
score = 0
canvas = Canvas(root, width=can_w, height=can_h, bg="light blue")
score_lbl = Label(root, text=f"Score: {score}", font=('Arial', 24, 'italic'))
canvas.grid()
score_lbl.grid(row=0, column=1)
canvas.create_rectangle(main_x, main_y, main_x + velocity, main_y + velocity, fill="purple", outline="purple")
fruit_x, fruit_y = random.choice(grid_x), random.choice(grid_y)
fruit = canvas.create_rectangle(fruit_x, fruit_y, fruit_x + velocity, fruit_y + velocity, fill="red", outline="red")
def spawn():
nonlocal fruit, fruit_x, fruit_y, score
score += 1
score_lbl.config(text=f"Score: {score}")
canvas.delete(fruit)
if key == "Up":
cords_list.append([cords_list[-1][0], cords_list[-1][1] + velocity])
tales.update({f"tale-{score}": canvas.create_rectangle(
cords_list[-1][0], cords_list[-1][1], cords_list[-1][0] + velocity, cords_list[-1][1] + velocity
)})
elif key == "Down":
cords_list.append([cords_list[-1][0], cords_list[-1][1] - velocity])
tales.update({f"tale-{score}": canvas.create_rectangle(
cords_list[-1][0], cords_list[-1][1], cords_list[-1][0] + velocity, cords_list[-1][1] + velocity
)})
elif key == "Left":
cords_list.append([cords_list[-1][0] + velocity, cords_list[-1][1]])
tales.update({f"tale-{score}": canvas.create_rectangle(
cords_list[-1][0], cords_list[-1][1], cords_list[-1][0] + velocity, cords_list[-1][1] + velocity
)})
elif key == "Right":
cords_list.append([cords_list[-1][0] - velocity, cords_list[-1][1]])
tales.update({f"tale-{score}": canvas.create_rectangle(
cords_list[-1][0], cords_list[-1][1], cords_list[-1][0] + velocity, cords_list[-1][1] + velocity
)})
fruit_x, fruit_y = random.choice(grid_x), random.choice(grid_y)
fruit = canvas.create_rectangle(fruit_x, fruit_y, fruit_x + 20, fruit_y + 20, fill="red", outline="red")
def up(event):
nonlocal key
if key != "Up":
key = "Up"
def move():
if cords_list[0][1] > 0 and [cords_list[0][0], cords_list[0][1] - velocity] not in cords_list:
canvas.move(1, 0, -velocity)
# print([cords_list[0][0], cords_list[0][1] - velocity], cords_list)
for v in range(len(cords_list) - 1, 0, -1):
cords_list[v] = cords_list[v - 1].copy()
cords_list[0][1] -= velocity
for count in range(1, len(tales) + 1):
canvas.delete(tales[f"tale-{count}"])
tales[f"tale-{count}"] = canvas.create_rectangle(cords_list[count][0], cords_list[count][1],
   cords_list[count][0] + 20,
   cords_list[count][1] + 20)
if cords_list[0][0] == fruit_x and cords_list[0][1] == fruit_y:
spawn()
if key == "Up":
root.after(80, move)
else:
StartGame("GAME OVER!", "Restart", canvas, score_lbl)
move()
def down(event):
nonlocal key
if key != "Down":
key = "Down"
def move():
if cords_list[0][1] + 20 < can_h and [cords_list[0][0], cords_list[0][1] + velocity] not in cords_list:
canvas.move(1, 0, velocity)
for v in range(len(cords_list) - 1, 0, -1):
cords_list[v] = cords_list[v - 1].copy()
cords_list[0][1] += velocity
for count in range(1, len(tales) + 1):
canvas.delete(tales[f"tale-{count}"])
tales[f"tale-{count}"] = canvas.create_rectangle(cords_list[count][0], cords_list[count][1],
   cords_list[count][0] + 20,
   cords_list[count][1] + 20)
if cords_list[0][0] == fruit_x and cords_list[0][1] == fruit_y:
spawn()
if key == "Down":
root.after(80, move)
else:
StartGame("GAME OVER!", "Restart", canvas, score_lbl)
move()
def left(event):
nonlocal key
if key != "Left":
key = "Left"
def move():
if cords_list[0][0] > 0 and [cords_list[0][0] - velocity, cords_list[0][1]] not in cords_list:
canvas.move(1, -velocity, 0)
for v in range(len(cords_list) - 1, 0, -1):
cords_list[v] = cords_list[v - 1].copy()
cords_list[0][0] -= velocity
for count in range(1, len(tales) + 1):
canvas.delete(tales[f"tale-{count}"])
tales[f"tale-{count}"] = canvas.create_rectangle(cords_list[count][0], cords_list[count][1],
   cords_list[count][0] + 20,
   cords_list[count][1] + 20)
if cords_list[0][0] == fruit_x and cords_list[0][1] == fruit_y:
spawn()
if key == "Left":
root.after(80, move)
else:
StartGame("GAME OVER!", "Restart", canvas, score_lbl)
move()
def right(event):
nonlocal key
if key != "Right":
key = "Right"
def move():
if cords_list[0][0] + 20 < can_w and [cords_list[0][0] + velocity, cords_list[0][1]] not in cords_list:
canvas.move(1, velocity, 0)
for v in range(len(cords_list) - 1, 0, -1):
cords_list[v] = cords_list[v - 1].copy()
cords_list[0][0] += velocity
for count in range(1, len(tales) + 1):
canvas.delete(tales[f"tale-{count}"])
tales[f"tale-{count}"] = canvas.create_rectangle(cords_list[count][0], cords_list[count][1],
   cords_list[count][0] + 20,
   cords_list[count][1] + 20)
if cords_list[0][0] == fruit_x and cords_list[0][1] == fruit_y:
spawn()
if key == "Right":
root.after(80, move)
else:
StartGame("GAME OVER!", "Restart", canvas, score_lbl)
move()
root.bind("<Up>", up)
root.bind("<Key-w>", up)
root.bind("<Key-W>", up)
root.bind("<Down>", down)
root.bind("<Key-s>", down)
root.bind("<Key-S>", down)
root.bind("<Left>", left)
root.bind("<Key-a>", left)
root.bind("<Key-A>", left)
root.bind("<Right>", right)
root.bind("<Key-d>", right)
root.bind("<Key-D>", right)
game()
root.mainloop()

您有一个逻辑问题。

  1. 用户按下UP键:
    • CCD_ 1被设置为"0";向上">
    • 蛇向上移动1
    • 下一个move()计划在现在+80ms
  2. 80ms后蛇向上移动,下一个move()计划在现在+80ms
  3. 80ms后蛇向上移动,下一个move()计划在现在+80ms
  4. 用户按下LEFT(向左(键:
    • 键被设置为";左">
    • 蛇向左移动1
    • 下一个左-move()计划在现在+80ms
  5. 预定的";UP";执行按键前的move()
    • snake向上摆动1并且不重新安排upmove();左">
  6. 稍后按下LEFT键后80毫秒:
    • 蛇向左移动1
    • 下一个move()计划在现在+80ms

等。

最简单的修复:

def up(event):  
nonlocal key
if key != "Up":
key = "Up"
def move():
if key != "Up": # same for left/right/down functions - do not execute
# movement if key got changed
return
if cords_list[0][1] > 0 and .... # the remainder of your code

所有其他移动事件也是如此。

最新更新