Search code examples
pygamesprite

my pygame bullet sprites only fire once each time through loop. would like to fire multiple times


i'm very new to coding, and i'm trying to get a ship to fire multiple bullets, but every time i push spacebar the bullet sort of re-triggers and doesn't make it to the end of the screen. it seems maybe only one instance of my Bullet class is called each time but i don't know how to fix it. here is the code i have going so far:

import sys

import pygame

from pygame.sprite import Sprite 

class Sideship():

    def __init__(self):

        pygame.init()

        self.screen = pygame.display.set_mode((1200,800))
        self.screen_rect = self.screen.get_rect()
        pygame.display.set_caption("Side Ship")
        self.bg_color = (50, 50, 255)

        self.bullets = pygame.sprite.Group()

        self.jet = Jet()

    def run_game(self):


        self.jet.rect.x = -20
        self.jet.rect.y = 290

        self.bullet = Bullet()

        while True:

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit()

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_DOWN:

                        self.jet.moving_down = True

                    if event.key == pygame.K_UP:

                        self.jet.moving_up = True


                    if event.key == pygame.K_SPACE:

                        self.new_bullet = Bullet()

                        self.bullets.add(self.new_bullet)
                        self.new_bullet.rect.x = self.jet.rect.x+200
                        self.new_bullet.rect.y = self.jet.rect.y+30

                if event.type == pygame.KEYUP:
                    if event.key == pygame.K_DOWN:

                        self.jet.moving_down = False

                    if event.key == pygame.K_UP:

                        self.jet.moving_up = False

                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:
                        sys.exit() 

            self.jet.update()

            self.bullets.update()

            self.screen.fill(self.bg_color)

            self.bullets.update()

            for bullet in self.bullets.sprites():
                pygame.draw.rect(self.screen, self.new_bullet.bullet_color, self.new_bullet.rect)

            self.screen.blit(self.jet.image, self.jet.rect)

            pygame.display.flip()

class Jet():

    def __init__(self):

        self.image = pygame.image.load('jet.bmp')
        self.rect = self.image.get_rect()

        self.moving_down = False
        self.moving_up = False

        self.rect.y = float(self.rect.y)
        self.rect.x = float(self.rect.x)

    def update(self):
        if self.moving_down and self.rect.bottom < 801:    
            self.rect.y += 1.9 
        if self.moving_up and self.rect.top > -14:
            self.rect.y -= 1.4

class Bullet(Sprite):

    def __init__(self,):
         super().__init__()
         self.bullet_width = 30
         self.bullet_height = 5
         self.bullet_color = (250,250,250)
         self.rect = pygame.Rect(0,0, self.bullet_width, self.bullet_height)

    def update(self):
        self.rect.x += 4

side_ship = Sideship()
side_ship.run_game()


Solution

  • The issue is in the loop, which draws the bullets. When you iterate through the bullets, the current element is referenced by bullet. Hence, you have to draw bullet, rather than self.new_bullet:

    pygame.draw.rect(self.screen, self.new_bullet.bullet_color, self.new_bullet.rect)

    for bullet in self.bullets.sprites():
       pygame.draw.rect(self.screen, bullet.bullet_color, bullet.rect)