1

I'm making a platform game and I got player standing and walking animations. I used tempbottom and tempcenterx to keep the player's position so he doesn't flash backwards or forwards when start walking. But I want to keep the standing rect while walking for convenience. Is there any way to do that? Or is there any way to leave rect unchanged while changing the relative position when changing image? Here's my sprites, they got different canvas size when exported: Standing enter image description here Walking enter image description here

Here's my code up to walking part:

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.width = self.image.get_width()
        self.height = self.image.get_height()
        self.rect = self.image.get_rect()
        print(self.rect)

        self.rect.x = x
        self.rect.y = y
        self.width = self.image.get_width()
        self.height = self.image.get_height()

        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.image = self.images_left[self.index]
            self.counter += 1
            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

            self.direction = -1
        if key[pygame.K_RIGHT]:
            dx += 1
            self.image = self.images_right[self.index]
            self.counter += 1
            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

            self.direction = +1

I just don't know how to modify the rects. I exported the standing animation with the image tightly cornered by borders and I did the same for walking animation. I managed to reposition but that would change the rect, I really want to keep the standing rect.

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

1 Answers1

0

I suggest to create 2 rectangles. 1 that has the borders of the player and 1 that has the original rectangle and is used for collision detection. Initially, both rectangles are the same size and position. However, if the size and position of the bounding rectangle (self.rect) is changed, the size of the collision detection rectangle (self.hit_box) remains the same and only the position is changed:

class Player():
    def __init__(self,x,y):
        # [...]

        # initially, both rectangles are the same
        self.rect = self.image.get_rect(topleft = (x, y))
        self.hit_box = self.rect.copy()


    def update(self):
        dx = 0
        dy = 0
        walk_cooldown = 8

        key = pygame.key.get_pressed()
        if key[pygame.K_LEFT]:
            dx -= 1
            self.image = self.images_left[self.index]
            self.counter += 1
            # change size of self.rect
            self.rect = self.image.get_rect(midbottom = self.rect.midbottom)
            self.direction = -1

        if key[pygame.K_RIGHT]:
            dx += 1
            self.image = self.images_right[self.index]
            self.counter += 1
            # change size of self.rect
            self.rect = self.image.get_rect(midbottom = self.rect.midbottom)
            self.direction = +1

        # use self.hit_box for the collision detection
        # [...]

        # change position of self.rect
        self.rect.centerx += dx
        self.rect.bottom += dy
        if self.rect.bottom > 540:
            self.rect.bottom = 540
            dy = 0

        # update position of self.hit_box
        self.hit_box.midbottom = self.rect.midbottom
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • You really saved my day. Can you check if my understanding is correct: In __init__ part it just states that hit box would be the same with rectangle and it never changes, in collision it uses hit box to check if collision happens and move rectangle if collision happens. After collision check the player finally moves and hitbox is repositioned to rectangle. If hit box and rectangle are always the same on y-axis then I can use hitbox in collision part for y-axis. – pupupyguy Dec 31 '22 at 09:55
  • @pupupyguy Yes, that is correct. – Rabbid76 Dec 31 '22 at 10:16