'bullet won't draw in alien invasion game

so I'm still working on the alien invasion game in python crash course. after I fixed the ship bug now my bullet won't draw onto the screen I'll just give you the code. Hopefully you will know what the problem is.

alien_invasion.py:

import pygame
import sys
from settings import Settings
from ship import Ship
from bullet import Bullet


class AlienInvasion:

    def __init__(self):
        pygame.init()
        self.settings = Settings()
        pygame.display.set_caption("Alien Invasion")
        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()

    def run_game(self):
        while True:
            self._check_events()
            self.ship.update()
            self.bullets.update()
            self._update_screen()

    def _check_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()
                if event.key == pygame.K_RIGHT:
                    self.ship.moving_right = True
                if event.key == pygame.K_LEFT:
                    self.ship.moving_left = True
                if event == pygame.K_SPACE:
                    self._fire_bullet()
            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_RIGHT:
                    self.ship.moving_right = False
                if event.key == pygame.K_LEFT:
                    self.ship.moving_left = False
            if event.type == pygame.VIDEORESIZE:
                self.width = pygame.display.get_surface().get_width()
                self.height = pygame.display.get_surface().get_height()
                self.settings.display = pygame.display.set_mode((int(self.width), int(self.height)), pygame.RESIZABLE)
                self.ship = Ship(self)

    def _fire_bullet(self):
        new_bullet = Bullet(self)
        self.bullets.add(new_bullet)

    def _update_screen(self):
        self.settings.display.fill(self.settings.rgb_color)
        self.ship.blitme()
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        pygame.display.flip()


if __name__ == '__main__':
    ai = AlienInvasion()
    ai.run_game()

settings.py:

import pygame
from win32api import GetSystemMetrics


class Settings:

    def __init__(self):
        loop = True
        while loop is True:
            print(f"Set Window Size(Type 'default' to use default 1920*1080, type 'full' to use full screen)")
            self.screenX = input()
            if self.screenX == 'default':
                self.screen_size = (1920, 1080)
                self.display_mode = 'Window'
                loop = False
            elif self.screenX == 'full':
                self.display_mode = 'Full'
                loop = False
            elif self.screenX.isdigit():
                print("X")
                self.screenY = input()
                self.screen_size = (int(self.screenX), int(self.screenY))
                self.display_mode = 'Window'
                loop = False
            else:
                print("You either type a integer, 'default' or 'full'")
        loop = True
        while loop is True:
            self.R = input("\nSet RGB Color(type 'default' to use default color)"
                           "\nR: ")
            if self.R == 'default':
                self.R = 59
                self.G = 61
                self.B = 151
                loop = False
            elif self.R.isdigit():
                while loop is True:
                    if int(self.R) <= 255:
                        self.G = input("G: ")
                        loop = False
                    else:
                        print("Choose between 0 and 255")
                        self.R = input("\nSet RGB Color(type 'default' to use default color)"
                                       "\nR: ")
                loop = True
                while loop is True:
                    if int(self.G) <= 255:
                        self.B = input("B: ")
                        loop = False
                    else:
                        print("Choose between 0 and 255")
                        self.G = input("\nG: ")
                loop = True
                while loop is True:
                    if int(self.B) <= 255:
                        loop = False
                    else:
                        print("Choose between 0 and 255")
                        self.B = input("\nB: ")
            else:
                print("Type an integer or 'default'")
        self.rgb_color = (int(self.R), int(self.G), int(self.B))
        if self.display_mode == 'Window':
            self.display = pygame.display.set_mode(self.screen_size, pygame.RESIZABLE)
        elif self.display_mode == 'Full':
            self.display = pygame.display.set_mode((GetSystemMetrics(0), GetSystemMetrics(1)), pygame.FULLSCREEN)
        self.display.fill(self.rgb_color)
        loop = True
        while loop is True:
            self.ship_speed = input("Set ship speed, (0 - 5) ")
            self.float_ship_speed = float(self.ship_speed)
            if self.float_ship_speed <= 5:
                loop = False
            else:
                print("Type a number between 0 and 5")

ship.py:

import pygame


class Ship:

    def __init__(self, ai_game):
        self.display = ai_game.settings.display
        self.settings = ai_game.settings
        self.display_rect = ai_game.settings.display.get_rect()
        self.image = pygame.image.load('SpaceShip.png')
        self.rect = self.image.get_rect()
        self.rect.midbottom = self.display_rect.midbottom

        self.x = float(self.rect.x)
        self.moving_right = False
        self.moving_left = False

    def update(self):
        if self.moving_right:
            self.x += self.settings.float_ship_speed
        if self.moving_left:
            self.x -= self.settings.float_ship_speed
        self.rect.x = self.x

    def blitme(self):
        self.display.blit(self.image, self.rect)

bullet.py:

import pygame
from pygame.sprite import Sprite


class Bullet(Sprite):

    def __init__(self, ai_game):
        super().__init__()
        self.ai_game = ai_game
        self.bullet = pygame.image.load("bullet.png")
        self.screen = ai_game.settings.display
        self.settings = ai_game.settings
        self.midbottom = ai_game.ship
        self.rect = self.bullet.get_rect()
        self.rect.midbottom = ai_game.ship.rect.midbottom

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

    def update(self):
        self.y -= self.settings.bullet_speed
        self.rect.y = self.y

    def draw_bullet(self):
        self.screen.blit(self.bullet, self.rect)

it's my first time making a game, so a lot of bugs are expected



Solution 1:[1]

I think your issue comes from the code in bullet.update():

    def update(self):
        self.y -= self.settings.bullet_speed
        self.rect.y = self.y

You're changing the value of self.y by the value assigned to bullet_speed. But I don't see where bullet_speed is defined. I don't see that attribute in your Settings class.

(I saw this just after posting the comment on your question. In the future, you're much more likely to get answers if you can provide a much simpler version of your question. In trying to create that simpler version, you'd probably notice that bullet_speed was never defined.)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 japhyr