Python Forum
How can I make all of the background move as opposed to just one platform?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How can I make all of the background move as opposed to just one platform?
#1
When I collide into a platform, the player is supposed to stop moving, and it did, but it also glitched slightly into the rectangle, so I found a work-around which is supposed to make the background move slightly over in order to compensate, but it only moves one platform, and if you were to repeatedly run into a platform it would cause it to shift indefinitely. I'm also currently just making it equal to the players left and right sides, but when I use Level(self).bgX += 10 inside the if statement in the player class that controls collisions it doesn't work, and I end up just glitching inside of it.

Here is my code:

import pygame

BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 255, 255)

SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600

class Player(pygame.sprite.Sprite):

    def __init__(self):


        super().__init__()


        width = 40
        height = 60
        self.image = pygame.Surface([width, height])
        self.image.fill(RED)


        self.rect = self.image.get_rect()


        self.xVel = 0
        self.yVel = 0


        self.level = None

    def update(self):
        self.calc_grav()


        Level(self).bgX += self.xVel



        block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
        for block in block_hit_list:
            if self.xVel < 0:
                self.friction()
                block.rect.left = 350 + 40
            elif self.xVel > 0:
                self.friction()
                block.rect.right = 350

        self.rect.y += self.yVel


        block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
        for block in block_hit_list:


            if self.yVel > 0:
                self.rect.bottom = block.rect.top
            elif self.yVel < 0:
                self.rect.top = block.rect.bottom


            self.yVel = 0

            if isinstance(block, MovingPlatform):
                Level(self).bgX += block.xVel

    def calc_grav(self):
        if self.yVel == 0:
            self.yVel = 1
        else:
            self.yVel +=0.5


        if self.rect.y >= SCREEN_HEIGHT - self.rect.height and self.yVel >= 0:
            self.yVel = 0
            self.rect.y = SCREEN_HEIGHT - self.rect.height

    def jump(self):
        self.rect.y += 2
        platform_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
        self.rect.y -= 2


        if len(platform_hit_list) > 0 or self.rect.bottom >= SCREEN_HEIGHT:
            self.yVel = -15

    def moveLeft(self):

        self.xVel = 6

    def moveRight(self):

        self.xVel = -6

    def friction(self):

        self.xVel = 0


class Platform(pygame.sprite.Sprite):

    def __init__(self, width, height):
        super().__init__()

        self.image = pygame.Surface([width, height])
        self.image.fill(GREEN)

        self.rect = self.image.get_rect()


class MovingPlatform(Platform):

    xVel = 0
    yVel = 0

    boundary_top = 0
    boundary_bottom = 0
    boundary_left = 0
    boundary_right = 0

    player = None

    level = None

    def update(self):
        self.rect.x += self.xVel

        hit = pygame.sprite.collide_rect(self, self.player)
        if hit:



            if self.xVel < 0:
                self.player.rect.right = self.rect.left
            else:

                self.player.rect.left = self.rect.right

        self.rect.y += self.yVel


        hit = pygame.sprite.collide_rect(self, self.player)
        if hit:

            if self.yVel < 0:
                self.player.rect.bottom = self.rect.top
            else:
                self.player.rect.top = self.rect.bottom

        if self.rect.bottom > self.boundary_bottom or self.rect.top < self.boundary_top:
            self.yVel *= -1

        cur_pos = self.rect.x - self.level.bgX
        if cur_pos < self.boundary_left or cur_pos > self.boundary_right:
            self.xVel *= -1


class Level(object):

    def __init__(self, player):
        self.platform_list = pygame.sprite.Group()
        self.enemy_list = pygame.sprite.Group()
        self.player = player

        self.background = None


        self.bgX = 0
        self.level_limit = -1000

    def update(self):
        self.platform_list.update()
        self.enemy_list.update()

    def draw(self, screen):

        screen.fill(BLUE)


        self.platform_list.draw(screen)
        self.enemy_list.draw(screen)

        for platform in self.platform_list:
            platform.rect.x += self.player.xVel

        for enemy in self.enemy_list:
            enemy.rect.x += self.player.xVel

