문제

i've been looking into game development in python and i'm very new to it, i tryed to copy a space invaders and here is what i came up with, it is massively inspired from tutorials and code i found online.

What im trying to do know is to get the background moving so i thought it would be a good idea to create 2 sprites with 2 background image and make them move one after the other. As soon as one is out of the screen it should reappear at the bottom and so on. But it does not work i am not sure what is going wrong. Here is what i have to far:

#!/usr/bin/env python

from helpers import *

class Space1(pygame.sprite.Sprite):
    def __init__(self, i):                      
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("space.png", 10)
        self.dx = -5
        self.reset(i)

    def update(self, i):
        self.rect.top += self.dx
        if i == 1:
            if self.rect.top <= -600:
                self.__init__(i) 
        else:
            if self.rect.top <= -1200:
                self.__init__(i) 

    def reset(self, i):
        if i == 1:
            self.rect.top = 1
        else:
            self.rect.top = 300

class Space2(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("space.png", 10)
        self.dx = -5
        self.reset()

    def update(self):
        self.rect.top += self.dx
        if self.rect.top <= -1200:
            self.__init__() 

    def reset(self):
        self.rect.top = 600

class Player(pygame.sprite.Sprite):

    def __init__(self):

        pygame.sprite.Sprite.__init__(self)

        self.image, self.rect = load_image('ship.gif', -1)
        self.x_dist = 5
        self.y_dist = 5
        self.lasertimer = 0
        self.lasermax = 5
        self.rect.centery = 400
        self.rect.centerx = 400

    def update(self):
        key = pygame.key.get_pressed()

        # Movement
        if key[K_UP]:
            self.rect.centery += -3
        if key[K_DOWN]:
            self.rect.centery += 3
        if key[K_RIGHT]:
            self.rect.centerx += 3
        if key[K_LEFT]:
            self.rect.centerx += -3

        # Lasers
        if key[K_SPACE]:
            self.lasertimer = self.lasertimer + 1
            if self.lasertimer == self.lasermax:
                laserSprites.add(Laser(self.rect.midtop))
                self.lasertimer = 0

        # Restrictions
        self.rect.bottom = min(self.rect.bottom, 600)
        self.rect.top = max(self.rect.top, 0)
        self.rect.right = min(self.rect.right, 800)
        self.rect.left = max(self.rect.left, 0)

class Laser(pygame.sprite.Sprite):
    def __init__(self, pos):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("laser.png", -1)
        self.rect.center = pos

    def update(self):
        if self.rect.right > 800:
            self.kill()
        else:
            self.rect.move_ip(0, -15)

class Enemy(pygame.sprite.Sprite):
    def __init__(self, centerx):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("alien.png", -1)
        self.rect = self.image.get_rect()
        self.dy = 8
        self.reset()

    def update(self):
        self.rect.centerx += self.dx
        self.rect.centery += self.dy
        if self.rect.top > 600:
            self.reset()

        # Laser Collisions    
        if pygame.sprite.groupcollide(enemySprites, laserSprites, 1, 1):
           explosionSprites.add(EnemyExplosion(self.rect.center))

        # Ship Collisions
        if pygame.sprite.groupcollide(enemySprites, playerSprite, 1, 1):
           explosionSprites.add(EnemyExplosion(self.rect.center))
           explosionSprites.add(PlayerExplosion(self.rect.center))

    def reset(self):
        self.rect.bottom = 0
        self.rect.centerx = random.randrange(0, 600)
        self.dy = random.randrange(5, 10)
        self.dx = random.randrange(-2, 2)

class EnemyExplosion(pygame.sprite.Sprite):
    def __init__(self, pos):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("enemyexplosion.png", -1)
        self.rect.center = pos        
        self.counter = 0
        self.maxcount = 10

    def update(self):
        self.counter = self.counter + 1
        if self.counter == self.maxcount:
            self.kill()

class PlayerExplosion(pygame.sprite.Sprite):
    def __init__(self, pos):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("enemyexplosion.png", -1)
        self.rect.center = pos        
        self.counter = 0
        self.maxcount = 10

    def update(self):
        self.counter = self.counter + 1
        if self.counter == self.maxcount:
            self.kill()
            exit()

def main():       
# Initialize Everything

    pygame.init()

    screen = pygame.display.set_mode((800, 600))

    pygame.display.set_caption('UoN Invaders')

# Create The Backgound

    background = pygame.Surface(screen.get_size())

    background = background.convert()

    background.fill((000, 000, 000))

# Display The Background

    screen.blit(background, (0, 0))

    pygame.display.flip()

# Start Music   

    music = pygame.mixer.music.load ("data/spacequest.mp3")
    pygame.mixer.music.play(-1)



# Initialize Game Objects
    global clock

    clock = pygame.time.Clock()

    i = 0
    i += 1

    space1 = Space1(i)
    space2 = Space2()
    global player

    player = Player()


# Render Objects
    # Space
    space1 = pygame.sprite.RenderPlain((space1))
    space2 = pygame.sprite.RenderPlain((space2))

    # Player
    global playerSprite   
    playerSprite = pygame.sprite.RenderPlain((player))

    # Enemy
    global enemySprites
    enemySprites = pygame.sprite.RenderPlain(())
    enemySprites.add(Enemy(200))
    enemySprites.add(Enemy(300))
    enemySprites.add(Enemy(400))    

    # Projectiles    
    global laserSprites
    laserSprites = pygame.sprite.RenderPlain(())   

    # Collisions   
    global enemyExplosion
    enemyExplosion = pygame.sprite.RenderPlain(())
    global playerExplosion
    playerExplosion = pygame.sprite.RenderPlain(())
    global explosionSprites
    explosionSprites = pygame.sprite.RenderPlain(())


# Main Loop

    going = True

    while going:

        clock.tick(60)



        # Input Events

        for event in pygame.event.get():

            if event.type == QUIT:

                going = False

            elif event.type == KEYDOWN and event.key == K_ESCAPE:

                going = False

        # Update
        space1.update(i)
        space2.update()
        player.update()
        enemySprites.update()
        laserSprites.update()
        enemyExplosion.update()
        playerExplosion.update()
        explosionSprites.update()



        screen.blit(background, (0, 0))


        # Draw
        space1.draw(screen) 
        space2.draw(screen)          
        playerSprite.draw(screen)
        enemySprites.draw(screen)
        laserSprites.draw(screen)
        enemyExplosion.draw(screen)
        playerExplosion.draw(screen)
        explosionSprites.draw(screen)


        pygame.display.flip()



    pygame.quit()

if __name__ == '__main__':

    main()
도움이 되었습니까?

해결책

class Space(pygame.sprite.Sprite):
    def __init__(self, num):
        pygame.sprite.Sprite.__init__(self)
        self.rect.top = num * 600
        self.image, self.rect = load_image("space.png", 10)
        self.dx = -5
        self.reset()

    def update(self):
        self.rect.top += self.dx
        if self.rect.top <= -1200:
            self.reset() 

    def reset(self):
        self.rect.top = 600

So this is a class to store your sprite in. I don't believe you need 2, because you can have a list of all of your instances of space for example in main, instead of having...

space1 = Space1(i)
space2 = Space2()

I would recommend doing something like.

spaces = []
for x in range(2):
    spaces.append(Space(x))

and then change

space1 = pygame.sprite.RenderPlain((space1))
space2 = pygame.sprite.RenderPlain((space2))

to

for space in spaces:
    space = pygame.sprite.RenderPlain((space))

then instead of

space1.update(i)
space2.update()

do

for space in spaces:
    space.update()

finally instead of

space1.draw(screen) 
space2.draw(screen)

do

for space in spaces:
    space.draw(screen) 

I hope that this works for you, as I see this as a reasonable way to store your instances of space and allows you to more easily have the code with less code. If you have any problems implementing this, please just leave a comment and I will help you fix it.

Cheers!

다른 팁

well i didnt not use your method and i tried this it seems to work fine, however there is a samll gap between the 2 instances of Space, i'm trying to fix it know. Here is the modified code:

#!/usr/bin/env python

from helpers import *

print("hello world")

class Space1(pygame.sprite.Sprite):
    def __init__(self, i):                      
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("space.png", 10)
        self.dxy = -5
        self.reset(i)

    def update(self, i):
        self.rect.top += self.dxy
        if self.rect.top <= -600:
            self.__init__(i) 

    def reset(self, i):
        if i == 0:
            self.rect.top = 1
        else:
            self.rect.top = 600

class Space2(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("space.png", 10)
        self.dx = -5
        self.reset()

    def update(self):
        self.rect.top += self.dx
        if self.rect.top <= -600:
            self.__init__() 

    def reset(self):
        self.rect.top = 600

class Player(pygame.sprite.Sprite):

    def __init__(self):

        pygame.sprite.Sprite.__init__(self)

        self.image, self.rect = load_image('ship.png', -1)
        self.x_dist = 5
        self.y_dist = 5
        self.lasertimer = 0
        self.lasermax = 5
        self.rect.centery = 400
        self.rect.centerx = 400

    def update(self):
        key = pygame.key.get_pressed()

        # Movement
        if key[K_UP]:
            self.rect.centery += -3
        if key[K_DOWN]:
            self.rect.centery += 3
        if key[K_RIGHT]:
            self.rect.centerx += 3
        if key[K_LEFT]:
            self.rect.centerx += -3

        # Lasers
        if key[K_SPACE]:
            self.lasertimer = self.lasertimer + 1
            if self.lasertimer == self.lasermax:
                laserSprites.add(Laser(self.rect.midtop))
                self.lasertimer = 0

        # Restrictions
        self.rect.bottom = min(self.rect.bottom, 600)
        self.rect.top = max(self.rect.top, 0)
        self.rect.right = min(self.rect.right, 800)
        self.rect.left = max(self.rect.left, 0)

class Laser(pygame.sprite.Sprite):
    def __init__(self, pos):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("laser.png", -1)
        self.rect.center = pos

    def update(self):
        if self.rect.right > 800:
            self.kill()
        else:
            self.rect.move_ip(0, -15)

class Enemy(pygame.sprite.Sprite):
    def __init__(self, centerx):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("alien.png", -1)
        self.rect = self.image.get_rect()
        self.dy = 8
        self.reset()

    def update(self):
        self.rect.centerx += self.dx
        self.rect.centery += self.dy
        if self.rect.top > 600:
            self.reset()

        # Laser Collisions    
        if pygame.sprite.groupcollide(enemySprites, laserSprites, 1, 1):
           explosionSprites.add(EnemyExplosion(self.rect.center))

        # Ship Collisions
        if pygame.sprite.groupcollide(enemySprites, playerSprite, 1, 1):
           explosionSprites.add(EnemyExplosion(self.rect.center))
           explosionSprites.add(PlayerExplosion(self.rect.center))

    def reset(self):
        self.rect.bottom = 0
        self.rect.centerx = random.randrange(0, 600)
        self.dy = random.randrange(5, 10)
        self.dx = random.randrange(-2, 2)

class EnemyExplosion(pygame.sprite.Sprite):
    def __init__(self, pos):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("enemyexplosion.png", -1)
        self.rect.center = pos        
        self.counter = 0
        self.maxcount = 10

    def update(self):
        self.counter = self.counter + 1
        if self.counter == self.maxcount:
            self.kill()

class PlayerExplosion(pygame.sprite.Sprite):
    def __init__(self, pos):
        pygame.sprite.Sprite.__init__(self)
        self.image, self.rect = load_image("enemyexplosion.png", -1)
        self.rect.center = pos        
        self.counter = 0
        self.maxcount = 10

    def update(self):
        self.counter = self.counter + 1
        if self.counter == self.maxcount:
            self.kill()
            exit()

def main():      
    pygame.init()

    screen = pygame.display.set_mode((800, 600))

    pygame.display.set_caption('UoN Invaders')

    background = pygame.Surface(screen.get_size())

    background = background.convert()

    background.fill((000, 000, 000))

    screen.blit(background, (0, 0))

    pygame.display.flip()

    music = pygame.mixer.music.load ("data/spacequest.mp3")
    pygame.mixer.music.play(-1)

    global clock

    clock = pygame.time.Clock()

    i = 0


    space1 = Space1(i)
    space2 = Space2()
    global player

    player = Player()

    space1 = pygame.sprite.RenderPlain((space1))
    space2 = pygame.sprite.RenderPlain((space2))

    global playerSprite   
    playerSprite = pygame.sprite.RenderPlain((player))

    global enemySprites
    enemySprites = pygame.sprite.RenderPlain(())
    enemySprites.add(Enemy(200))
    enemySprites.add(Enemy(300))
    enemySprites.add(Enemy(400))    

    global laserSprites
    laserSprites = pygame.sprite.RenderPlain(())   

    global enemyExplosion
    enemyExplosion = pygame.sprite.RenderPlain(())
    global playerExplosion
    playerExplosion = pygame.sprite.RenderPlain(())
    global explosionSprites
    explosionSprites = pygame.sprite.RenderPlain(())


# Main Loop
    going = True
    while going:
        clock.tick(60)
        for event in pygame.event.get():

            if event.type == QUIT:

                going = False

            elif event.type == KEYDOWN and event.key == K_ESCAPE:

                going = False
        # Update
        i += 1        
        space1.update(i)
        space2.update()
        player.update()
        enemySprites.update()
        laserSprites.update()
        enemyExplosion.update()
        playerExplosion.update()
        explosionSprites.update()
        screen.blit(background, (0, 0))

        # Draw
        space1.draw(screen) 
        space2.draw(screen)          
        playerSprite.draw(screen)
        enemySprites.draw(screen)
        laserSprites.draw(screen)
        enemyExplosion.draw(screen)
        playerExplosion.draw(screen)
        explosionSprites.draw(screen)
        pygame.display.flip()

    while going == False:
        gameover()


def gameover():
    print("hello world")

if __name__ == '__main__':
    main()
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top