0

Q:Pygame How Do I Make my level Scroll Side-To-Side As The Player Move?

I am trying to figure out how can I make a side-scrolling view in pygame if i am moving right or left or Up want to portion of the level shown on the screen to shift follow the character Heres A Animation of my pygame: https://gyazo.com/636fef8a16198b24bc0496f566c57d9c

And my Script is below:

pygame.init()


window = pygame.display.set_mode((500,500))
pygame.display.set_caption("GET LOAD OF THIES")


# Character class
class players(object):
    def __init__(self,x,y,height,width):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.isJump = False
        self.JumpCount = 10
        self.fall = 0
        self.speed = 5

# enemy class 1
class enemys(object):
    def __init__(self,cordx,cordy,cordheight,cordwidth):
        self.cordx = cordx
        self.cordy = cordy
        self.cordheight = cordheight
        self.cordwidth = cordwidth

# enemy class 2
class enemyss(object):
    def __init__(self,xs,ys,sheights,swidths):
        self.xs = xs
        self.ys = ys
        self.sheights = sheights
        self.swidths = swidths

class lava(object):
    def __init__(self,lavax,lavay,lavawidth,lavaheight):

        self.lavax = lavax
        self.lavay = lavay
        self.lavawidth = lavawidth
        self.lavaheight = lavaheight



# enemy class 3
class enemysss(object):
    def __init__(self,velx,vely,velheight,velwidth):
        self.velx = velx
        self.vely = vely
        self.velwidth = velwidth
        self.velheight = velheight


# Colors
NiceBlue = (0,214, 82)
NiceGreen = (214,0,82)

# FPS
FPS = 60
clock = pygame.time.Clock()

# Defininition for the class player/enemys
playerman = players(50,390,20,20)
enemy1 = enemys(150,390,100,10)
enemy2 = enemyss(320,320,100,10)
enemy3 = enemysss(120,250,100,10)
enemy4 = lava(0,459,500,40)


# Main loop
runninggame = True
while runninggame:
    # Frames per second
    clock.tick(FPS)
    # Exit Event
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            runninggame = False
        #Draw The enemys and Main Characte
    window.fill((0,0,0))
    player = pygame.draw.rect(window, (NiceGreen), (playerman.x,playerman.y,playerman.height,playerman.width))
    enemy = pygame.draw.rect(window, (NiceBlue), (enemy1.cordx,enemy1.cordy,enemy1.cordheight,enemy1.cordwidth))
    soenemy = pygame.draw.rect(window, (NiceBlue), (enemy2.xs,enemy2.ys,enemy2.sheights,enemy2.swidths))
    dudeenemy = pygame.draw.rect(window, (NiceBlue), (enemy3.velx,enemy3.vely,enemy3.velheight,enemy3.velwidth))
    thisanotherenemy = pygame.draw.rect(window, (230,4,231), (enemy4.lavax,enemy4.lavay,enemy4.lavawidth,enemy4.lavaheight))


    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        playerman.x -= playerman.speed
    if keys[pygame.K_RIGHT]:
        playerman.x += playerman.speed
    if not playerman.isJump:

        playerman.y += playerman.fall
        playerman.fall += 1
# ----------------------------------------------------- # enem1 collisio
# both of my 2 enemy squares collisions push me back when ever I Jump on the top of them on there sides but when I jump on the middle of of both of them it seems to work if I just want it so when I jump on both of my squares I just don't get pushed back 
        player.topleft = (playerman.x, playerman.y)
        collide = False
        if player.colliderect(enemy):
            collide = True
            playerman.y = enemy.top - player.height
            if player.right > enemy.left and  player.left < enemy.left - player.width:
                playerman.x = enemy.left - player.width
            if player.left < enemy.right and  player.right > enemy.right + player.width:
                playerman.x = enemy.right

        if player.colliderect(soenemy):
            collide = True
            playerman.y = soenemy.top - player.height
            if playerman.y > soenemy.left and player.left < enemy.left - player.width:
                playerman.x = soenemy.left  - player.width
            if player.left < soenemy.left and player.right > soenemy.right + player.width:
                playerman.x = soenemy.right
        if player.colliderect(dudeenemy):
            collide = True
            playerman.y = dudeenemy.top - player.height
            if playerman.y > dudeenemy.left and player.left < dudeenemy.left - player.width:
                playerman.x = dudeenemy.left  - player.width
            if player.left < dudeenemy.left and player.right > dudeenemy.right + player.width:
                playerman.x = dudeenemy.right
        if player.colliderect(thisanotherenemy):
            collide = True
            playerman.y = thisanotherenemy.top - player.height
            if playerman.y > thisanotherenemy.left and player.left < thisanotherenemy.left - player.width:
                playerman.x = thisanotherenemy.left  - player.width
            if player.left < thisanotherenemy.left and player.right > thisanotherenemy.right + player.width:
                playerman.x = thisanotherenemy.right





        if player.bottom >= 500:
            collide = True
            playerman.isJump = False
            playerman.JumpCount = 10
            playerman.y = 500 - player.height

        if collide:
            if keys[pygame.K_SPACE]:
                playerman.isJump = True
            playerman.fall = 0
    else:
        if playerman.JumpCount > 0:
            playerman.y -= (playerman.JumpCount * abs(playerman.JumpCount)) * 0.3
            playerman.JumpCount -= 1
        else:
            playerman.JumpCount = 10
            playerman.isJump = False



        # update winodw event
    pygame.display.update()
