You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 13:10:50