Pygame射击脚本子弹左出屏时出现拉伸线条问题求助
问题原因及修复方案
问题根源
- 坐标精度丢失:子弹更新位置时,将
x_vel和y_vel强制转为int,导致坐标计算精度丢失,当子弹移出屏幕左侧时,异常的坐标触发Pygame渲染bug,出现拉伸线条。 - 子弹移除逻辑错误:遍历子弹列表时直接使用
pop,会导致遍历过程中跳过部分元素,部分过期或出屏的子弹无法被正确移除,持续渲染引发异常。 - 缺少出屏检测:仅靠
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
相关产品推荐
相关产品推荐

