2

I was just curious if someone could take a look at this code and explain to me why the walking_right images won't animate but the walking left will? Also, I have a set of animations for standing still, what do you think would be the best way to implement this? Lastly, I am trying to get a handle on OOP. Is this doing ok or what other critiques would you suggest. Thanks.

import pygame

WIDTH = 640
HEIGHT = 480
FPS = 100

WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (0, 0, 255)
GREY = (235, 235, 235)

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

import pygame
import character_tuple_list as tl
from settings import Settings

class Player(pygame.sprite.Sprite):

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        #Load in our sprite sheet with character data
        player_sheet = pygame.image.load(r'D:\Python Projects\Group Game\Character\Character 50x37.png').convert_alpha()
        self.image = pygame.transform.scale(player_sheet, (50, 37))

        #Get our coordinates or screen and image
        gm_settings = Settings()
        gm_settings.screen_height
        self.rect = self.image.get_rect()

        #Set image in the bottom middle of screen
        self.rect.centerx = 400 #center of rectangle
        self.rect.bottom = 470#pixels up from the bottom

        #Set the speed
        self.speedx = 0

        #Set Direction
        self.left = False
        self.right = False


        self.standing = []
        for image in tl.image_list_standing:
            self.standing.append(player_sheet.subsurface(image))    

        self.walking_right = []
        for image in tl.image_list_right:
            self.walking_right.append(player_sheet.subsurface(image))

        self.walking_left = []
        for inverse in self.walking_right:
            inverse = pygame.transform.flip(inverse, True, False)
            self.walking_left.append(inverse)    


    def update(self):

        gm_settings = Settings()
#        noi, time, current_image = 3,0,0
        pos_x = self.rect.x

        if self.right:
            frame = (pos_x // 30) % len(self.walking_right)
            self.image = self.walking_right[frame]
        if self.left:
            frame = (pos_x // 30) % len(self.walking_left)
            self.image = self.walking_left[frame]
        else:
            self.image = self.standing[0]

        self.speedx = 0 #Need these to make sure
        keystate = pygame.key.get_pressed()


        if keystate[pygame.K_LEFT]:
            self.speedx = -1
            self.left = True
            self.right = False

        elif keystate[pygame.K_RIGHT]:
            self.speedx = 1
            self.left = False
            self.right = True   

        else:
            self.right = False
            self.left = False

        self.rect.x += self.speedx

        #Set Walls for Width and Height
        if self.rect.right > gm_settings.screen_width:
            self.rect.rect = gm_settings.screen_width
        if self.rect.left < 0:
            self.rect.left = 0

all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)


running = True
while running:
    clock.tick(FPS)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    all_sprites.update()
    screen.fill(GREY)
    all_sprites.draw(screen)
    pygame.display.flip()

pygame.quit()# -*- coding: utf-8 -*-

1 Answer 1

1

You problem is in the conditional group I quote bellow:

    if self.right:
        frame = (pos_x // 30) % len(self.walking_right)
        self.image = self.walking_right[frame]
    if self.left:
        frame = (pos_x // 30) % len(self.walking_left)
        self.image = self.walking_left[frame]
    else:
        self.image = self.standing[0]

See: if the character is not walking left (self.left), it will follow the else clause, and the standing image will be used. Even when the first if clause is followed (self.right is True), the image is reset to standing in this else clause.

Just change the if self.left: line to elif self.left: - that will prevent the else clause to be entered when self.right is True.

I will skip comments on the OO aspects at this time, as those would be too broad - but this code is not bad at all. One's attention is caught by the fact the update method calls pygame's get_pressed directly - since there won't be a lot of sprites simultaneously in need of the keyboard input, you could create another "update_movement" method that would take the vector returned by get_pressed as a parameter, and be called explicitly from the main loop - that would decouple your class from pygame's keyboard specifics, and would even free your character to be machine or network controlled.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, this is awesome!! Sorry for the too broad of question!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.