[Python] Pygame stuttering/choppy image movement

Discussão em 'Python' iniciado por Stack, Março 5, 2025.

  1. Stack

    Stack Membro Participativo

    I am currently trying to create an occlusion object in Pygame, trying to dynamically obscure part of an image. The way I currently have this occlusion set up is that it is a transparent surface being blited to the main surface of the image; however, no matter how I choose to implement this occlusion, I have the same issue of flickering/inconsistent position of the occlusion surface Occlusion with intended transparency

    Occlusion with coloring

    Method for creating occlusion within the sprite object as well as sprites run method:

    def create_occlusion_rect(self, pos_x, pos_y, width, height):
    #spirte_occlusion = occlusion(pos_x, pos_y, width, height)

    spirte_occlusion = [[pos_x, pos_y], pygame.surface.Surface((width, height))]
    self.occlusion_rects.append(spirte_occlusion)
    return spirte_occlusion


    def run(self, event_loop, delta_time):

    self.surface.fill((20, 20, 20))
    self.surface.blit(self.surface_image, ((self.width_difference), - (self.height_difference)))
    for occlusion in self.occlusion_rects:
    occlusion[1].fill((0, 0, 255))
    self.surface.blit(occlusion[1], occlusion[0])



    Code for the arms object:

    class grab_arms():
    def __init__(self, pos, direction, groups):

    self.buffer = 50
    self.pos = [pos[0] - 24 - self.buffer, pos[1] + 16]
    self.direction = direction
    self.action = "init"
    front = groups[0]
    back = groups[1]


    arm_image_front = pygame.image.load("assets/pictures/projectiles/arms/front/right/0.png").convert_alpha()
    arm_image_back = pygame.image.load("assets/pictures/projectiles/arms/back/right/0.png").convert_alpha()

    self.front_arms = sprite("Arms_Front", [self.pos[0] - 6, self.pos[1] + 6], [front], self.pos, [5, 5], arm_image_front, buffer=[self.buffer, 0])
    self.back_arms = sprite("Arms_Back", [self.pos[0] - 2, self.pos[1]], [back], self.pos, [5, 5], arm_image_back, buffer=[self.buffer, 0])

    self.front_surf_pos = [self.front_arms.pos[0], self.front_arms.pos[1]]
    self.back_surf_pos = [self.back_arms.pos[0], self.back_arms.pos[1]]

    self.occlusion_width = 40
    self.occlusion_width_max = self.occlusion_width
    self.occlusion_height = 40

    self.total_movement_x = 0
    self.total_movement_y = 0


    self.back_occlusion = self.back_arms.create_occlusion_rect(self.buffer, 0, self.occlusion_width, self.occlusion_height)
    self.front_occlusion = self.front_arms.create_occlusion_rect(self.buffer, 0, self.occlusion_width, self.occlusion_height)

    self.reverse = False
    self.destroy = False

    def run(self, delta_time):

    if self.reverse == False and self.destroy == False:
    frame_movement = 50 * delta_time
    self.total_movement_x += frame_movement
    if self.total_movement_x >= self.occlusion_width_max:
    self.reverse = True
    self.occlusions_cleared = True
    else:
    self.front_arms.pos[0] += frame_movement
    self.back_arms.pos[0] += frame_movement
    self.occlusion_width -= frame_movement
    if self.occlusion_width < 1:
    self.occlusion_width = 1
    self.front_occlusion[0][0] -= frame_movement
    self.back_occlusion[0][0] -= frame_movement
    #self.front_arms.resize_occlusion(0, (self.occlusion_width+100, self.occlusion_height))




    elif self.reverse == True and self.destroy == False:
    frame_movement = -50 * delta_time
    self.total_movement_x += frame_movement
    if self.total_movement_x <= 0:
    self.destroy = True
    else:
    self.front_arms.pos[0] += frame_movement
    self.back_arms.pos[0] += frame_movement
    self.occlusion_width -= frame_movement
    if self.occlusion_width < 1:
    self.occlusion_width = 1
    self.front_occlusion[0][0] -= frame_movement
    self.back_occlusion[0][0] -= frame_movement
    #self.front_arms.resize_occlusion(0, (self.occlusion_width+100, self.occlusion_height))


    Code for initializing and updating grab arms from player class

    #initalizing
    if keys[pygame.K_e]:
    for event in event_loop:
    if event.type == pygame.KEYDOWN and event.key == 101 and self.movement_options['grab']== True:
    self.grab_arms = grab_arms(self.pos, self.direction_animation, self.grab_arms_groups)
    self.movement_options['grab'] = False



    #updating
    if self.grab_arms != None:
    self.grab_arms.run(delta_time)
    if self.grab_arms.destroy == True:
    for group in self.grab_arms_groups:
    if len(group) > 0:
    group.pop(0)
    self.grab_arms = None
    self.movement_options['grab'] = True


    Code for drawing objects in level order

    def draw(self, display):
    self.camera.update()
    self.camera.draw_ui(display, self.back_sprites, self.wall_sprites, self.entity_sprites, self.front_sprites)


    Code for basic camera rendering

    def draw_ui(self, display, *sprites):
    for sprite_groups in sprites:
    for sprite in sprite_groups:
    display.blit(sprite.surface, sprite.pos)


    Somethings I have tried, all of which have had the same effect,

    • Transforming the subsurface instead of moving it
    • Drawing a rectangle instead of a surface and changing position
    • Drawing a rectangle and changing the width

    Continue reading...

Compartilhe esta Página