# quit event
pygame.quit()
Community
  • 1
  • 1
Habib Ismail
  • 69
  • 5
  • 16

1 Answers1

2

Lets start by by making the code as simple as possible so its easier to add scrolling

First, you have a separate class for each object, that is unnecessary, the way classes work is you can create multiple instances off one class, so instead of having a class for every enemy, you can have one.

# enemy class 1
class enemys(object):
    def __init__(self,x,y,height,width):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
# Defininition for the class player/enemys
playerman = players(50,390,20,20)
enemy1 = enemys(150,390,100,10)
enemy2 = enemys(320,320,100,10)
enemy3 = enemys(120,250,100,10)
enemy4 = enemys(0,459,500,40)

you also have another variable for each enemies rect. lets move it to the class. In fact, lets move all the drawing to the class

# enemy class 1
class enemys(object):
    def __init__(self,x,y,height,width):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.rect = pygame.Rect(x,y,width,height)

    def draw(self):
        pygame.draw.rect(window, (NiceBlue), self.rect) 
playerman.draw()
enemy1.draw()
enemy2.draw()
enemy3.draw()
enemy4.draw()

i did notice that lava has a different colour, so lets make that an argument for creating the enemy

# enemy class 1
class enemys: #you dont need an (object) only in python2
    def __init__(self,x,y,height,width,color):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.rect = pygame.Rect(x,y,width,height)
        self.color = color

    def draw(self):
        pygame.draw.rect(window, self.color, self.rect)
enemy1 = enemys(150,390,100,10, NiceBlue)
enemy2 = enemys(320,320,100,10, NiceBlue)
enemy3 = enemys(120,250,100,10, NiceBlue)
enemy4 = enemys(0,459,500,40, (230,4,231))

Now to clean up the collision, it works, but you dont need all of those if statements, you can use a loop. lets also fix up everywhere there was a playe and change it to playerman.rect, and the same with enemy

enemies = [enemy1,enemy2,enemy3,enemy4]
collide = False
    for enemy in enemies:
        if playerman.rect.colliderect(enemy.rect):
            collide = True
            playerman.y = enemy.rect.top - playerman.height + 1 #had to add 1 to look smooth
            if playerman.rect.right > enemy.rect.left and  playerman.rect.left < enemy.rect.left - playerman.width:
                playerman.x = enemy.rect.left - player.width
            if playerman.rect.left < enemy.rect.right and  playerman.rect.right > enemy.rect.right + playerman.width:
                playerman.x = enemy.rect.right
            break  #break so dont check every object

    if playerman.rect.bottom >= 500:
        collide = True
        playerman.isJump = False
        playerman.JumpCount = 10
        playerman.y = 500 - playerman.height

Now Lets make the scroll, to scroll, you need to move everything on the screen once the player moves near the edge of the screen

if keys[pygame.K_LEFT]:
    playerman.x -= playerman.speed
    if playerman.x < 100:                  #if the player is close to the edge
        playerman.x += playerman.speed     #move everything the other direction
        for enemy in enemies:
            enemy.x += playerman.speed
if keys[pygame.K_RIGHT]:
    playerman.x += playerman.speed
    if playerman.x > 400:
        playerman.x -= playerman.speed
        for enemy in enemies:
            enemy.x -= playerman.speed     

and the same for the jump

if playerman.y < 250:
    playerman.y += 1
    for enemy in enemies:
        enemy.y += playerman.speed  

Now i chose numbers to be close to the edge, you should replace the 400, 100 and 250 to variables so you can change them.

Here is the full code:

import pygame

pygame.init()


window = pygame.display.set_mode((500,500))
pygame.display.set_caption("GET LOAD OF THIES")


# Character class
class players(object):
    def __init__(self,x,y,height,width):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.isJump = False
        self.JumpCount = 10
        self.fall = 0
        self.speed = 5
        self.rect = pygame.Rect(x,y,width,height)

    #draw the player
    def draw(self):
        self.rect.topleft = (self.x, self.y)
        pygame.draw.rect(window, (NiceGreen), self.rect)

# enemy class 1
class enemys(object):
    def __init__(self,x,y,width,height,color):
        self.x = x
        self.y = y
        self.height = height
        self.width = width
        self.rect = pygame.Rect(x,y,width,height)
        self.color = color

    #draw the enemy
    def draw(self):
        #update the rect with new positions
        self.rect.topleft = (self.x, self.y)
        pygame.draw.rect(window, self.color, self.rect)



# Colors
NiceBlue = (0,214, 82)
NiceGreen = (214,0,82)

# FPS
FPS = 60
clock = pygame.time.Clock()

# Defininition for the class player/enemys
playerman = players(50,390,20,20)
enemy1 = enemys(150,390,100,10, NiceBlue)
enemy2 = enemys(320,320,100,10, NiceBlue)
enemy3 = enemys(120,250,100,10, NiceBlue)
enemy4 = enemys(0,459,500,40, (230,4,231))


enemies = [enemy1,enemy2,enemy3,enemy4]

# Main loop
runninggame = True
while runninggame:
    # Frames per second
    clock.tick(FPS)
    # Exit Event
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            runninggame = False
        #Draw The enemys and Main Characte
    window.fill((0,0,0))
    playerman.draw()
    enemy1.draw()
    enemy2.draw()
    enemy3.draw()
    enemy4.draw()

    #check for scroll up
    if playerman.y < 250:
        playerman.y += 1
        for enemy in enemies:
            enemy.y += playerman.speed   
#-----------------------------------------------------put here---------------
    #check for scroll down
    if playerman.y > 450: #somewhere close to the bottom of the screen
        playerman.y -= playerman.fall  #reverse direction
        for enemy in enemies:
            enemy.y -= playerman.fall
#---------------------------------------------------------------------------

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        playerman.x -= playerman.speed
        #check to scroll left
        if playerman.x < 100:
            playerman.x += playerman.speed #move player back so doesnt go off screen
            for enemy in enemies:          #move everything in other direction
                enemy.x += playerman.speed
    if keys[pygame.K_RIGHT]:
        playerman.x += playerman.speed
        #check to scroll right
        if playerman.x > 400:             
            playerman.x -= playerman.speed
            for enemy in enemies:
                enemy.x -= playerman.speed        
    if not playerman.isJump:

        playerman.y += playerman.fall
        playerman.fall += 1
# ----------------------------------------------------- # enem1 collisio
# both of my 2 enemy squares collisions push me back when ever I Jump on the top of them on there sides but when I jump on the middle of of both of them it seems to work if I just want it so when I jump on both of my squares I just don't get pushed back 
        collide = False
        for enemy in enemies:
            if playerman.rect.colliderect(enemy.rect):
                collide = True
                playerman.y = enemy.rect.top - playerman.height + 1 #had to add 1 to look smooth
                if playerman.rect.right > enemy.rect.left and  playerman.rect.left < enemy.rect.left - playerman.width:
                    playerman.x = enemy.rect.left - player.width
                if playerman.rect.left < enemy.rect.right and  playerman.rect.right > enemy.rect.right + playerman.width:
                    playerman.x = enemy.rect.right
                break

        if playerman.rect.bottom >= 500:
            collide = True
            playerman.isJump = False
            playerman.JumpCount = 10
            playerman.y = 500 - playerman.height

        if collide:
            if keys[pygame.K_SPACE]:
                playerman.isJump = True
            playerman.fall = 0
    else:
        if playerman.JumpCount > 0:
            playerman.y -= (playerman.JumpCount * abs(playerman.JumpCount)) * 0.3
            playerman.JumpCount -= 1
        else:
            playerman.JumpCount = 10
            playerman.isJump = False



        # update winodw event
    pygame.display.update()
# quit event
pygame.quit()

#check for scroll up
    if playerman.y > 450: #somewhere close to the bottom of the screen
        playerman.y -= playerman.fall  #reverse direction
        for enemy in enemies:
            enemy.y -= playerman.fall
The Big Kahuna
  • 2,097
  • 1
  • 6
  • 19
  • THANK YOU SO MUCH I WAS SEARCHING FOR A SOLUTION FOR 3 DAYS!! the only problem is when I go UP I stay up instead of moving back down https://gyazo.com/02689600575707480ca10e9e54d9f76e thank you so much man!!!! – Habib Ismail May 05 '20 at 02:50
  • 1
    @HabibIsmail No problem! I didnt do the scrolling down, my bad, You can do the same thing for the scroll up, just change it to `playerman.y > number` and `-= speed` – The Big Kahuna May 05 '20 at 03:03
  • sorry if I am being annoying but I make a new key for up? and then add that? – Habib Ismail May 05 '20 at 21:06
  • @HabibIsmail No, because you want to check if the player is moving outside the screen every frame, not just the frames you press the down key as there is gravity, so you move without having to press anything, I put the code in the answer above. – The Big Kahuna May 05 '20 at 23:38
  • it works great LAST question 0_0 I did that but I want it to scroll down if I am not standing like my player scrolls back to my window 450 if not standing on a platform https://gyazo.com/c9a3c1fac6ca22da2508875bc0dfa27a when I go left it will push me down if go right it pushes me down I want it to take me back to 450 if I am not on a platform – Habib Ismail May 07 '20 at 23:34
  • @HabibIsmail I think you may have put it in the wrong place. It looks like you have put in so it only checks when pressing down a key. If you look at the full code, ive added it where it should be and hopefully made it easy to find – The Big Kahuna May 08 '20 at 01:12
  • @HabibIsmail I also changed it from scrolling by 1 to scrolling by `playerman.fall` so it scrolls by the amount the player is falling, i think it looks better and is more of what your after, You can still put it back to 1 tho – The Big Kahuna May 08 '20 at 01:26