如何在Python Turtle中实现平滑输入 解决Pong游戏挡板移动卡顿问题
解决方案
你当前遇到的卡顿来自turtle的onkeypress事件依赖操作系统的按键重复触发逻辑,系统默认首次触发按键事件后会有数百毫秒的延迟才会连续发送重复事件,这就是初始跳动后才移动的原因。
我们改用按键状态标记的方案规避系统延迟:
- 新增布尔变量记录对应按键的按下/松开状态
- 按键事件仅用来更新状态,不直接处理移动
- 移动逻辑放到主循环中执行,完全由程序自主控制移动节奏
完整修改后代码
import turtle import time game: bool = True win = turtle.Screen() win.setup(width=800, height=600) win.tracer(0) win.bgcolor("black") # 补充黑色背景,避免看不到白色挡板 # 按键状态标记,初始为未按下 paddle_a_up_pressed = False paddle_a_down_pressed = False paddle_b_up_pressed = False paddle_b_down_pressed = False # Paddle A paddle_a = turtle.Turtle() paddle_a.speed(0) paddle_a.shape("square") paddle_a.color("white") paddle_a.shapesize(stretch_wid=5, stretch_len=1) paddle_a.penup() paddle_a.goto(-350, 0) # Paddle B paddle_b = turtle.Turtle() paddle_b.speed(0) paddle_b.shape("square") paddle_b.color("white") paddle_b.shapesize(stretch_wid=5, stretch_len=1) paddle_b.penup() paddle_b.goto(350, 0) # 按键状态更新函数 def a_up_press(): global paddle_a_up_pressed paddle_a_up_pressed = True def a_up_release(): global paddle_a_up_pressed paddle_a_up_pressed = False def a_down_press(): global paddle_a_down_pressed paddle_a_down_pressed = True def a_down_release(): global paddle_a_down_pressed paddle_a_down_pressed = False def b_up_press(): global paddle_b_up_pressed paddle_b_up_pressed = True def b_up_release(): global paddle_b_up_pressed paddle_b_up_pressed = False def b_down_press(): global paddle_b_down_pressed paddle_b_down_pressed = True def b_down_release(): global paddle_b_down_pressed paddle_b_down_pressed = False # 绑定按下和松开事件 win.listen() win.onkeypress(a_up_press, "w") win.onkeypress(a_up_press, "W") win.onkeyrelease(a_up_release, "w") win.onkeyrelease(a_up_release, "W") win.onkeypress(a_down_press, "s") win.onkeypress(a_down_press, "S") win.onkeyrelease(a_down_release, "s") win.onkeyrelease(a_down_release, "S") win.onkeypress(b_up_press, "Up") win.onkeyrelease(b_up_release, "Up") win.onkeypress(b_down_press, "Down") win.onkeyrelease(b_down_release, "Down") # 主循环 while game: win.update() # 处理挡板A移动 if paddle_a_up_pressed and paddle_a.ycor() + 70 < 300: paddle_a.sety(paddle_a.ycor() + 3) if paddle_a_down_pressed and paddle_a.ycor() - 70 > -300: paddle_a.sety(paddle_a.ycor() - 3) # 处理挡板B移动 if paddle_b_up_pressed and paddle_b.ycor() + 70 < 300: paddle_b.sety(paddle_b.ycor() + 3) if paddle_b_down_pressed and paddle_b.ycor() - 70 > -300: paddle_b.sety(paddle_b.ycor() - 3) # 控制帧率约60帧/秒,保证移动速度均匀 time.sleep(0.016)
参数调整说明
- 可修改主循环中的
time.sleep参数调整帧率,数值越小帧率越高 - 可修改移动步长(代码中的
+3/-3)调整挡板移动速度,数值越大移动越快
内容的提问来源于stack exchange,提问作者TaCo
相关产品推荐
相关产品推荐

