import pygame import random import math import os # Initialize Pygame pygame.init() # Screen dimensions WIDTH, HEIGHT = 800, 600 screen = pygame.display.set_mode((WIDTH, HEIGHT)) pygame.display.set_caption("Asteroids") # Colors BLACK = (0, 0, 0) WHITE = (255, 255, 255) RED = (255, 0, 0) # Clock clock = pygame.time.Clock() FPS = 60 # Game variables running = True game_over = False defeat_message = "" # Load all PNG files from the "images" folder IMAGE_FOLDER = "images" asteroid_images = [] for filename in os.listdir(IMAGE_FOLDER): if filename.endswith(".png"): image = pygame.image.load(os.path.join(IMAGE_FOLDER, filename)) asteroid_images.append((image, filename)) # Store both image and filename # Check if images were loaded if not asteroid_images: raise FileNotFoundError("No PNG files found in the 'images' folder!") class Ship: def __init__(self): self.x = WIDTH // 2 self.y = HEIGHT // 2 self.angle = 0 self.speed = 0 self.acceleration = 0.1 self.max_speed = 5 self.rotation_speed = 5 self.size = 20 def draw(self): # Define the ship's shape tip_x = self.x + math.cos(math.radians(self.angle)) * self.size tip_y = self.y - math.sin(math.radians(self.angle)) * self.size left_x = self.x + math.cos(math.radians(self.angle + 120)) * self.size left_y = self.y - math.sin(math.radians(self.angle + 120)) * self.size right_x = self.x + math.cos(math.radians(self.angle - 120)) * self.size right_y = self.y - math.sin(math.radians(self.angle - 120)) * self.size # Draw the ship pygame.draw.polygon(screen, WHITE, [(tip_x, tip_y), (left_x, left_y), (right_x, right_y)]) def move(self): self.x += math.cos(math.radians(self.angle)) * self.speed self.y -= math.sin(math.radians(self.angle)) * self.speed # Wrap around the screen if self.x > WIDTH: self.x = 0 elif self.x < 0: self.x = WIDTH if self.y > HEIGHT: self.y = 0 elif self.y < 0: self.y = HEIGHT def accelerate(self): if self.speed < self.max_speed: self.speed += self.acceleration def decelerate(self): if self.speed > 0: self.speed -= self.acceleration else: self.speed = 0 def rotate_left(self): self.angle += self.rotation_speed def rotate_right(self): self.angle -= self.rotation_speed # Create the player ship player = Ship() def handle_input(): keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: player.rotate_left() if keys[pygame.K_RIGHT]: player.rotate_right() if keys[pygame.K_UP]: player.accelerate() if keys[pygame.K_DOWN]: player.decelerate() if keys[pygame.K_SPACE]: shoot() class Asteroid: def __init__(self, x, y, size, image, filename): self.x = x self.y = y self.size = size self.speed = random.randint(1, 3) self.angle = random.randint(0, 360) self.image = pygame.transform.scale(image, (size, size)) # Resize the image self.filename = filename # Store the filename def draw(self): screen.blit(self.image, (int(self.x - self.size / 2), int(self.y - self.size / 2))) def move(self): self.x += math.cos(math.radians(self.angle)) * self.speed self.y -= math.sin(math.radians(self.angle)) * self.speed # Wrap around the screen if self.x > WIDTH: self.x = 0 elif self.x < 0: self.x = WIDTH if self.y > HEIGHT: self.y = 0 elif self.y < 0: self.y = HEIGHT def check_collision(obj1, obj2): distance = math.sqrt((obj1.x - obj2.x)**2 + (obj1.y - obj2.y)**2) return distance < obj2.size / 2 + obj1.size / 2 def create_asteroids(num_asteroids, min_size, max_size, safe_distance): asteroids = [] for _ in range(num_asteroids): while True: x = random.randint(0, WIDTH) y = random.randint(0, HEIGHT) size = random.randint(min_size, max_size) # Check if the asteroid is too close to the ship distance_to_ship = math.sqrt((x - player.x)**2 + (y - player.y)**2) if distance_to_ship > safe_distance: image, filename = random.choice(asteroid_images) # Randomly select an image and its filename asteroids.append(Asteroid(x, y, size, image, filename)) break return asteroids # Create a list of asteroids with larger initial size and ensure they don't spawn on the ship asteroids = create_asteroids(num_asteroids=10, min_size=50, max_size=80, safe_distance=100) class Bullet: def __init__(self, x, y, angle): self.x = x self.y = y self.angle = angle self.speed = 10 self.size = 2 def draw(self): pygame.draw.circle(screen, WHITE, (int(self.x), int(self.y)), self.size) def move(self): self.x += math.cos(math.radians(self.angle)) * self.speed self.y -= math.sin(math.radians(self.angle)) * self.speed bullets = [] def shoot(): bullets.append(Bullet(player.x, player.y, player.angle)) def split_asteroid(asteroid): if asteroid.size > 30: # Minimum size before splitting stops new_size = asteroid.size // 2 image, filename = random.choice(asteroid_images) # Use the same image and filename for split asteroids asteroids.append(Asteroid(asteroid.x, asteroid.y, new_size, image, filename)) asteroids.append(Asteroid(asteroid.x, asteroid.y, new_size, image, filename)) def draw_defeat_message(): font_normal = pygame.font.SysFont("Arial", 36) font_bold = pygame.font.SysFont("Arial", 48, bold=True) # Split the message into two parts first_part = "You have been defeated by" second_part = defeat_message.split("by ")[1].upper() # Get the part after "by" and make it uppercase # Render both parts text1 = font_normal.render(first_part, True, RED) text2 = font_bold.render(second_part, True, RED) # Position the text text1_rect = text1.get_rect(centerx=WIDTH // 2, bottom=HEIGHT // 2) text2_rect = text2.get_rect(centerx=WIDTH // 2, top=HEIGHT // 2) # Draw both parts screen.blit(text1, text1_rect) screen.blit(text2, text2_rect) while running: screen.fill(BLACK) # Handle events for event in pygame.event.get(): if event.type == pygame.QUIT: running = False if not game_over: # Handle input handle_input() # Move and draw the player player.move() player.draw() # Check for collisions between bullets and asteroids for bullet in bullets[:]: for asteroid in asteroids[:]: if check_collision(bullet, asteroid): bullets.remove(bullet) asteroids.remove(asteroid) split_asteroid(asteroid) break # Move and draw bullets for bullet in bullets: bullet.move() bullet.draw() # Remove bullets that go off-screen bullets = [bullet for bullet in bullets if 0 <= bullet.x <= WIDTH and 0 <= bullet.y <= HEIGHT] # Move and draw the asteroids for asteroid in asteroids: asteroid.move() asteroid.draw() # Check for collisions between the player and asteroids for asteroid in asteroids: if check_collision(player, asteroid): defeat_message = f"You have been defeated by {asteroid.filename.split('.')[0]}" game_over = True else: # Display defeat message draw_defeat_message() # Update the display pygame.display.flip() # Cap the frame rate clock.tick(FPS) pygame.quit()