3
\$\begingroup\$

I'd like to create a moving background in my Python game, with an image, that moves up until it reaches the end, then it goes back to its first position. I'm still in my learning process and this is really troublesome, because I don't even know the approach it.

image:

enter image description here

What I have for now:

import pygame, random, sys

def main():
  pygame.init()

  global screenSize, allColors, FPS, clock, surface

  screenSize = (640, 480)

  surface = pygame.display.set_mode(screenSize)
  pygame.display.set_caption('Space Shooters')

  black    = (0  , 0  , 0  )
  white    = (255, 255, 255)
  gray     = (100, 100, 100)
  navyblue = (60 , 60 , 100)
  red      = (255, 0  , 0  )
  green    = (0  , 255, 0  )
  blue     = (0  , 0  , 255)
  yellow   = (255, 255, 0  )
  orange   = (255, 155, 55 )
  purple   = (255, 0  , 255)
  cyan     = (0  , 255, 255)
  #             0      1     2      3      4      5       6      7       8       9
  allColors = [white,red, green, blue, yellow, orange, purple, cyan, navyblue, gray]
  clock = pygame.time.Clock()

  FPS = 64
#-------------------------------------------------------------------------------
  spaceship = Spaceship()
  bullets = Bullet(spaceship)
  while True:
    #step1 SetDelay
    clock.tick(FPS)
    #step2 reactOnPlayerInput
    for event in pygame.event.get():
      if event.type == pygame.QUIT:
        terminate()
      if event.type == pygame.KEYDOWN:
        if event.key == pygame.K_ESCAPE:
          terminate()
        if event.key == pygame.K_UP:
          spaceship.moveUp = True
          spaceship.moveDown = False
        if event.key == pygame.K_DOWN:
          spaceship.moveUp = False
          spaceship.moveDown = True
        if event.key == pygame.K_LEFT:
          spaceship.moveRight = False
          spaceship.moveLeft = True
        if event.key == pygame.K_RIGHT:
          spaceship.moveRight = True
          spaceship.moveLeft = False
        if event.key == pygame.K_SPACE:
          bullets.isShooting = True

      if event.type == pygame.KEYUP:
        if event.key == pygame.K_UP:
          spaceship.moveUp = False
        if event.key == pygame.K_DOWN:
          spaceship.moveDown = False
        if event.key == pygame.K_LEFT:
          spaceship.moveLeft = False
        if event.key == pygame.K_RIGHT:
          spaceship.moveRight = False
        if event.key == pygame.K_SPACE:
          bullets.isShooting = False

    #step3 updateClasses/Variables
    spaceship.update()
    bullets.update(spaceship)
    #step4 renderEverything
    surface.fill((255,255,255))
    bullets.render()
    spaceship.render()
    pygame.display.update()

def terminate():
  pygame.quit()
  sys.exit()

class Spaceship():
  def __init__(self):
    self.height = 32
    self.width = 28

    self.ssIMG = pygame.image.load("/home/bucky/Dokumente/Computing/Python/scripts/pygame/spaceShooter/spaceShip.png")

    self.centerx = screenSize[0] / 2
    self.centery = screenSize[1] / 2

    self.speed = 5
    self.color = allColors[9]

    self.moveLeft, self.moveRight, self.moveUp, self.moveDown = False, False, False, False

    self.rect = pygame.Rect(self.centerx - self.width / 2, self.centery - self.height / 2, self.width, self.height)


  def update(self):
    if self.moveLeft and self.rect.left > 0:
      self.rect.centerx -= self.speed
    if self.moveRight and self.rect.right < screenSize[0] - 1:
      self.rect.centerx += self.speed
    if self.moveUp and self.rect.top > 0:
      self.rect.centery -= self.speed
    if self.moveDown and self.rect.bottom < screenSize[1] - 1:
      self.rect.centery += self.speed

  def render(self):
    surface.blit(self.ssIMG, self.rect)

class Bullet():
  def __init__(self, spaceship):
    self.bulletIMG = pygame.image.load("/home/bucky/Dokumente/Computing/Python/scripts/pygame/spaceShooter/bullet.png")

    self.width = 8
    self.height = 12

    self.centerx = spaceship.rect.centerx
    self.centery = spaceship.rect.centery

    self.color = allColors[4]

    self.speed = 16

    self.isShooting = False

    self.listOfBullets = []

  def update(self, spaceship):
    for i in range(len(self.listOfBullets)):
      if i >= len(self.listOfBullets):
        break
      if self.listOfBullets[i]['counter'] >= 64:
        del self.listOfBullets[i]
        continue
      self.listOfBullets[i]['rect'].centery -= self.speed
      self.listOfBullets[i]['counter'] += 1

    if self.isShooting:
      self.listOfBullets.append({
      'rect':pygame.Rect(spaceship.rect.centerx - self.width / 2, spaceship.rect.centery - self.height, self.width, self.height),
      'counter':0
      })

  def render(self):
    for i in range(len(self.listOfBullets)):
      surface.blit(self.bulletIMG, self.listOfBullets[i]['rect'])

main()

[Edit]:

With the right approach of Areeb I could figure out how to move the background permanently. I added a Background class, with a 'bgY'-variable, which is permanently decreasing, until it goes out of the screen, than it goes back to its first position. But I had to add the same picture twice with the diffrence of a little displacement, because when the background runs out of the screen there will not be any background at all:

class Background():
    def __init__(self):
        self.bgimage = pygame.image.load('/home/bucky/Dokumente/Computing/Python/scripts/pygame/spaceShooter/weltraum.png')
        self.rectBGimg = self.bgimage.get_rect()
        self.bgimage = pygame.transform.scale(self.bgimage, (int(screenSize[0] / self.rectBGimg.width * self.rectBGimg.width), int(screenSize[0] / self.rectBGimg.width * self.rectBGimg.height)))
        self.rectBGimg = self.bgimage.get_rect()

        self.bgY1 = 0
        self.bgX1 = 0

        self.bgY2 = self.rectBGimg.height
        self.bgX2 = 0

        self.movingUpSpeed = 5

    def update(self):
        self.bgY1 -= self.movingUpSpeed
        self.bgY2 -= self.movingUpSpeed
        if self.bgY1 <= -self.rectBGimg.height:
            self.bgY1 = self.rectBGimg.height
        if self.bgY2 <= -self.rectBGimg.height:
            self.bgY2 = self.rectBGimg.height

    def render(self):
        surface.blit(self.bgimage, (self.bgX1, self.bgY1))
        surface.blit(self.bgimage, (self.bgX2, self.bgY2))

Watch the result: https://youtu.be/dhuPA2v8gG0

\$\endgroup\$
2
\$\begingroup\$

A background really isn't anything but an image that you draw before anything else.

The easiest way to do that is to import the image using image.load() and save it to the variable background. After doing that create a new variable background_y that saves the position of where the background is.

After that, go to your update function and decrement background_y, because you want it to move up. Then add an if statement that checks whether background_y is equal to the negative height of the background image, which can be gotten using background.get_height(). And in that if statement, set background_y to whatever it was originally.

Now having done that, just add surface.blit(background, (0, background_y)) right after you clear the screen using surface.fill(). That will draw the background in the right position.

That should get you the results you have been looking for.

If you want an example with code, Just ask in the comments.

\$\endgroup\$
  • \$\begingroup\$ Yeah, that would be nice! And thank you for the answer, I'll try it now \$\endgroup\$ – Uuser Jul 25 '16 at 12:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.