Python turtle模块onkeypress()函数失效问题:按键控制paddle无响应求助
问题分析与解决方案
我一眼就瞅出问题啦——你在使用turtle的onkeypress()(或者onkey())时犯了个新手常踩的小坑:你直接执行了sety()方法,而不是把函数本身作为回调传进去。
问题根源
当你写wn.onkeypress(paddle_a.sety(paddle_a.ycor() + 20), "w")的时候,Python会立刻计算paddle_a.ycor() + 20并执行sety(),然后把这个方法的返回值(None)传给onkeypress。这就导致按键事件绑定的是None,自然不会有任何响应,换onkey()也没用,因为本质问题没解决。
修复方案
我们需要把函数引用传给onkeypress,可以用两种方式实现:
方式1:使用lambda表达式(简洁)
lambda可以快速创建匿名函数,刚好适合这种简单的移动逻辑:
import turtle wn = turtle.Screen() wn.title("Pong") wn.setup(width=800, height=600) wn.bgcolor("black") wn.tracer(0) #paddle_a paddle_a = turtle.Turtle() paddle_a.shape("square") paddle_a.goto(-350, 0) paddle_a.speed(0) paddle_a.color("blue") paddle_a.penup() paddle_a.shapesize(stretch_wid=5, stretch_len=1) #paddle_b paddle_b = turtle.Turtle() paddle_b.shape("square") paddle_b.goto(350, 0) paddle_b.speed(0) paddle_b.color("red") paddle_b.penup() paddle_b.shapesize(stretch_wid=5, stretch_len=1) #ball ball = turtle.Turtle() ball.shape("square") ball.goto(0, 0) ball.speed(0) ball.color("white") ball.penup() wn.listen() # 这里用lambda包裹移动逻辑,把函数传给onkeypress wn.onkeypress(lambda: paddle_a.sety(paddle_a.ycor() + 20), "w") wn.onkeypress(lambda: paddle_a.sety(paddle_a.ycor() - 20), "s") wn.onkeypress(lambda: paddle_b.sety(paddle_b.ycor() + 20), "Up") wn.onkeypress(lambda: paddle_b.sety(paddle_b.ycor() - 20), "Down") while True: wn.update()
方式2:定义单独的移动函数(更清晰,适合复杂逻辑)
如果之后要给移动加更多判断(比如限制边界),单独定义函数会更易维护:
import turtle wn = turtle.Screen() wn.title("Pong") wn.setup(width=800, height=600) wn.bgcolor("black") wn.tracer(0) #paddle_a paddle_a = turtle.Turtle() paddle_a.shape("square") paddle_a.goto(-350, 0) paddle_a.speed(0) paddle_a.color("blue") paddle_a.penup() paddle_a.shapesize(stretch_wid=5, stretch_len=1) #paddle_b paddle_b = turtle.Turtle() paddle_b.shape("square") paddle_b.goto(350, 0) paddle_b.speed(0) paddle_b.color("red") paddle_b.penup() paddle_b.shapesize(stretch_wid=5, stretch_len=1) #ball ball = turtle.Turtle() ball.shape("square") ball.goto(0, 0) ball.speed(0) ball.color("white") ball.penup() # 定义移动函数 def paddle_a_up(): y = paddle_a.ycor() y += 20 paddle_a.sety(y) def paddle_a_down(): y = paddle_a.ycor() y -= 20 paddle_a.sety(y) def paddle_b_up(): y = paddle_b.ycor() y += 20 paddle_b.sety(y) def paddle_b_down(): y = paddle_b.ycor() y -= 20 paddle_b.sety(y) wn.listen() # 直接传函数名(不要加括号!) wn.onkeypress(paddle_a_up, "w") wn.onkeypress(paddle_a_down, "s") wn.onkeypress(paddle_b_up, "Up") wn.onkeypress(paddle_b_down, "Down") while True: wn.update()
额外优化建议
可以给 paddle 加个边界限制,防止它飞出屏幕,比如在移动函数里加判断:
def paddle_a_up(): y = paddle_a.ycor() if y < 250: # 因为paddle高度是100(5*20),所以顶部边界是300-50=250 y += 20 paddle_a.sety(y)
这样你的Pong游戏就更完整啦!
内容的提问来源于stack exchange,提问作者Alhamzah Omar
相关产品推荐
相关产品推荐

