Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9174321
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 17, 20262026-06-17T16:44:00+00:00 2026-06-17T16:44:00+00:00

Ok so I included the code for my project below, I’m just doing some

  • 0

Ok so I included the code for my project below, I’m just doing some experimenting with pygame on making a platformer. I’m trying to figure out how to do some very simple scrolling that follows the player, so the player is the center of the camera and it bounces/follows him. Can anyone help me?

import pygame
from pygame import *

WIN_WIDTH = 800
WIN_HEIGHT = 640
HALF_WIDTH = int(WIN_WIDTH / 2)
HALF_HEIGHT = int(WIN_HEIGHT / 2)

DISPLAY = (WIN_WIDTH, WIN_HEIGHT)
DEPTH = 32
FLAGS = 0
CAMERA_SLACK = 30

def main():
    global cameraX, cameraY
    pygame.init()
    screen = pygame.display.set_mode(DISPLAY, FLAGS, DEPTH)
    pygame.display.set_caption("Use arrows to move!")
    timer = pygame.time.Clock()

    up = down = left = right = running = False
    bg = Surface((32,32))
    bg.convert()
    bg.fill(Color("#000000"))
    entities = pygame.sprite.Group()
    player = Player(32, 32)
    platforms = []

    x = y = 0
    level = [
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
        "P                                P",
        "P                                P",
        "P                                P",
        "P                                P",
        "P                                P",
        "P                                P",
        "P                                P",
        "P       PPPPPPPPPPP              P",
        "P                                P",
        "P                                P",
        "P                                P",
        "P                                P",
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",]
    # build the level
    for row in level:
        for col in row:
            if col == "P":
                p = Platform(x, y)
                platforms.append(p)
                entities.add(p)
            if col == "E":
                e = ExitBlock(x, y)
                platforms.append(e)
                entities.add(e)
            x += 32
        y += 32
        x = 0

    entities.add(player)

    while 1:
        timer.tick(60)

        for e in pygame.event.get():
            if e.type == QUIT: raise SystemExit, "QUIT"
            if e.type == KEYDOWN and e.key == K_ESCAPE:
                raise SystemExit, "ESCAPE"
            if e.type == KEYDOWN and e.key == K_UP:
                up = True
            if e.type == KEYDOWN and e.key == K_DOWN:
                down = True
            if e.type == KEYDOWN and e.key == K_LEFT:
                left = True
            if e.type == KEYDOWN and e.key == K_RIGHT:
                right = True
            if e.type == KEYDOWN and e.key == K_SPACE:
                running = True

            if e.type == KEYUP and e.key == K_UP:
                up = False
            if e.type == KEYUP and e.key == K_DOWN:
                down = False
            if e.type == KEYUP and e.key == K_RIGHT:
                right = False
            if e.type == KEYUP and e.key == K_LEFT:
                left = False
            if e.type == KEYUP and e.key == K_RIGHT:
                right = False

        # draw background
        for y in range(32):
            for x in range(32):
                screen.blit(bg, (x * 32, y * 32))

        # update player, draw everything else
        player.update(up, down, left, right, running, platforms)
        entities.draw(screen)

        pygame.display.update()

class Entity(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

class Player(Entity):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.xvel = 0
        self.yvel = 0
        self.onGround = False
        self.image = Surface((32,32))
        self.image.fill(Color("#0000FF"))
        self.image.convert()
        self.rect = Rect(x, y, 32, 32)

    def update(self, up, down, left, right, running, platforms):
        if up:
            # only jump if on the ground
            if self.onGround: self.yvel -= 10
        if down:
            pass
        if running:
            self.xvel = 12
        if left:
            self.xvel = -8
        if right:
            self.xvel = 8
        if not self.onGround:
            # only accelerate with gravity if in the air
            self.yvel += 0.3
            # max falling speed
            if self.yvel > 100: self.yvel = 100
        if not(left or right):
            self.xvel = 0
        # increment in x direction
        self.rect.left += self.xvel
        # do x-axis collisions
        self.collide(self.xvel, 0, platforms)
        # increment in y direction
        self.rect.top += self.yvel
        # assuming we're in the air
        self.onGround = False;
        # do y-axis collisions
        self.collide(0, self.yvel, platforms)

    def collide(self, xvel, yvel, platforms):
        for p in platforms:
            if pygame.sprite.collide_rect(self, p):
                if isinstance(p, ExitBlock):
                    pygame.event.post(pygame.event.Event(QUIT))
                if xvel > 0:
                    self.rect.right = p.rect.left
                    print "collide right"
                if xvel < 0:
                    self.rect.left = p.rect.right
                    print "collide left"
                if yvel > 0:
                    self.rect.bottom = p.rect.top
                    self.onGround = True
                    self.yvel = 0
                if yvel < 0:
                    self.rect.top = p.rect.bottom


class Platform(Entity):
    def __init__(self, x, y):
        Entity.__init__(self)
        self.image = Surface((32, 32))
        self.image.convert()
        self.image.fill(Color("#DDDDDD"))
        self.rect = Rect(x, y, 32, 32)

    def update(self):
        pass

class ExitBlock(Platform):
    def __init__(self, x, y):
        Platform.__init__(self, x, y)
        self.image.fill(Color("#0033FF"))

if __name__ == "__main__":
    main()
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-17T16:44:01+00:00Added an answer on June 17, 2026 at 4:44 pm

    You need to apply an offset to the position of your entities when drawing them. Let’s call that offset a camera, since this is the effect we want to achieve with this.

    First of all, we can’t use the draw function of the sprite group, since the sprites don’t need to know that their position (rect) is not the position they are going to be drawn on the screen (At the end, we’ll subclass the Group class and reimplement the it’s draw to be aware of the camera, but let’s start slow).


    Let’s start by creating a Camera class to hold the state of the offset we want to apply to the position of our entities:

    class Camera(object):
        def __init__(self, camera_func, width, height):
            self.camera_func = camera_func
            self.state = Rect(0, 0, width, height)
            
        def apply(self, target):
            return target.rect.move(self.state.topleft)
            
        def update(self, target):
            self.state = self.camera_func(self.state, target.rect)
    

    some things to note here:

    We need to store the position of the camera, and the width and height of the level in pixels (since we want to stop scrolling at the edges of the level). I used a Rect to store all these informations, but you could easily just use some fields.

    Using Rect comes in handy in the apply function. This is where we re-calculate the position of an entity on the screen to apply the scrolling.

    Once per iteration of the main loop, we need to update the position of the camera, hence there’s the update function. It just alters the state by calling the camera_func function, which will do all the hard work for us. We implement it later.

    Let’s create an instace of the camera:

    for row in level:
        ...
    
    total_level_width  = len(level[0])*32 # calculate size of level in pixels
    total_level_height = len(level)*32    # maybe make 32 an constant
    camera = Camera(*to_be_implemented*, total_level_width, total_level_height)
    
    entities.add(player)
    ... 
    

    and alter our main loop:

    # draw background
    for y in range(32):
        ...
    
    camera.update(player) # camera follows player. Note that we could also follow any other sprite
    
    # update player, draw everything else
    player.update(up, down, left, right, running, platforms)
    for e in entities:
        # apply the offset to each entity.
        # call this for everything that should scroll,
        # which is basically everything other than GUI/HUD/UI
        screen.blit(e.image, camera.apply(e)) 
    
    pygame.display.update()
    

    Our camera class is already very flexible and yet dead simple. It can use different kinds of scrolling (by providing different camera_func functions), and it can follow any arbitary sprite, not just the player. You even can change this at runtime.

    Now for the implementation of camera_func. A simple approach is to just center the player (or whichever entity we want to follow) at the screen, and the implementation is straight forward:

    def simple_camera(camera, target_rect):
        l, t, _, _ = target_rect # l = left,  t = top
        _, _, w, h = camera      # w = width, h = height
        return Rect(-l+HALF_WIDTH, -t+HALF_HEIGHT, w, h)
    

    We just take the position of our target, and add the half total screen size. You can try it by creating your camera like this:

    camera = Camera(simple_camera, total_level_width, total_level_height)
    

    So far, so good. But maybe we don’t want to see the black background outside the level? How about:

    def complex_camera(camera, target_rect):
        # we want to center target_rect
        x = -target_rect.center[0] + WIN_WIDTH/2 
        y = -target_rect.center[1] + WIN_HEIGHT/2
        # move the camera. Let's use some vectors so we can easily substract/multiply
        camera.topleft += (pygame.Vector2((x, y)) - pygame.Vector2(camera.topleft)) * 0.06 # add some smoothness coolnes
        # set max/min x/y so we don't see stuff outside the world
        camera.x = max(-(camera.width-WIN_WIDTH), min(0, camera.x))
        camera.y = max(-(camera.height-WIN_HEIGHT), min(0, camera.y))
        
        return camera
    

    Here we simply use the min/max functions to ensure we don’t scroll outside out level.

    Try it by creating your camera like this:

    camera = Camera(complex_camera, total_level_width, total_level_height)
    

    There’s a little animation of our final scrolling in action:

    enter image description here

    Here’s the complete code again. Note I changed some things:

    • the level is bigger and to have some more platforms
    • use python 3
    • use a sprite group to handle the camera
    • refactored some duplicate code
    • since Vector2/3 is now stable, use them for easier math
    • get rid of that ugly event handling code and use pygame.key.get_pressed instead

     #! /usr/bin/python
    
    import pygame
    from pygame import *
    
    SCREEN_SIZE = pygame.Rect((0, 0, 800, 640))
    TILE_SIZE = 32 
    GRAVITY = pygame.Vector2((0, 0.3))
    
    class CameraAwareLayeredUpdates(pygame.sprite.LayeredUpdates):
        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            
                
    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                                          P",
            "P                                          P",
            "P                    PPPPPPPPPPP           P",
            "P                                          P",
            "P                                          P",
            "P                                          P",
            "P    PPPPPPPP                              P",
            "P                                          P",
            "P                          PPPPPPP         P",
            "P                 PPPPPP                   P",
            "P                                          P",
            "P         PPPPPPP                          P",
            "P                                          P",
            "P                     PPPPPP               P",
            "P                                          P",
            "P   PPPPPPPPPPP                            P",
            "P                                          P",
            "P                 PPPPPPPPPPP              P",
            "P                                          P",
            "P                                          P",
            "P                                          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))
        
        # build the level
        x = y = 0
        for row in level:
            for col in row:
                if col == "P":
                    Platform((x, y), platforms, entities)
                if col == "E":
                    ExitBlock((x, y), platforms, entities)
                x += TILE_SIZE
            y += TILE_SIZE
            x = 0
        
        while 1:
    
            for e in pygame.event.get():
                if e.type == QUIT: 
                    return
                if e.type == KEYDOWN and e.key == K_ESCAPE:
                    return
    
            entities.update()
    
            screen.fill((0, 0, 0))
            entities.draw(screen)
            pygame.display.update()
            timer.tick(60)
    
    class Entity(pygame.sprite.Sprite):
        def __init__(self, color, pos, *groups):
            super().__init__(*groups)
            self.image = Surface((TILE_SIZE, TILE_SIZE))
            self.image.fill(color)
            self.rect = self.image.get_rect(topleft=pos)
    
    class Player(Entity):
        def __init__(self, platforms, pos, *groups):
            super().__init__(Color("#0000FF"), pos)
            self.vel = pygame.Vector2((0, 0))
            self.onGround = False
            self.platforms = platforms
            self.speed = 8
            self.jump_strength = 10
            
        def update(self):
            pressed = pygame.key.get_pressed()
            up = pressed[K_UP]
            left = pressed[K_LEFT]
            right = pressed[K_RIGHT]
            running = pressed[K_SPACE]
            
            if up:
                # only jump if on the ground
                if self.onGround: self.vel.y = -self.jump_strength
            if left:
                self.vel.x = -self.speed
            if right:
                self.vel.x = self.speed
            if running:
                self.vel.x *= 1.5
            if not self.onGround:
                # only accelerate with gravity if in the air
                self.vel += GRAVITY
                # max falling speed
                if self.vel.y > 100: self.vel.y = 100
            print(self.vel.y)
            if not(left or right):
                self.vel.x = 0
            # increment in x direction
            self.rect.left += self.vel.x
            # do x-axis collisions
            self.collide(self.vel.x, 0, self.platforms)
            # increment in y direction
            self.rect.top += self.vel.y
            # assuming we're in the air
            self.onGround = False;
            # do y-axis collisions
            self.collide(0, self.vel.y, self.platforms)
    
        def collide(self, xvel, yvel, platforms):
            for p in platforms:
                if pygame.sprite.collide_rect(self, p):
                    if isinstance(p, ExitBlock):
                        pygame.event.post(pygame.event.Event(QUIT))
                    if xvel > 0:
                        self.rect.right = p.rect.left
                    if xvel < 0:
                        self.rect.left = p.rect.right
                    if yvel > 0:
                        self.rect.bottom = p.rect.top
                        self.onGround = True
                        self.vel.y = 0
                    if yvel < 0:
                        self.rect.top = p.rect.bottom
    
    class Platform(Entity):
        def __init__(self, pos, *groups):
            super().__init__(Color("#DDDDDD"), pos, *groups)
    
    class ExitBlock(Entity):
        def __init__(self, pos, *groups):
            super().__init__(Color("#0033FF"), pos, *groups)
    
    if __name__ == "__main__":
        main()
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have two related qestions on the code included below 1) I am trying
In my Project I included a splash-screen. For that i wrote below code in
I'm trying include this barcode source code Stefanhafeneger - Barcode github.com to my project
I am trying to set up Cobertura code coverage on a project which includes
I am trying to count characters in comments included in C code using Python
While running the code I've included below I receive the error EntityCommandExecutionException was unhandled
We are running some code on a project that uses OpenMP and I've run
As part of my Final Year Project, I need to convert some FORTRAN code
I am trying to open a file (included in my project as Content and
I have a code like this below in /root_project/main.cpp : #include theoraplayer/TheoraVideoClip.h unsigned int

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.