1

I just started to learn pygame and there has been a issue of misplaced sprites. I think I don't have a clear idea of relation between image and rect. I got a player with standing and walking animation. standing

walking

in the code I just used get_rect so the rects look like

when I run the code the position of the image is decided by the top left corner(I think, I just don't really get this part) so the sprites are misplaced, when I press left key the player will flash to right a bit then start walking.

Is there any way to modify code so that they look like this when player walks left.

Here's my code for player

class Player():
    def __init__(self,x,y):
        self.img_stand = pygame.image.load('D:\ThingThing\inthething\H stand.png')
        self.img_standL = pygame.image.load('D:\ThingThing\inthething\H standL.png')
        #walk animation
        self.images_right = []
        self.images_left = []
        self.index = 0
        self.counter = 0
        self.direction = 0


        for num in range(1,17):
            img_right = pygame.image.load(f'D:\ThingThing\inthething\H walk{num}.png')
            self.images_right.append(img_right)

        for num in range(1,17):
            img_left = pygame.image.load(f'D:\ThingThing\inthething\H walkL{num}.png')
            self.images_left.append(img_left)

        self.image = self.img_stand
        self.rect = self.image.get_rect()
        print(self.rect)

        self.rect.x = x
        self.rect.y = y

        self.vel_y = 0
        self.jumped = False
    def update(self):
        dx = 0
        dy = 0
        walk_cooldown = 8


        #get key
        key = pygame.key.get_pressed()
        if key[pygame.K_LEFT]:
            dx -= 1
            self.counter += 1
            self.image = self.images_left[self.index]
            self.tempx = self.rect.x
            self.tempy = self.rect.y
            self.rect = self.image.get_rect()
            self.rect.x = self.tempx
            self.rect.y = self.tempy


            self.direction = -1
        if key[pygame.K_RIGHT]:
            dx += 1
            self.counter += 1
            self.image = self.images_right[self.index]
            self.direction = 1
            self.tempx = self.rect.x
            self.tempy = self.rect.y
            self.rect = self.image.get_rect()
            self.rect.x = self.tempx
            self.rect.y = self.tempy

        if key[pygame.K_SPACE] and self.jumped == False:
            self.vel_y = -8
            self.jumped = True


        if key[pygame.K_SPACE] == False:
            self.jumped = False
        if (key[pygame.K_LEFT] == False and key[pygame.K_RIGHT] == False) or (key[pygame.K_LEFT] == True and key[pygame.K_RIGHT] == True):
            self.counter = 0
            self.index = 0
            if self.direction == 1:
                self.image = self.img_stand
            if self.direction == -1:
                self.image = self.img_standL
            self.tempx = self.rect.x
            self.tempy = self.rect.y
            self.rect = self.image.get_rect()
            self.rect.x = self.tempx
            self.rect.y = self.tempy



        if self.counter > walk_cooldown:
            self.counter = 0
            self.index += 1
            if self.direction == 1:
                if self.index >= len(self.images_right):
                    self.index = 0
                self.image = self.images_right[self.index]
            if self.direction == -1:
                if self.index >= len(self.images_left):
                    self.index = 0
                self.image = self.images_left[self.index]


        #jump + gravity
        self.vel_y += 0.3
        if self.vel_y > 10:
            self.vel_y = 10
        dy += self.vel_y

        #collision


        #move

        self.rect.x += dx
        self.rect.y += dy




        if self.rect.bottom > 540:
            self.rect.bottom = 540
            dy = 0






        #onto screen
        screen.blit(self.image,self.rect)
        pygame.draw.rect(screen,(255,255,255),self.rect,2)

I'm so confused with the top left rect thing. Maybe I should enlarge the rect of the standing animation? I also have no idea of how to resize the rect of the image after using get_rect.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
pupupyguy
  • 33
  • 4

1 Answers1

0

rect.x and rect.y specify the position of the upper left corner of the pygame.Rect object. A pygame.Rect object has a lot of virtual attributes that can be used to align the rectangle. I suggest using the center bottom position of the player instead of the top left position. e.g.:

if key[pygame.K_LEFT]:
    dx -= 1
    self.counter += 1
    self.image = self.images_left[self.index]
    self.tempx = self.rect.centerx
    self.tempy = self.rect.bottom
    self.rect = self.image.get_rect()
    self.rect.centerx = self.tempx
    self.rect.bottom = self.tempy

With the keyword attributes of pygame.Surface.get_rect this can be written even shorter:

if key[pygame.K_LEFT]:
    dx -= 1
    self.counter += 1
    self.image = self.images_left[self.index]
    self.rect = self.image.get_rect(midbottom = self.rect.midbottom)

Do the same for all other movements.

Note: self.image.get_rect(midbottom = self.rect.midbottom) means that the center bottom position is taken from the old rectangle and the new rectangle is moved so that its center bottom is located at that point.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174