Air dash pushes player on to next block top when hitting a wall in x direction and continues in x direction. Need player to stop moving if hit wall

Viewed 45

My dash method is as below (player2 may as well refer to self as I have 2 instances of this class where only player2 dashes).

def dash(self):
    if self.dashing == True:
        self.yvel = self.yvel_dash
        self.dash_timer += 1
        if player2.direction == 1:
            player2.rect[0] += self.speed * 3
            player2.rect[1] += self.yvel_dash
        if player2.direction == -1:
            player2.rect[0] -= self.speed * 3
            player2.rect[1] += self.yvel_dash
        if self.dash_timer > 10:
            self.dash_timer = 0
            self.dashed = True
            if self.dashed == True:
                self.dashing = False
    if self.airborne == False:
        self.dashed = False

Then after adding the tiles and world, everything works perfectly apart from the issue in title. Collision code as below in separate move method.

for tile in world.obstacle_list:
        if tile[1].colliderect(self.rect[0]+loc[0],self.rect[1],self.width, self.height):
            loc[0] = 0
        if tile[1].colliderect(self.rect[0],self.rect[1]+loc[1],self.width, self.height):
            if self.yvel < 0:
                self.yvel = 0
                loc[1] = tile[1].bottom - self.rect.top
            elif self.yvel >= 0:
                self.yvel = 0
                self.airborne = False
                self.falling = False
                self.jump_counter = 0
                loc[1] = tile[1].top - self.rect.bottom
                self.dashing = False
                self.dashed = True

    self.rect[0] += loc[0]
    self.rect[1] += loc[1]

I have tried adding more collision 'ifs' in dash function and 'if dashing' but nothing is affecting this game breaking issue and the same error occurs. Taking self.yvel_dash out of the equation doesn't alter it apart from allows the player to fall as normal when dashing as opposed to dashing straight.

1 Answers

You must separate the collision tests for the X and Y axes. First do the collision test along the X-axis and then the collision test along the Y-axis. It is important that you do this in 2 separate loops.
If the player hits a block from the side, place the player next to the block. Finally, do the collision test along the Y-axis:

for tile in world.obstacle_list:
    if tile[1].colliderect(self.rect[0]+loc[0], self.rect[1], self.width, self.height):
        if loc[0] > 0:
            self.rect.left = tile[1].left - self.width
        if loc[0] < 0
            self.rect.left = tile[1].right
        loc[0] = 0

self.rect[0] += loc[0]

for tile in world.obstacle_list:    
    if tile[1].colliderect(self.rect[0],self.rect[1]+loc[1],self.width, self.height):
        if self.yvel < 0:
            self.yvel = 0
            loc[1] = 0
            self.rect.top = tile[1].bottom

        elif self.yvel >= 0:
            self.yvel = 0
            loc[1] = 0
            self.rect.bottom = tile[1].top

            self.airborne = False
            self.falling = False
            self.jump_counter = 0
            self.dashing = False
            self.dashed = True

self.rect[1] += loc[1]
Related