How can I make a scrolling background in python with pygame?

孤人 提交于 2020-01-11 14:09:16

问题


I've been trying to make a space shooting game for the past 2 days and I want to make the background scrolling down but i don't know how. Heres my code:

import pygame
import time
pygame.init()

width = 800
height = 600

black = (0,0,0)
white = (255,255,255)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)

ship_width = 35
ship_height = 64

disp = pygame.display.set_mode((width,height))

pygame.display.set_caption("Space Jump")

clock = pygame.time.Clock()

background = pygame.image.load("Space.png").convert()

shipImg = pygame.image.load("Ship.png")

def ship(x,y):
    disp.blit(shipImg, (x,y))

def gameLoop():
    x = (width * 0.45)
    y = (height * 0.8)

x_ch = 0
y_ch = 0

gameExit = False

while not gameExit:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gameExit = True

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                x_ch = -5
            elif event.key == pygame.K_RIGHT:
                x_ch = 5
            elif event.key == pygame.K_UP:
                y_ch = -5
            elif event.key == pygame.K_DOWN:
                y_ch = 5


        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT:
                x_ch = 0
            if event.key == pygame.K_UP or event.key == pygame.K_DOWN:
                y_ch = 0

    x += x_ch
    y += y_ch

    if x > width - ship_width or x < 0:
        x_ch = 0

    if y > height - ship_height or y < 0:
        y_ch = 0
    x_bg = 0
    while True:
        disp.blit(background, (0,x_bg)) # i tried this but when i launch
                                        #a black screen just appears without 
        x_bg -= 1                       #any image
    ship(x,y)

    pygame.display.update()
    clock.tick(60)

gameLoop()
pygame.quit()
quit()

I have a background and i want to make it scrolling down continuously can you help me?


回答1:


Some things first:

  • fix your indentation
  • your ship function is practically useless
  • use the Rect to handle moving
  • your real problem is that your code never reaches pygame.display.update() because of your second while loop

So, to make an endless scrolling background, and easy way is to do the following:

Blit your background image twice, once at position y, and once at y + image_width (replace y with x of you want). Then, every iteration of your mainloop, you can substract from y to create the movement. Once an image moved it's entire height, reset y to the starting value


Here's a complete example, showing a scrolling background (and how to use sprites, groups, vectors and rects):

import pygame
pygame.init()
SCREEN = pygame.display.set_mode((300, 300))

move_map = {pygame.K_w: pygame.math.Vector2( 0, -1),
            pygame.K_s: pygame.math.Vector2( 0,  1),
            pygame.K_a: pygame.math.Vector2(-1,  0),
            pygame.K_d: pygame.math.Vector2( 1,  0)}

class Actor(pygame.sprite.Sprite):
    def __init__(self, group, color, pos, size=(30, 30)):
        self.image = pygame.Surface(size)
        self.image.fill(color)
        self.rect = self.image.get_rect(center=pos)
        pygame.sprite.Sprite.__init__(self, group)

class Bullet(Actor):
    def __init__(self, *args):
        Actor.__init__(self, *args)
        self.speed = 10

    def update(self):
        self.rect.move_ip(self.speed, 0)
        if not SCREEN.get_rect().colliderect(self.rect):
            self.kill()

class Player(Actor):
    def __init__(self, *args):
        self._layer = 4
        Actor.__init__(self, *args)
        self.speed = 4
        self.timeout = 0

    def update(self):
        p = pygame.key.get_pressed()
        move_vector = pygame.math.Vector2(0, 0)
        for v in [move_map[key] for key in move_map if p[key]]:
            move_vector += v
        if move_vector:
            self.rect.move_ip(*move_vector.normalize() * self.speed)
            self.rect.clamp_ip(SCREEN.get_rect())

        if self.timeout :
            self.timeout -= 1
        if p[pygame.K_SPACE] and not self.timeout:
            Bullet(self.groups()[0], (130, 200, 77), self.rect.center, (10, 3))
            self.timeout = 5


class Background(pygame.sprite.Sprite):
    def __init__(self, number, *args):
        self.image = pygame.image.load('back.jpg').convert()
        self.rect = self.image.get_rect()
        self._layer = -10
        pygame.sprite.Sprite.__init__(self, *args)
        self.moved = 0
        self.number = number
        self.rect.x = self.rect.width * self.number

    def update(self):
        self.rect.move_ip(-1, 0)
        self.moved += 1

        if self.moved >= self.rect.width:
            self.rect.x = self.rect.width * self.number
            self.moved = 0

group = pygame.sprite.LayeredUpdates()
Player(group, (255, 255, 255), (100, 100))
Background(0, group)
Background(1, group)

clock = pygame.time.Clock()
run = True
while run:
    for e in pygame.event.get():
        if e.type ==pygame.QUIT:
            run = False
    SCREEN.fill((0,0,0))
    group.update()
    group.draw(SCREEN)
    pygame.display.flip()
    clock.tick(60)

For testing this, you can use this image (save it as back.jpg):



来源:https://stackoverflow.com/questions/44622825/how-can-i-make-a-scrolling-background-in-python-with-pygame

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!