Python Pong游戏使用ontimer函数时屏幕闪瞬消失问题求助
Turtle Pong游戏窗口一闪即灭的问题解决
我是Python编程新手,练习写Pong游戏时,为了获得稳定的球速和刷新率,用ontimer替代了while True循环里的win.update(),但现在窗口只显示一瞬间就消失了。以下是我的代码:
import turtle as t import time import os #Score variables player_a = 0 player_b = 0 paddle_min_step=15 #create Pong main screen win = t.Screen() win.title('Ping Pong Game') win.bgcolor('black') win.setup(width=800,height=600) win.tracer(0) #create left paddle paddle_left=t.Turtle() paddle_left.speed(0) paddle_left.shape('square') paddle_left.shapesize(stretch_wid=5,stretch_len=1) paddle_left.color('yellow') paddle_left.penup() paddle_left.goto(-350,0) #create right paddle paddle_right=t.Turtle() paddle_right.speed(0) paddle_right.shape('square') paddle_right.shapesize(stretch_wid=5,stretch_len=1) paddle_right.color('blue') paddle_right.penup() paddle_right.goto(350,0) #create ball ball=t.Turtle() ball.speed(0) ball.shape('circle') ball.color('white') ball.penup() ball.goto(0,0) ball_dx=1 #variabel for speed of ball in x dir ball_dy=1 #variabel for speed of ball in y dir #create pen for score pen=t.Turtle() pen.speed(0) pen.color('skyblue') pen.penup() pen.hideturtle() pen.goto(0,260) pen.write("Player A: 0 Player B: 0 ",align="center",font=('Monaco',24,"normal")) #create paddle actions def paddle_left_up(): y=paddle_left.ycor() y=y+paddle_min_step paddle_left.sety(y) def paddle_left_down(): y=paddle_left.ycor() y=y-paddle_min_step paddle_left.sety(y) def paddle_right_up(): y=paddle_right.ycor() y=y+paddle_min_step paddle_right.sety(y) def paddle_right_down(): y=paddle_right.ycor() y=y-paddle_min_step paddle_right.sety(y) win.listen() win.onkeypress(paddle_left_up,"w") win.onkeypress(paddle_left_down,'x') win.onkeypress(paddle_right_up,'Up') win.onkeypress(paddle_right_down,'Down') def check_ballpos_score(): global ball_dx, ball_dy win.update() ball.setx(ball.xcor()+ball_dx) ball.sety(ball.ycor()+ball_dy) #setting the borders for the ball #for y dir avoid ball is out of screen #for x dir check ball out of screen -> score if ball.ycor()>290: ball.sety(290) ball_dy=ball_dy * -1 if ball.ycor()<-290: ball.sety(-290) ball_dy=ball_dy * -1 #ball out of screen left/right check + change score if ball.xcor()>390: ball.goto(0,0) player_a+=1 pen.clear() pen.goto(0,260) pen.write("Player A: {} Player B: {} ".format(player_a,player_b),align="center",font=('Monaco',24,"normal")) if ball.xcor()<-390: ball.goto(0,0) player_b+=1 pen.clear() pen.goto(0,260) pen.write("Player A: {} Player B: {} ".format(player_a,player_b),align="center",font=('Monaco',24,"normal")) #handling collision ball with the paddles if(ball.xcor() > 340) and (ball.xcor() < 350) and (ball.ycor() < paddle_right.ycor() + 40 and ball.ycor() > paddle_right.ycor() - 40): ball.setx(340) ball_dx = ball_dx * -1 if(ball.xcor() < -340) and (ball.xcor() > -350) and (ball.ycor() < paddle_left.ycor() + 40 and ball.ycor() > paddle_left.ycor() - 40): ball.setx(-340) ball_dx = ball_dx * -1 win.ontimer(check_ballpos_score, 40) # Main loop check_ballpos_score()
我已尝试多种方法保留屏幕,但至今未成功。
问题分析与解决方案
问题核心有两个:
- 缺少turtle主事件循环:turtle依赖
mainloop()维持窗口运行、处理按键和定时任务,你的代码只触发了一次定时函数就直接退出,导致窗口关闭。 - 分数变量未声明全局:修改
player_a和player_b时没有声明全局,会导致分数无法正确累加。
修改后的完整代码:
import turtle as t import time import os #Score variables player_a = 0 player_b = 0 paddle_min_step=15 #create Pong main screen win = t.Screen() win.title('Ping Pong Game') win.bgcolor('black') win.setup(width=800,height=600) win.tracer(0) #create left paddle paddle_left=t.Turtle() paddle_left.speed(0) paddle_left.shape('square') paddle_left.shapesize(stretch_wid=5,stretch_len=1) paddle_left.color('yellow') paddle_left.penup() paddle_left.goto(-350,0) #create right paddle paddle_right=t.Turtle() paddle_right.speed(0) paddle_right.shape('square') paddle_right.shapesize(stretch_wid=5,stretch_len=1) paddle_right.color('blue') paddle_right.penup() paddle_right.goto(350,0) #create ball ball=t.Turtle() ball.speed(0) ball.shape('circle') ball.color('white') ball.penup() ball.goto(0,0) ball_dx=1 #variabel for speed of ball in x dir ball_dy=1 #variabel for speed of ball in y dir #create pen for score pen=t.Turtle() pen.speed(0) pen.color('skyblue') pen.penup() pen.hideturtle() pen.goto(0,260) pen.write("Player A: 0 Player B: 0 ",align="center",font=('Monaco',24,"normal")) #create paddle actions def paddle_left_up(): y=paddle_left.ycor() y=y+paddle_min_step paddle_left.sety(y) def paddle_left_down(): y=paddle_left.ycor() y=y-paddle_min_step paddle_left.sety(y) def paddle_right_up(): y=paddle_right.ycor() y=y+paddle_min_step paddle_right.sety(y) def paddle_right_down(): y=paddle_right.ycor() y=y-paddle_min_step paddle_right.sety(y) win.listen() win.onkeypress(paddle_left_up,"w") win.onkeypress(paddle_left_down,'x') win.onkeypress(paddle_right_up,'Up') win.onkeypress(paddle_right_down,'Down') def check_ballpos_score(): global ball_dx, ball_dy, player_a, player_b # 新增分数变量的全局声明 win.update() ball.setx(ball.xcor()+ball_dx) ball.sety(ball.ycor()+ball_dy) #setting the borders for the ball #for y dir avoid ball is out of screen #for x dir check ball out of screen -> score if ball.ycor()>290: ball.sety(290) ball_dy=ball_dy * -1 if ball.ycor()<-290: ball.sety(-290) ball_dy=ball_dy * -1 #ball out of screen left/right check + change score if ball.xcor()>390: ball.goto(0,0) player_a+=1 pen.clear() pen.goto(0,260) pen.write("Player A: {} Player B: {} ".format(player_a,player_b),align="center",font=('Monaco',24,"normal")) if ball.xcor()<-390: ball.goto(0,0) player_b+=1 pen.clear() pen.goto(0,260) pen.write("Player A: {} Player B: {} ".format(player_a,player_b),align="center",font=('Monaco',24,"normal")) #handling collision ball with the paddles if(ball.xcor() > 340) and (ball.xcor() < 350) and (ball.ycor() < paddle_right.ycor() + 40 and ball.ycor() > paddle_right.ycor() - 40): ball.setx(340) ball_dx = ball_dx * -1 if(ball.xcor() < -340) and (ball.xcor() > -350) and (ball.ycor() < paddle_left.ycor() + 40 and ball.ycor() > paddle_left.ycor() - 40): ball.setx(-340) ball_dx = ball_dx * -1 win.ontimer(check_ballpos_score, 40) # Main loop check_ballpos_score() win.mainloop() # 启动turtle主事件循环
关键修改说明
- 添加
win.mainloop():这是turtle程序的核心,负责维持窗口运行、处理所有交互事件(按键、定时任务),没有它程序会直接执行完毕退出。 - 补充全局变量声明:在
check_ballpos_score()的global语句中加入player_a和player_b,确保函数内对分数的修改能同步到全局变量,解决分数不更新的问题。
修改后窗口会持续显示,球的运动、碰撞检测、分数更新和按键控制都能正常工作。
内容的提问来源于stack exchange,提问作者Deef
相关产品推荐
相关产品推荐

