Pygame创建的圆形小球无法显示 排查Ball类与游戏函数错误
Pygame 圆形小球无法显示问题修复
核心问题点
- 绘图参照系错误:
pygame.draw.circle是在self.image这个独立的小球专属Surface上绘图,该Surface的坐标原点是自身左上角,你传入的圆心坐标是相对于整个屏幕的self.rect.centerx/centery,数值远大于Surface本身的宽高,圆完全被画到Surface可视区域外,根本没有实际绘制内容。正确的圆心坐标应为Surface自身中心点(self.radius, self.radius)。 - 未将小球绘制到主屏幕:你在
update_screen里仅遍历调用ball.draw_ball()在小球自己的Surface上绘图,从来没有把小球的Surface贴到主屏幕画布上,相当于在小画纸上画完内容没往主画布上贴,自然看不到。 - Sprite更新方法不匹配:Pygame的Sprite组调用
update()时,会自动执行组内每个精灵的update()方法,你把小球的更新方法命名为update_ball(),移动、边界判断的逻辑根本不会被触发,就算小球显示了也不会动。 - 边界判断逻辑写反:原
update_ball里的边界判断布尔逻辑完全颠倒,会导致小球在窗口内时不会移动,碰到边界也不会反弹。 - 代码缩进错误:
update_balls函数里y轴速度反转的代码缩进异常,没有归属到elif分支下,运行会直接抛出语法错误。
修正后代码
Ball类修正
import pygame from pygame.sprite import Sprite import random class Ball(Sprite): def __init__(self, bg_settings, screen, user): super(Ball,self).__init__() self.screen = screen self.bg_settings = bg_settings # 加SRCALPHA参数开启透明通道,避免球周围显示黑色方块底 self.image = pygame.Surface((bg_settings.ball_radius*2, bg_settings.ball_radius*2), pygame.SRCALPHA) self.rect = self.image.get_rect() self.screen_rect = screen.get_rect() # 随机初始速度,可加判断过滤0值避免小球静止 self.velocityx = random.randint(-bg_settings.ball_speed, bg_settings.ball_speed) self.velocityy = random.randint(-bg_settings.ball_speed, bg_settings.ball_speed) # 随机初始位置,避开用户控件区域 self.rect.centerx = random.randint(0, bg_settings.screen_width) self.rect.centery = random.randint(0, bg_settings.screen_height) while (self.rect.centerx in range(user.rect.left - 30, user.rect.right + 30) and self.rect.centery in range(0, user.rect.top + 30)): self.rect.centerx = random.randint(0,bg_settings.screen_width) self.rect.centery = random.randint(0,bg_settings.screen_height) self.color = bg_settings.ball_color self.radius = bg_settings.ball_radius # 初始化时直接在自身Surface上画好圆,不用每帧重复绘制 pygame.draw.circle(self.image, self.color, (self.radius, self.radius), self.radius) # 方法名统一为update,匹配Sprite组的自动调用逻辑 def update(self): self.rect.centerx += self.velocityx self.rect.centery += self.velocityy # 左右边界反弹 if self.rect.left <= 0 or self.rect.right >= self.screen_rect.right: self.velocityx *= -1 # 上下边界反弹 if self.rect.top <= 0 or self.rect.bottom >= self.screen_rect.bottom: self.velocityy *= -1
游戏功能函数修正
def update_screen(ai_settings, screen, user, balls, gem): screen.fill(ai_settings.bg_color) user.blitme() # 直接调用Sprite组的draw方法,自动把所有小球按rect位置贴到主屏幕 balls.draw(screen) gem.blitme() pygame.display.flip() def set_balls(balls, bg_settings, screen, user): for ball_number in range(bg_settings.num_balls): new_ball = Ball(bg_settings, screen, user) balls.add(new_ball) def update_balls(balls): # 调用组update自动执行所有小球的移动、边界判断逻辑 balls.update()
主循环保持原有结构即可,调用update_balls时无需再传入bg_settings参数,边界判断逻辑已经整合到Ball类内部。
内容的提问来源于stack exchange,提问作者szhang04
相关产品推荐
相关产品推荐

