Create main.py

This commit is contained in:
OusmBlueNinja 2025-04-10 11:29:20 -05:00
parent aa4e288c3d
commit b407560bde

218
only-particles-game/main.py Normal file
View File

@ -0,0 +1,218 @@
import pygame
import math
import random
# Initialize pygame
pygame.init()
# Screen dimensions
WIDTH, HEIGHT = 800, 600
SCREEN = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Neon Breaker with Particles")
# Colors (RGB)
BLACK = (0, 0, 0)
NEON_BLUE = (50, 255, 255)
NEON_PINK = (255, 50, 255)
NEON_GREEN = (50, 255, 50)
money = 0
# Helper function to draw a neon glow circle using multiple layers
def draw_neon_circle(surface, color, center, radius, glow_layers=10):
for i in range(glow_layers, 0, -1):
# Calculate alpha for the glow (decreases with each layer)
alpha = max(10, int(255 * (i / glow_layers) * 0.5))
glow_color = (*color, alpha)
glow_radius = radius + i
temp_surface = pygame.Surface((glow_radius * 2, glow_radius * 2), pygame.SRCALPHA)
pygame.draw.circle(temp_surface, glow_color, (glow_radius, glow_radius), glow_radius)
surface.blit(temp_surface, (center[0] - glow_radius, center[1] - glow_radius))
pygame.draw.circle(surface, color, center, radius)
# Helper function to draw a neon glow rectangle
def draw_neon_rect(surface, color, rect, glow_layers=8):
for i in range(glow_layers, 0, -1):
alpha = max(10, int(255 * (i / glow_layers) * 0.5))
glow_color = (*color, alpha)
temp_rect = rect.inflate(i * 2, i * 2)
temp_surface = pygame.Surface((temp_rect.width, temp_rect.height), pygame.SRCALPHA)
pygame.draw.rect(temp_surface, glow_color, (0, 0, temp_rect.width, temp_rect.height), border_radius=4)
surface.blit(temp_surface, temp_rect.topleft)
pygame.draw.rect(surface, color, rect, border_radius=4)
# Particle class: updated using dt, with fading effect
class Particle:
def __init__(self, x, y, angle, speed, lifetime, color, size):
self.x = x
self.y = y
self.angle = angle # in radians
self.speed = speed # pixels per second
self.lifetime = lifetime # seconds
self.color = color
self.size = size # initial size
def update(self, dt):
# Move particle using dt
self.x += math.cos(self.angle) * self.speed * dt
self.y += math.sin(self.angle) * self.speed * dt
self.lifetime -= dt
def draw(self, surface):
if self.lifetime > 0:
# Compute fade effect: size and brightness fade with remaining lifetime
fade = max(0, self.lifetime)
current_size = max(1, int(self.size * (fade)))
# Draw with the neon glow effect.
draw_neon_circle(surface, self.color, (int(self.x), int(self.y)), current_size, glow_layers=4)
# Particle system to manage all particles
class ParticleSystem:
def __init__(self):
self.particles = []
def add_explosion(self, x, y, count, base_speed, lifetime, color, size):
for _ in range(count):
angle = random.uniform(0, 2 * math.pi)
speed = random.uniform(0.5 * base_speed, base_speed)
# lifetime is given in seconds; each particle will have a slightly variable lifetime
part_lifetime = random.uniform(0.5 * lifetime, lifetime)
self.particles.append(Particle(x, y, angle, speed, part_lifetime, color, size))
def update(self, dt):
for p in self.particles:
p.update(dt)
# Remove dead particles
self.particles = [p for p in self.particles if p.lifetime > 0]
def draw(self, surface):
for p in self.particles:
p.draw(surface)
# Ball class: uses dt in its movement and adds a neon glow.
class Ball:
def __init__(self, x, y, radius=10, color=NEON_BLUE):
self.x = x
self.y = y
self.radius = radius
self.color = color
self.vx = random.choice([-200, 200]) # pixels per second
self.vy = random.choice([-200, 200]) # pixels per second
def update(self, dt):
self.x += self.vx * dt
self.y += self.vy * dt
# Bounce off the walls
if self.x - self.radius <= 0 or self.x + self.radius >= WIDTH:
self.vx *= -1
self.x = max(self.radius, min(WIDTH - self.radius, self.x))
if self.y - self.radius <= 0 or self.y + self.radius >= HEIGHT:
self.vy *= -1
self.y = max(self.radius, min(HEIGHT - self.radius, self.y))
def draw(self, surface):
draw_neon_circle(surface, self.color, (int(self.x), int(self.y)), self.radius)
def get_rect(self):
return pygame.Rect(self.x - self.radius, self.y - self.radius,
self.radius * 2, self.radius * 2)
# Block class with dt-independent health and neon visuals.
class Block:
def __init__(self, x, y, width=80, height=30, health=3, color=NEON_PINK):
self.rect = pygame.Rect(x, y, width, height)
self.max_health = health
self.health = health
self.color = color
def draw(self, surface):
intensity = self.health / self.max_health
mod_color = (int(self.color[0] * intensity),
int(self.color[1] * intensity),
int(self.color[2] * intensity))
draw_neon_rect(surface, mod_color, self.rect)
def hit(self, damage):
self.health -= damage
if self.health < 0:
self.health = 0
def is_destroyed(self):
return self.health <= 0
def main():
global money
clock = pygame.time.Clock()
particle_system = ParticleSystem()
running = True
# Create a neon ball at the center.
ball = Ball(WIDTH // 2, HEIGHT // 2)
# Create blocks in a grid layout.
blocks = []
rows, cols = 3, 7
padding = 10
block_width = (WIDTH - (cols + 1) * padding) // cols
block_height = 30
for row in range(rows):
for col in range(cols):
x = padding + col * (block_width + padding)
y = padding + row * (block_height + padding)
blocks.append(Block(x, y, block_width, block_height, health=3, color=NEON_PINK))
font = pygame.font.SysFont("Arial", 24)
while running:
# Calculate delta time in seconds.
dt = clock.tick() / 1000.0
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# Update game objects using dt.
ball.update(dt)
particle_system.update(dt)
# Collision check between ball and blocks.
ball_rect = ball.get_rect()
for block in blocks[:]:
if ball_rect.colliderect(block.rect):
# Reflect the ball vertically.
ball.vy *= -1
# Add particle explosion at collision point.
collision_x = ball.x
collision_y = ball.y
particle_system.add_explosion(collision_x, collision_y, count=20,
base_speed=150, lifetime=0.5,
color=NEON_GREEN, size=4)
# Damage the block.
block.hit(1)
# When block is destroyed, add additional particle explosion.
if block.is_destroyed():
money += 10
particle_system.add_explosion(block.rect.centerx, block.rect.centery,
count=40, base_speed=200, lifetime=0.7,
color=NEON_PINK, size=6)
blocks.remove(block)
# Stop checking after one collision per frame.
break
# Draw everything.
SCREEN.fill(BLACK)
ball.draw(SCREEN)
for block in blocks:
block.draw(SCREEN)
particle_system.draw(SCREEN)
money_text = font.render(f"Money: ${money}", True, NEON_GREEN)
SCREEN.blit(money_text, (10, HEIGHT - 40))
pygame.display.flip()
pygame.quit()
if __name__ == "__main__":
main()