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