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

Pygame射击脚本子弹左出屏时出现拉伸线条问题求助

问题原因及修复方案

问题根源

  1. 坐标精度丢失:子弹更新位置时,将x_vel和y_vel强制转为int,导致坐标计算精度丢失,当子弹移出屏幕左侧时,异常的坐标触发Pygame渲染bug,出现拉伸线条。
  2. 子弹移除逻辑错误:遍历子弹列表时直接使用pop,会导致遍历过程中跳过部分元素,部分过期或出屏的子弹无法被正确移除,持续渲染引发异常。
  3. 缺少出屏检测:仅靠lifetime控制子弹消失,未及时移除出屏子弹,放大了渲染问题。

修复步骤

  • 保留子弹坐标的float类型,不强制转换速度为整数,保证移动精度。
  • 添加出屏检测逻辑,当子弹完全超出屏幕范围时立即移除。
  • 改用反向遍历子弹列表,避免遍历过程中修改列表导致的元素跳过问题。

修改后的完整代码

import pygame, math
pygame.init()

display = pygame.display.set_mode((600,600))
clock = pygame.time.Clock()

class Player(object):
    def __init__(self, x, y, radius):
        self.x = x
        self.y = y
        self.radius = radius

    def draw(self, display):
        pygame.draw.circle(display, (255, 0, 0), (int(self.x), int(self.y)), self.radius)

class Bullet(object):
    def __init__(self, x, y, mouse_x, mouse_y):
        self.x = float(x)
        self.y = float(y)
        self.mouse_x = mouse_x
        self.mouse_y = mouse_y
        self.lifetime = 50
        self.speed = 15
        self.angle = math.atan2(mouse_y - y, mouse_x - x)
        self.x_vel = math.cos(self.angle) * self.speed
        self.y_vel = math.sin(self.angle) * self.speed
        
    def update(self):
        self.x += self.x_vel
        self.y += self.y_vel
        self.lifetime -= 1
        
    def draw(self, display):
        pygame.draw.circle(display, (255, 255, 255), (int(self.x), int(self.y)), 5)
        
    def is_off_screen(self, screen_width, screen_height):
        # 检测子弹是否完全超出屏幕
        return (self.x < -5 or self.x > screen_width +5 or 
                self.y < -5 or self.y > screen_height +5)

player = Player(100.0, 100.0, 20)
bullets = []

run = True
# 主循环
while run:
    display.fill((0, 0, 0))

    x, y = pygame.mouse.get_pos()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
            run = False

        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                bullets.append(Bullet(player.x, player.y, x, y))

    # 玩家移动
    keys = pygame.key.get_pressed()
    if keys[pygame.K_w]:
        player.y -= 5
    if keys[pygame.K_s]:
        player.y += 5
    if keys[pygame.K_a]:
        player.x -= 5
    if keys[pygame.K_d]:
        player.x += 5
    
    # 反向遍历子弹列表,安全移除过期或出屏的子弹
    for i in range(len(bullets)-1, -1, -1):
        bullet = bullets[i]
        if bullet.lifetime <= 0 or bullet.is_off_screen(600, 600):
            bullets.pop(i)
            continue
        bullet.update()
        bullet.draw(display)
        
    player.draw(display)

    clock.tick(60)
    pygame.display.update()

内容的提问来源于stack exchange,提问作者CapybaraProgrammer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 17:12:47