Bullet Projectile not showing

when i load this, the bullets dont show them flying from one place to the other, ive confirmed that bullets are being spawned but idk how to fix

import pygame
import random
import os
import math
import time
from typing import Tuple

# Initialize Pygame
pygame.init()

# Type aliases
Position = Tuple[int, int]
Color = Tuple[int, int, int]

class GameConfig:
    """Configuration class for game constants and settings."""
    SCREEN_WIDTH: int = 800
    SCREEN_HEIGHT: int = 600
    FPS: int = 60
    BG_COLOR: Color = (9, 121, 105)
    SOLDIER_SIZE: Tuple[int, int] = (50, 50)
    BULLET_SIZE: Tuple[int, int] = (10, 10)  # Updated bullet size
    SOLDIER_HEALTH: int = 200
    BULLET_DAMAGE: int = 50
    RELOAD_TIME: int = 2000  # 2 seconds in milliseconds
    BULLET_SPEED: float = 3  # Reduced speed for visibility
    
    @staticmethod
    def get_asset_path(filename: str) -> str:
        """Returns the full path for an asset file."""
        return os.path.join(os.path.expanduser("~"), "Downloads", "New Folder", filename)

class Bullet(pygame.sprite.Sprite):
    """Represents a bullet fired by soldiers."""
    
    def __init__(self, start_pos: Position, target_pos: Position, speed: float = GameConfig.BULLET_SPEED):
        super().__init__()
        self.image = pygame.Surface(GameConfig.BULLET_SIZE)
        self.image.fill((255, 255, 0))  # Yellow bullet for visibility
        self.rect = self.image.get_rect()
        self.rect.center = start_pos
        
        # Calculate direction
        dx = target_pos[0] - start_pos[0]
        dy = target_pos[1] - start_pos[1]
        distance = math.sqrt(dx**2 + dy**2)
        self.velocity_x = (dx/distance) * speed if distance > 0 else 0
        self.velocity_y = (dy/distance) * speed if distance > 0 else 0
        
    def update(self):
        """Update bullet position."""
        self.rect.x += self.velocity_x
        self.rect.y += self.velocity_y
        
        # Remove if off screen
        if not (0 <= self.rect.x <= GameConfig.SCREEN_WIDTH and 
                0 <= self.rect.y <= GameConfig.SCREEN_HEIGHT):
            self.kill()

class Soldier(pygame.sprite.Sprite):
    """Represents a soldier in the battle simulation."""
    
    def __init__(self, position: Position, team: str, shooting_image: pygame.Surface, resting_image: pygame.Surface):
        super().__init__()
        self.shooting_image = pygame.transform.scale(shooting_image, GameConfig.SOLDIER_SIZE)
        self.resting_image = pygame.transform.scale(resting_image, GameConfig.SOLDIER_SIZE)
        self.image = self.resting_image
        self.rect = self.image.get_rect()
        self.rect.center = position
        self.team = team
        self.health = GameConfig.SOLDIER_HEALTH
        self.last_shot = pygame.time.get_ticks()
        self.shooting = False
        self.shoot_start_time = 0
        
    def update(self, soldiers, bullets):
        """Update soldier state and handle shooting."""
        if self.health <= 0:
            self.kill()
            return

        now = pygame.time.get_ticks()
        
        # Find closest enemy
        closest_enemy = self.find_closest_enemy(soldiers)
        
        if closest_enemy and now - self.last_shot > GameConfig.RELOAD_TIME:
            # Determine if soldier wants to shoot (50% chance)
            if random.random() < 0.5:
                # Enter shooting position
                if not self.shooting:
                    self.shooting = True
                    self.image = self.shooting_image
                    self.shoot_start_time = time.time()
                
                # Wait 1 second before firing
                if self.shooting and (time.time() - self.shoot_start_time) >= 1:
                    self.fire_bullet(closest_enemy.rect.center, bullets)
                    self.last_shot = now
                    self.shooting = False
                    self.image = self.resting_image
    
    def find_closest_enemy(self, soldiers):
        """Find the closest enemy soldier."""
        min_dist = float('inf')
        closest_enemy = None
        
        for soldier in soldiers:
            if soldier.team != self.team:
                dist = math.sqrt((self.rect.centerx - soldier.rect.centerx)**2 + 
                               (self.rect.centery - soldier.rect.centery)**2)
                if dist < min_dist:
                    min_dist = dist
                    closest_enemy = soldier
        
        return closest_enemy
    
    def fire_bullet(self, target_pos: Position, bullets: pygame.sprite.Group):
        """Fire a bullet towards the target position."""
        bullet = Bullet(self.rect.center, target_pos)
        bullets.add(bullet)

