Created
December 25, 2024 19:06
-
-
Save ivanfioravanti/d6578a83ed81f8b392330c1bf3f2899f to your computer and use it in GitHub Desktop.
Asteroids with DeepSeek V3 chat.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just add png files in a folder called images at same level of py file and that's it.