如何在Pygame代码中添加可移动弹跳的圆形图形?
如何在Pygame中添加可移动反弹的圆形?
问题描述
我想在如下Pygame代码中添加一个圆形,使其像现有矩形一样移动并在窗口边缘反弹:
import pygame, sys, time from pygame.locals import * # Set up pygame. pygame.init() # Set up the window. WINDOWWIDTH = 400 WINDOWHEIGHT = 400 windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32) pygame.display.set_caption('Animation') # Set up direction variables. DOWNLEFT = 'downleft' DOWNRIGHT = 'downright' UPLEFT = 'upleft' UPRIGHT = 'upright' MOVESPEED = 4 # Set up the colors. WHITE = (255, 255, 255) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) BLACK = (0, 0, 0) # Set up the box data structure. b1 = {'rect':pygame.Rect(300, 80, 50, 100), 'color':RED, 'dir':UPRIGHT} b2 = {'rect':pygame.Rect(200, 200, 20, 20), 'color':GREEN, 'dir':UPLEFT} b3 = {'rect':pygame.Rect(100, 150, 60, 60), 'color':BLUE, 'dir':DOWNLEFT} boxes = [b1, b2, b3] # Run the game loop. while True: #Check for the QUIT event. for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() #Draw the white background onto the surface. windowSurface.fill(WHITE) for b in boxes: # Move the box data structure. if b['dir'] == DOWNLEFT: b['rect'].left -= MOVESPEED b['rect'].top += MOVESPEED if b['dir'] == DOWNRIGHT: b['rect'].left += MOVESPEED b['rect'].top += MOVESPEED if b['dir'] == UPLEFT: b['rect'].left -= MOVESPEED b['rect'].top -= MOVESPEED if b['dir'] == UPRIGHT: b['rect'].left += MOVESPEED b['rect'].top -= MOVESPEED # Check whether the box has moved out of the window. if b['rect'].top < 0: # The box has moved past the top. if b['dir'] == UPLEFT: b['dir'] = DOWNLEFT if b['dir'] == UPRIGHT: b['dir'] = DOWNRIGHT if b['rect'].bottom > WINDOWHEIGHT: # The box has moved past the bottom. if b['dir'] == DOWNLEFT: b['dir'] = UPLEFT if b['dir'] == DOWNRIGHT: b['dir'] = UPRIGHT if b['rect'].left < 0: # The box has moved past the left side. if b['dir'] == DOWNLEFT: b['dir'] = DOWNRIGHT if b['dir'] == UPLEFT: b['dir'] = UPRIGHT if b['rect'].right > WINDOWWIDTH: # The box has moved past the right side. if b['dir'] == DOWNRIGHT: b['dir'] = DOWNLEFT if b['dir'] == UPRIGHT: b['dir'] = UPLEFT # Draw the box onto the surface. pygame.draw.rect(windowSurface, b['color'], b['rect']) # Draw the window onto the screen. pygame.display.update() time.sleep(0.02)
我尝试在boxes列表中添加圆形项,调用pygame.draw.circle(windowSurface, b['color'], b['circle'])进行绘制,但一直出现"circle"无模块属性的错误,不知道该如何实现需求。
解决方案
问题出在你对圆形数据结构的定义和绘制调用上。pygame.draw.circle需要的参数是表面、颜色、圆心坐标、半径,而不是一个名为"circle"的属性。同时为了让圆形复用现有移动和边界反弹逻辑,我们可以给圆形绑定一个Rect对象(用于边界碰撞检测),同时存储圆心和半径信息。
修改后的完整代码
import pygame, sys, time from pygame.locals import * # Set up pygame. pygame.init() # Set up the window. WINDOWWIDTH = 400 WINDOWHEIGHT = 400 windowSurface = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT), 0, 32) pygame.display.set_caption('Animation') # Set up direction variables. DOWNLEFT = 'downleft' DOWNRIGHT = 'downright' UPLEFT = 'upleft' UPRIGHT = 'upright' MOVESPEED = 4 # Set up the colors. WHITE = (255, 255, 255) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) BLACK = (0, 0, 0) PURPLE = (128, 0, 128) # 新增紫色用于圆形 # Set up the shape data structure: 区分矩形和圆形 b1 = {'type': 'rect', 'rect':pygame.Rect(300, 80, 50, 100), 'color':RED, 'dir':UPRIGHT} b2 = {'type': 'rect', 'rect':pygame.Rect(200, 200, 20, 20), 'color':GREEN, 'dir':UPLEFT} b3 = {'type': 'rect', 'rect':pygame.Rect(100, 150, 60, 60), 'color':BLUE, 'dir':DOWNLEFT} # 新增圆形:type标记为circle,rect用于碰撞检测(圆心对应rect中心,宽高是直径),center存储圆心坐标,radius是半径 circle1 = { 'type': 'circle', 'rect': pygame.Rect(150, 100, 40, 40), # 宽高等于直径,方便用rect做边界检测 'color': PURPLE, 'dir': DOWNRIGHT, 'radius': 20, 'center': (150+20, 100+20) # 初始圆心是rect的中心 } shapes = [b1, b2, b3, circle1] # 把所有图形放到统一列表 # Run the game loop. while True: # Check for the QUIT event. for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() # Draw the white background onto the surface. windowSurface.fill(WHITE) for shape in shapes: # Move the shape data structure if shape['dir'] == DOWNLEFT: shape['rect'].left -= MOVESPEED shape['rect'].top += MOVESPEED if shape['dir'] == DOWNRIGHT: shape['rect'].left += MOVESPEED shape['rect'].top += MOVESPEED if shape['dir'] == UPLEFT: shape['rect'].left -= MOVESPEED shape['rect'].top -= MOVESPEED if shape['dir'] == UPRIGHT: shape['rect'].left += MOVESPEED shape['rect'].top -= MOVESPEED # 更新圆形的圆心坐标(因为rect移动了) if shape['type'] == 'circle': shape['center'] = (shape['rect'].centerx, shape['rect'].centery) # Check whether the shape has moved out of the window. if shape['rect'].top < 0: # The shape has moved past the top. if shape['dir'] == UPLEFT: shape['dir'] = DOWNLEFT if shape['dir'] == UPRIGHT: shape['dir'] = DOWNRIGHT if shape['rect'].bottom > WINDOWHEIGHT: # The shape has moved past the bottom. if shape['dir'] == DOWNLEFT: shape['dir'] = UPLEFT if shape['dir'] == DOWNRIGHT: shape['dir'] = UPRIGHT if shape['rect'].left < 0: # The shape has moved past the left side. if shape['dir'] == DOWNLEFT: shape['dir'] = DOWNRIGHT if shape['dir'] == UPLEFT: shape['dir'] = UPRIGHT if shape['rect'].right > WINDOWWIDTH: # The shape has moved past the right side. if shape['dir'] == DOWNRIGHT: shape['dir'] = DOWNLEFT if shape['dir'] == UPRIGHT: shape['dir'] = UPLEFT # 根据图形类型绘制 if shape['type'] == 'rect': pygame.draw.rect(windowSurface, shape['color'], shape['rect']) elif shape['type'] == 'circle': pygame.draw.circle(windowSurface, shape['color'], shape['center'], shape['radius']) # Draw the window onto the screen. pygame.display.update() time.sleep(0.02)
关键修改点说明
- 新增图形类型标记:给每个图形字典添加
type字段,区分是矩形还是圆形,方便后续绘制逻辑判断。 - 圆形的数据结构:
- 用
rect对象做边界碰撞检测,宽高设置为圆形的直径,这样rect的边界正好对应圆形的外切矩形,和现有矩形的碰撞逻辑完全兼容。 - 存储
center(圆心坐标)和radius(半径),用于pygame.draw.circle调用。
- 用
- 移动时更新圆心:每次移动圆形的
rect后,同步更新center为rect的中心坐标,保证圆形位置正确。 - 分类型绘制:在循环中根据
type字段选择调用pygame.draw.rect或pygame.draw.circle。
这样修改后,圆形就能和矩形一样移动并在窗口边缘反弹了。
内容的提问来源于stack exchange,提问作者Retracer9329
相关产品推荐
相关产品推荐

