SDL2自定义World Applicator无法拾取自定义Entity实现问题
问题:SDL2 World-Entity-Applicator模式无法识别自定义Entity
我的目标
借助示例pong.py中的World-Entity-Applicator模式渲染多边形。
我对自定义多边形渲染的理解
- 创建
sdl2.ext.World实例 - 创建筛选特定类(componenttype)的applicator
- 将applicator作为系统添加至world
- 创建多边形对象实例,
sdl2.ext.Entity类会在__new__方法中将其添加到world - 调用world的
process()方法时,自定义applicator应拾取多边形并进行渲染,例如调用:
sdl2.sdlgfx.filledPolygonRGBA(renderer.sdlrenderer, x_array, y_array, vertex_count, *color)
遇到的问题
Applicator无法在其组件集中识别自定义Entity。编写的复现代码中,预期在"There should be polygons listed here:"后输出内容,但实际无任何输出。代码如下:
import sdl2.ext class Polygon(sdl2.ext.Entity): def __init__(self, world, x, y, vertices): self.position = (x, y) self.vertices = vertices class PolygonApplicator(sdl2.ext.Applicator): def __init__(self): super().__init__() self.componenttypes = (Polygon,) def process(self, world, componentsets): print("There should be polygons listed here:") for polygon in componentsets: # Draw the polygon entity here print(polygon) def run(): sdl2.ext.init() window = sdl2.ext.Window("Polygon Example", size=(640, 480)) window.show() world = sdl2.ext.World() world.add_system(PolygonApplicator()) polygon = Polygon(world, 100, 100, [(0, 0), (50, 0), (50, 50), (0, 50)]) running = True while running: events = sdl2.ext.get_events() for event in events: if event.type == sdl2.SDL_QUIT: running = False break world.process() window.refresh() sdl2.ext.quit() if __name__ == "__main__": run()
解决方案
问题核心是对Applicator的作用逻辑理解偏差:sdl2.ext.Applicator是用来筛选**组件(Component)而非实体(Entity)**的。你把Polygon定义成Entity子类,但Applicator只会收集带有指定组件的实体,不会直接匹配实体类本身。
正确做法是拆分组件与实体:
- 定义独立的组件类(无需继承
Entity),存储多边形数据 - 让
Entity实例持有这些组件 - 在
Applicator中指定要筛选的组件类型
修改后的代码如下:
import sdl2.ext # 定义组件类,负责存储数据 class PositionComponent: def __init__(self, x, y): self.x = x self.y = y class VerticesComponent: def __init__(self, vertices): self.vertices = vertices # Applicator筛选同时持有PositionComponent和VerticesComponent的实体 class PolygonApplicator(sdl2.ext.Applicator): def __init__(self): super().__init__() self.componenttypes = (PositionComponent, VerticesComponent) def process(self, world, componentsets): print("There should be polygons listed here:") # componentsets每个元素是(PositionComponent实例, VerticesComponent实例, 对应实体) for pos, verts, entity in componentsets: print(f"Polygon at ({pos.x}, {pos.y}) with vertices: {verts.vertices}") def run(): sdl2.ext.init() window = sdl2.ext.Window("Polygon Example", size=(640, 480)) window.show() world = sdl2.ext.World() world.add_system(PolygonApplicator()) # 创建实体并绑定组件 polygon = sdl2.ext.Entity(world) polygon.position = PositionComponent(100, 100) polygon.vertices = VerticesComponent([(0, 0), (50, 0), (50, 50), (0, 50)]) running = True while running: events = sdl2.ext.get_events() for event in events: if event.type == sdl2.SDL_QUIT: running = False break world.process() window.refresh() sdl2.ext.quit() if __name__ == "__main__": run()
关键说明
sdl2.ext.Entity是组件容器,本身不作为组件被Applicator筛选Applicator的componenttypes需指定组件类型,只有当实体拥有所有指定组件时,才会被纳入componentsetsprocess方法的componentsets元素是元组,包含指定组件实例及对应实体
内容的提问来源于stack exchange,提问作者Ferenc Fazekas
相关产品推荐
相关产品推荐

