Skip to content

Instantly share code, notes, and snippets.

@ivanfioravanti
Created December 25, 2024 19:06
Show Gist options
  • Save ivanfioravanti/d6578a83ed81f8b392330c1bf3f2899f to your computer and use it in GitHub Desktop.
Save ivanfioravanti/d6578a83ed81f8b392330c1bf3f2899f to your computer and use it in GitHub Desktop.
Asteroids with DeepSeek V3 chat.
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()
@ivanfioravanti
Copy link
Author

Just add png files in a folder called images at same level of py file and that's it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment