0

My goal

Render a polygon using the World-Entity-Applicator pattern in the example pong.py.

My understanding of rendering a custom polygon

  1. Create an instance of a sdl2.ext.World
  2. Create an applicator that filters for a specific class (componenttype)
  3. Add applicator as a system to the world
  4. Create an instance of my polygon object, the sdl2.ext.Entity class will add this in the __ new__ method to the world
  5. When we call process() on the world object, the custom applicator picks up our polygon, and it can render it however it wants to, for example by calling the following
sdl2.sdlgfx.filledPolygonRGBA(renderer.sdlrenderer, x_array, y_array, vertex_count, *color)

The issue

The Applicator doesn't pick up the custom Entity in its component set.

I have written the following code to reproduce the issue. I am expecting it to print out something after "There should be polygons listed here:", but it prints nothing.

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()

1 Answers1

0

Entity is only a holder class that can identify one or more components. It is not the name of the implementing class that is added to the World instance, but the name of the field.

I solved the issue by putting the logic in a separate class and named my field after the Polygon class.

import sdl2.ext


class Polygon:
    def __init__(self, x, y, vertices):
        self.position = (x, y)
        self.vertices = vertices


class CanBeCalledAnythingPolygonEntity(sdl2.ext.Entity):
    def __init__(self, world, polygon):
        self.polgyon = polygon


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 obj in componentsets:
            # Draw the polygon entity here
            print(obj[0].position, obj[0].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())

    CanBeCalledAnythingPolygonEntity(world, Polygon(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()