class Level_01(Level):

    def __init__(self, player):


        Level.__init__(self, player)

        self.level_limit = -1500


        level = [[210, 70, 500, 500],
                 [210, 70, 800, 400],
                 [210, 70, 1000, 500],
                 [210, 70, 1120, 280],
                 ]


        for platform in level:
            block = Platform(platform[0], platform[1])
            block.rect.x = platform[2]
            block.rect.y = platform[3]
            block.player = self.player
            self.platform_list.add(block)


        block = MovingPlatform(70, 40)
        block.rect.x = 1350
        block.rect.y = 280
        block.boundary_left = 1350
        block.boundary_right = 1600
        block.xVel = 1
        block.player = self.player
        block.level = self
        self.platform_list.add(block)


class Level_02(Level):

    def __init__(self, player):

        Level.__init__(self, player)

        self.level_limit = -1000


        level = [[210, 70, 500, 550],
                 [210, 70, 800, 400],
                 [210, 70, 1000, 500],
                 [210, 70, 1120, 280],
                 ]


        for platform in level:
            block = Platform(platform[0], platform[1])
            block.rect.x = platform[2]
            block.rect.y = platform[3]
            block.player = self.player
            self.platform_list.add(block)

        block = MovingPlatform(70, 70)
        block.rect.x = 1500
        block.rect.y = 300
        block.boundary_top = 100
        block.boundary_bottom = 550
        block.yVel = -1
        block.player = self.player
        block.level = self
        self.platform_list.add(block)


def main():
    pygame.init()


    size = [SCREEN_WIDTH, SCREEN_HEIGHT]
    screen = pygame.display.set_mode(size)

    pygame.display.set_caption("Platformer with moving platforms")

    player = Player()

    level_list = []
    level_list.append(Level_01(player))

    current_level_no = 0
    current_level = level_list[current_level_no]

    active_sprite_list = pygame.sprite.Group()
    player.level = current_level

    player.rect.x = 350
    player.rect.y = SCREEN_HEIGHT - player.rect.height
    active_sprite_list.add(player)


    done = False


    clock = pygame.time.Clock()

    # -------- Main Program Loop -----------
    while not done:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    player.moveLeft()
                if event.key == pygame.K_RIGHT:
                    player.moveRight()
                if event.key == pygame.K_UP:
                    player.jump()

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT and player.xVel > 0:
                    player.friction()
                if event.key == pygame.K_RIGHT and player.xVel < 0:
                    player.friction()

        active_sprite_list.update()

        current_level.update()



        current_position = current_level.bgX
        if current_position < current_level.level_limit:
            if current_level_no < len(level_list)-1:
                player.rect.x = 350
                current_level_no += 1
                current_level = level_list[current_level_no]
                player.level = current_level
            else:

                done = True


        current_level.draw(screen)
        active_sprite_list.draw(screen)


        clock.tick(60)


        pygame.display.flip()

    pygame.quit()

if __name__ == "__main__":
    main()
Is there a way to make the entire background shift as opposed to just the platform? It would also help if someone could tell me why you can't just hold the right arrow key and jump simultaneously after you collide with a platform.
Reply


Messages In This Thread
How can I make all of the background move as opposed to just one platform? - by HelpMEE - Dec-28-2019, 02:54 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyGame] Players not falling from the platform, and some other errors. urmom33 1 1,733 Jan-23-2023, 10:28 PM
Last Post: deanhystad
  How to make an image move in relation to another in PYGAME CompleteNewb 1 2,387 Nov-10-2021, 03:38 PM
Last Post: metulburr
  [PyGame] how to make objects move at a precise amount of time? Zhaleh 2 2,718 Aug-02-2020, 02:52 PM
Last Post: Zhaleh
  How to make a walljump + move between rooms ? dMn420 1 2,622 Jul-17-2019, 08:49 PM
Last Post: SheeppOSU

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020