You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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只会收集带有指定组件的实体,不会直接匹配实体类本身。

正确做法是拆分组件与实体:

  1. 定义独立的组件类(无需继承Entity),存储多边形数据
  2. 让Entity实例持有这些组件
  3. 在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需指定组件类型,只有当实体拥有所有指定组件时,才会被纳入componentsets
  • process方法的componentsets元素是元组,包含指定组件实例及对应实体

内容的提问来源于stack exchange,提问作者Ferenc Fazekas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 22:54:54