class BattleSimulator:
    """Main game class for the battle simulation."""
    
    def __init__(self):
        """Initialize the battle simulator."""
        self.screen = pygame.display.set_mode((GameConfig.SCREEN_WIDTH, GameConfig.SCREEN_HEIGHT))
        pygame.display.set_caption("Soldier Battle Simulator")
        self.clock = pygame.time.Clock()
        self.all_sprites = pygame.sprite.Group()
        self.bullets = pygame.sprite.Group()
        self.soldiers = pygame.sprite.Group()
        
        # Load images
        self.german_image = pygame.image.load(GameConfig.get_asset_path("german_shooting.png"))
        self.french_image = pygame.image.load(GameConfig.get_asset_path("french_shooting.png"))
        self.german_resting = pygame.image.load(GameConfig.get_asset_path("german_resting.png"))
        self.french_resting = pygame.image.load(GameConfig.get_asset_path("french_resting.png"))

    def spawn_soldiers(self, french_count: int, german_count: int):
        """Spawn initial soldiers for both teams."""
        # Spawn French soldiers
        for _ in range(french_count):
            position = (
                random.randint(GameConfig.SCREEN_WIDTH - 150, GameConfig.SCREEN_WIDTH - 50),
                random.randint(50, GameConfig.SCREEN_HEIGHT - 50)
            )
            soldier = Soldier(position, "French", self.french_image, self.french_resting)
            self.all_sprites.add(soldier)
            self.soldiers.add(soldier)

        # Spawn German soldiers
        for _ in range(german_count):
            position = (
                random.randint(50, 150),
                random.randint(50, GameConfig.SCREEN_HEIGHT - 50)
            )
            soldier = Soldier(position, "German", self.german_image, self.german_resting)
            self.all_sprites.add(soldier)
            self.soldiers.add(soldier)

    def handle_collisions(self):
        """Handle bullet collisions with soldiers."""
        for bullet in self.bullets:
            hits = pygame.sprite.spritecollide(bullet, self.soldiers, False)
            for soldier in hits:
                soldier.health -= GameConfig.BULLET_DAMAGE
                bullet.kill()

    def run(self):
        """Main game loop."""
        french_count = int(input("Enter number of French soldiers: "))
        german_count = int(input("Enter number of German soldiers: "))
        self.spawn_soldiers(french_count, german_count)

        running = True
        while running:
            self.clock.tick(GameConfig.FPS)
            
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False

            # Update game state
            self.soldiers.update(self.soldiers, self.bullets)
            self.bullets.update()
            self.handle_collisions()

            # Render
            self.screen.fill(GameConfig.BG_COLOR)
            self.all_sprites.draw(self.screen)
            self.bullets.draw(self.screen)
            pygame.display.flip()

        pygame.quit()

if __name__ == "__main__":
    simulator = BattleSimulator()
    simulator.run()

It’s hard for us to help you with this code because we don’t have access to the .png files. Could you rewrite this code so that instead of loading image files, it just draws simple colored rectangles instead? This way, you can share the program without having to upload the image files somewhere for people to download.

This is often used in game development since the art assets are often being developed by someone else. Using basic colored rectangles as placeholder images lets people try out the gameplay without being distracted by graphics.