Python Turtle Pong游戏球速受处理速度影响的解决咨询
解决Python Turtle Pong游戏球速随处理速度变化的问题
你当前的Pong游戏球速随处理速度变化,原因是每帧给球固定的位移值(ball.dx/ball.dy),当程序运行帧速率波动时(比如系统资源占用变化),单位时间内的帧数改变,球的实际移动速度就会不稳定。要解决这个问题,需要用**时间增量(Delta Time)**来控制运动,让移动距离基于实际流逝的时间,而非帧数。
核心思路
- 记录每帧之间的时间差,确保移动距离和真实时间挂钩
- 用时间差乘以基础速度,得到每帧的实际位移值
修改后的代码
import turtle import win32api import time # 新增导入time模块 wind = turtle.Screen() wind.title("Pong game") wind.bgcolor("black") wind.setup(width=800, height=500) wind.tracer(0) # racket1 racket1 = turtle.Turtle() racket1.speed(0) racket1.penup() racket1.color("blue") racket1.shape("square") racket1.goto(-370, 0) racket1.shapesize(stretch_wid=5, stretch_len=1) # racket2 racket2 = turtle.Turtle() racket2.speed(0) racket2.penup() racket2.color("red") racket2.shape("square") racket2.goto(370, 0) racket2.shapesize(stretch_wid=5, stretch_len=1) # ball ball = turtle.Turtle() ball.speed(0) ball.penup() ball.color("white") ball.shape("circle") ball.goto(0, 0) # 调整基础速度为每秒移动的像素值,可根据需求修改 ball.dx = 80 ball.dy = 80 # score writer scw = turtle.Turtle() scw.penup() scw.speed(0) scw.hideturtle() scw.goto(0, 210) scw.color("white") scw.write("Blue: 0 Red: 0", font=("Arial", 24, "bold"), align="center") # racket 1 functions def racket1_up(delta): y = racket1.ycor() if y < 200: # 用时间差计算位移,基础速度设为每秒100像素 y += 100 * delta racket1.sety(y) def racket1_down(delta): y = racket1.ycor() if y > -200: y -= 100 * delta racket1.sety(y) # racket 2 functions def racket2_up(delta): y = racket2.ycor() if y < 200: y += 100 * delta racket2.sety(y) def racket2_down(delta): y = racket2.ycor() if y > -200: y -= 100 * delta racket2.sety(y) # scores p1 = 0 p2 = 0 # 记录上一帧的时间 last_time = time.time() while True: # 计算时间差(秒) current_time = time.time() delta_time = current_time - last_time last_time = current_time wind.update() # ball move - 基于时间差计算位移 ball.setx(ball.xcor() + ball.dx * delta_time) ball.sety(ball.ycor() + ball.dy * delta_time) # border check if ball.ycor() > 239: ball.dy *= -1 if ball.ycor() < -239: ball.dy *= -1 if ball.xcor() > 389: ball.goto(0, 0) p1 += 1 ball.dy *= -1 # 同时反转y方向,避免重复同一轨迹 ball.dx *= -1 scw.clear() scw.write(f"Blue: {p1} Red: {p2}", font=("Arial", 24, "bold"), align="center") if ball.xcor() < -389: ball.goto(0, 0) p2 += 1 ball.dy *= -1 ball.dx *= -1 scw.clear() scw.write(f"Blue: {p1} Red: {p2}", font=("Arial", 24, "bold"), align="center") # ball and racket collision if ball.xcor() > 350 and ball.ycor() < racket2.ycor()+60 and ball.ycor() > racket2.ycor()-60: ball.dx *= -1 if ball.xcor() < -350 and ball.ycor() < racket1.ycor()+60 and ball.ycor() > racket1.ycor()-60: ball.dx *= -1 # racket 1 movement - 传入时间差 w = win32api.GetKeyState(0x57) s = win32api.GetKeyState(0x53) if w < 0: racket1_up(delta_time) if s < 0: racket1_down(delta_time) # racket 2 movement - 传入时间差 u = win32api.GetKeyState(0x26) d = win32api.GetKeyState(0x28) if u < 0: racket2_up(delta_time) if d < 0: racket2_down(delta_time)
关键修改点
- 导入
time模块,用于计算每帧的时间差 - 将球和球拍的基础速度改为每秒移动的像素值,而非每帧位移
- 在循环中计算
delta_time(当前帧与上一帧的时间差),每帧的位移 = 基础速度 × delta_time - 修改球拍移动函数,传入
delta_time参数,确保球拍速度也不受帧速率影响
这样修改后,球和球拍的移动速度会基于真实时间,不管程序运行的帧速率如何波动,实际速度都会保持稳定。
内容的提问来源于stack exchange,提问作者Memo Gaming
相关产品推荐
相关产品推荐

