Python SDL2 Animation Frame Doesn't Have Time To Render

68 views Asked by At

My goal is to be able to drag polygons around a screen when I click and hold somewhere on the screen. I have created some polygons in Python SDL2. I added some basic animation, so when I drag my mouse, the polygons move too.

This results in continuously reusing the previous buffer. Previous Frames Are Not Ereased

If I clear the buffer before every frame of animation, the polygons flicker as they render in order from top to bottom. If the movement is fast enough, they don't even have time to render. Half rendered group of polygons

Half rendered group of polygons 2

I have tried rendering with

renderflags = (
  sdl2.SDL_RENDERER_ACCELERATED | sdl2.SDL_RENDERER_PRESENTVSYNC
)

I thought this would improve performance, but it made it worse.

How can I avoid the flicker?

This is the part of the code that handles the click input, and clears the buffer:

    grid = new_hex_grid(edge_size, font, radius, x_offset, y_offset)
    grid.render(renderer)

    # Wait for the user to close the window
    running = True
    mousedown_start_position = None
    previous_touch_down_position = None
    while running:
        for event in sdl2.ext.get_events():
            if event.type == sdl2.SDL_QUIT:
                running = False
            elif event.type == sdl2.SDL_MOUSEBUTTONDOWN:
                # print(event.motion.x, event.motion.y)
                print("hi")
                mousedown_start_position = (event.motion.x, event.motion.y)
                previous_touch_down_position = mousedown_start_position
            elif event.type == sdl2.SDL_MOUSEMOTION:
                if mousedown_start_position:
                    pass
                    renderer.clear(0)
                    # print(event.motion.x, event.motion.y)
                    grid.move_to(grid.x + event.motion.x - previous_touch_down_position[0],
                                 grid.y + event.motion.y - previous_touch_down_position[1])
                    grid.render(renderer)
                    previous_touch_down_position = (event.motion.x, event.motion.y)
            elif event.type == sdl2.SDL_MOUSEBUTTONUP:
                mousedown_start_position = None
        # Do all animations here
        # Refresh the screen
        renderer.present()
    # Clean up
    sdl2.ext.quit()

This is how I render the hexagon from a separate hexagon class


        color = (50, 150, 50, 255)
        # Convert the vertex lists to arrays of c_int16
        x_array = (ctypes.c_int16 * vertex_count)(*vx)
        y_array = (ctypes.c_int16 * vertex_count)(*vy)
        # Draw the filled box
        sdl2.sdlgfx.filledPolygonRGBA(renderer.sdlrenderer, x_array, y_array, vertex_count, *color)

This is the class that class the collection of hexagons

class HexGrid(Renderable):
    def __init__(self, font, radius, hexagons_by_idx, x, y):
        self.radius = radius
        self.font = font
        self.x = x
        self.y = y
        self.hexagons_by_idx = hexagons_by_idx

    def move_to(self, x, y):
        self.x = x
        self.y = y

    def render(self, renderer: sdl2.ext.Renderer):
        font_offset_x = self.radius / 2 + self.x
        font_offset_y = self.radius / 3 + self.y
        font_block_width = self.radius
        left_corner_index = 3
        for idx, hexagon in self.hexagons_by_idx.items():
            hexagon.move_to(self.x, self.y)
            hexagon.render(renderer)
            render_font(self.font, font_block_width,
                        hexagon.vertices[left_corner_index][0] + font_offset_x,
                        hexagon.vertices[left_corner_index][1] + font_offset_y, renderer,
                        f"{idx[0]}, {idx[1]}")
0

There are 0 answers