0

I am making a small game in pygame and I have been using the script from the first answer here, to make a camera that follows my character around the screen:

    def __init__(self, target, world_size):
        super().__init__()
        self.target = target
        self.cam = pygame.Vector2(0, 0)
        self.world_size = world_size
        if self.target:
            self.add(target)

    def update(self, *args):
        super().update(*args)
        if self.target:
            x = -self.target.rect.center[0] + SCREEN_SIZE.width/2
            y = -self.target.rect.center[1] + SCREEN_SIZE.height/2
            self.cam += (pygame.Vector2((x, y)) - self.cam) * 0.05
            self.cam.x = max(-(self.world_size.width-SCREEN_SIZE.width), min(0, self.cam.x))
            self.cam.y = max(-(self.world_size.height-SCREEN_SIZE.height), min(0, self.cam.y))

    def draw(self, surface):
        spritedict = self.spritedict
        surface_blit = surface.blit
        dirty = self.lostsprites
        self.lostsprites = []
        dirty_append = dirty.append
        init_rect = self._init_rect
        for spr in self.sprites():
            rec = spritedict[spr]
            newrect = surface_blit(spr.image, spr.rect.move(self.cam))
            if rec is init_rect:
                dirty_append(newrect)
            else:
                if newrect.colliderect(rec):
                    dirty_append(newrect.union(rec))
                else:
                    dirty_append(newrect)
                    dirty_append(rec)
            spritedict[spr] = newrect
        return dirty            

How would one go about adding a background image, that scrolls at the same time/together with the level, that only moves when the player does. I tried do figure out what the code in the draw method of the Camera means so I could alter it, but was very confused as I am quite new to pygame and also not all too proficient yet in python. The level is built with this code(also from the other question):

def main():
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE.size)
    pygame.display.set_caption("Use arrows to move!")
    timer = pygame.time.Clock()

    level = [
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
        "P                                          P",
        "P                 PPPPPP                   P",
        "P                                          P",
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",]


    platforms = pygame.sprite.Group()
    player = Player(platforms, (TILE_SIZE, TILE_SIZE))
    level_width  = len(level[0])*TILE_SIZE
    level_height = len(level)*TILE_SIZE
    entities = CameraAwareLayeredUpdates(player, pygame.Rect(0, 0, level_width, level_height))

I've also tried making the background scroll separately, depending on whether the player is moving or not, but that caused a misalignment of the actual platforms on the stage and the background. This is very problematic because my 'story' relies on the background and textboxes that appear when stepping on certain bricks, which are next to characters drawn on the background.

I hope I have provided everything necessary for an answer and have asked an understandable question. Otherwise, please let me know what other information is needed, I thank anyone who tries in advance.

1 Answers1

1

Not sure if this is what you actually want, but here we go:

Create a Sprite for your background image

class StaticImage(pygame.sprite.Sprite):
    def __init__(self, image, *groups):
        super().__init__(*groups)
        self.image = image
        self.rect = self.image.get_rect()
        self._layer = -1 # always draw first.

and add an instance to the Group

def main():
    ...
    entities = CameraAwareLayeredUpdates(player, pygame.Rect(0, 0, level_width, level_height))    
    backimage = pygame.image.load('*PATH*').convert()
    StaticImage(backimage, entities)

Since the position of this Sprite is always 0, 0, it will move with the level when the camera moves.

sloth
  • 99,095
  • 21
  • 171
  • 219
  • Thanks a lot, but now it blits the background over the player and you can't see the player anymore. – Green Chili Sep 24 '19 at 15:47
  • The `CameraAwareLayeredUpdates` class support layers, so an easy fix is to give your background class a `_layer` attribute to control the order of drawing. Sprites with a lower `_layer` will be drawn first. – sloth Sep 25 '19 at 06:39
  • Would I then still have to change something in the ```CameraAwareLayeredUpdates``` group? Sorry if that's a dumb question, as I said, I'm much of a noob – Green Chili Sep 25 '19 at 19:00
  • No. Just give your Sprites a `_layer` attribute to control the order of drawing – sloth Sep 26 '19 at 06:53