Python Pygame开发中如何动态创建不同名称的实例属性?
可行实现方案
方案1:用列表存储所有Camera实例(最直观易维护)
你遇到的核心问题是单个属性只能存一个实例,用列表存储所有实例即可解决覆盖问题,同时遍历调用也很方便:
- 首先在你的主类
__init__初始化方法中新增存储摄像头的列表:
def __init__(self): # 原有初始化逻辑保留 self.cameras = [] # 注意:你当前的Wall实例也存在同样的覆盖问题,如果有多个墙建议也新增self.walls = []存储
- 修改地图遍历逻辑,把生成的Camera实例直接加入列表:
# 提前定义方向映射,减少重复if判断,代码更简洁 direction_map = { '8': 'up', '2': 'down', '6': 'right', '4': 'left' } for row, tiles in enumerate(self.mapData): for colone, tile in enumerate(tiles): if tile == 'w': # 多个墙的优化写法:self.walls.append(Wall(self,colone, row)) self.wall = Wall(self,colone, row) if tile in direction_map: # 生成实例后直接加入列表,不会覆盖之前的实例 self.cameras.append(Camera(self, colone, row, direction_map[tile]))
- 后续检测逻辑改为遍历列表逐个判断:
for camera in self.cameras: if camera.x <= self.player.x < camera.x1 and camera.y <= self.player.y < camera.y1: print("detecté") self.alive = False break # 检测到触发即可提前退出循环
方案2:正确使用Pygame的Group功能
你之前用Group失败大概率是没有让Camera类继承Sprite父类,按如下方式修改即可:
- 给Camera类继承
pygame.sprite.Sprite,并且调用父类初始化方法:
import pygame class Camera(pygame.sprite.Sprite): def __init__(self, game, x, y, direction): super().__init__() # 必须加这一行,否则实例无法加入Sprite Group # 原有Camera类的属性逻辑全部保留 self.x = x self.y = y self.x1 = x + 检测范围宽度 self.y1 = y + 检测范围高度 # 其他属性不变
- 主类
__init__中创建Sprite Group:
def __init__(self): # 原有初始化逻辑保留 self.camera_group = pygame.sprite.Group()
- 地图遍历逻辑中把Camera实例加入Group:
if tile in direction_map: cam = Camera(self, colone, row, direction_map[tile]) self.camera_group.add(cam)
- 检测逻辑遍历Group即可,用法和列表完全一致:
for camera in self.camera_group: if camera.x <= self.player.x < camera.x1 and camera.y <= self.player.y < camera.y1: print("detecté") self.alive = False break
不推荐动态创建命名属性的方案:动态生成
self.camera_1、self.camera_2这类属性后续遍历调用反而更麻烦,需要自行拼接属性名字符串,可维护性远低于列表/Group方案。
内容的提问来源于stack exchange,提问作者Unknown piece of garbage
相关产品推荐
相关产品推荐

