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

前端 未结 1 1211
甜味超标
甜味超标 2021-01-17 04:57

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:

im         


        
1条回答
  •  慢半拍i
    慢半拍i (楼主)
    2021-01-17 05:24

    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):

    0 讨论(0)
提交回复
热议问题