Update particle.py
This commit is contained in:
parent
4e2e199297
commit
2058989c85
165
particle.py
165
particle.py
@ -0,0 +1,165 @@
|
|||||||
|
import pygame
|
||||||
|
import random
|
||||||
|
import math
|
||||||
|
|
||||||
|
class Particle:
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
pos,
|
||||||
|
vel=(0, 0),
|
||||||
|
acceleration=(0, 0),
|
||||||
|
lifetime=2.0, # seconds the particle lives
|
||||||
|
decay_rate=1, # how fast the lifetime decreases
|
||||||
|
color=(255, 255, 255),
|
||||||
|
size=5,
|
||||||
|
size_decay=0, # rate at which the size decreases
|
||||||
|
glow=False,
|
||||||
|
glow_intensity=0, # multiplier for glow radius
|
||||||
|
friction=0, # slows down velocity over time
|
||||||
|
gravity=0, # constant acceleration downward
|
||||||
|
bounce=False,
|
||||||
|
bounce_damping=0.5, # energy loss when bouncing off boundaries
|
||||||
|
random_spread=0, # randomness added to velocity each update
|
||||||
|
spin=0, # current rotation (unused for circles)
|
||||||
|
spin_rate=0, # rotation speed
|
||||||
|
spin_decay=0, # how spin_rate slows down
|
||||||
|
trail=False,
|
||||||
|
trail_length=10, # how many previous positions to store
|
||||||
|
fade=False, # if True, the particle will fade (alpha decreases)
|
||||||
|
shape='circle' # could be 'circle' or 'square'
|
||||||
|
):
|
||||||
|
# Position, velocity, and acceleration are stored as vectors.
|
||||||
|
self.pos = pygame.math.Vector2(pos)
|
||||||
|
self.vel = pygame.math.Vector2(vel)
|
||||||
|
self.acceleration = pygame.math.Vector2(acceleration)
|
||||||
|
|
||||||
|
# Lifetime and decay
|
||||||
|
self.lifetime = lifetime
|
||||||
|
self.initial_lifetime = lifetime
|
||||||
|
self.decay_rate = decay_rate
|
||||||
|
|
||||||
|
# Appearance settings
|
||||||
|
self.color = color
|
||||||
|
self.size = size
|
||||||
|
self.initial_size = size
|
||||||
|
self.size_decay = size_decay
|
||||||
|
self.fade = fade
|
||||||
|
self.alpha = 255
|
||||||
|
|
||||||
|
# Effects options
|
||||||
|
self.glow = glow
|
||||||
|
self.glow_intensity = glow_intensity
|
||||||
|
self.friction = friction
|
||||||
|
self.gravity = gravity
|
||||||
|
self.bounce = bounce
|
||||||
|
self.bounce_damping = bounce_damping
|
||||||
|
self.random_spread = random_spread
|
||||||
|
|
||||||
|
# Spin (if using rotated images or shapes)
|
||||||
|
self.spin = spin
|
||||||
|
self.spin_rate = spin_rate
|
||||||
|
self.spin_decay = spin_decay
|
||||||
|
|
||||||
|
# Trail settings: stores previous positions to create a trailing effect
|
||||||
|
self.trail = trail
|
||||||
|
self.trail_length = trail_length
|
||||||
|
self.positions = [self.pos.copy()] if trail else []
|
||||||
|
|
||||||
|
# Shape of the particle ('circle' or 'square')
|
||||||
|
self.shape = shape
|
||||||
|
|
||||||
|
def update(self, dt, screen_rect):
|
||||||
|
"""
|
||||||
|
dt: Delta time in seconds.
|
||||||
|
screen_rect: The rectangle representing screen boundaries (for bounce).
|
||||||
|
"""
|
||||||
|
# Decrease lifetime
|
||||||
|
self.lifetime -= self.decay_rate * dt
|
||||||
|
if self.lifetime < 0:
|
||||||
|
self.lifetime = 0
|
||||||
|
|
||||||
|
# Add random variation to velocity if enabled.
|
||||||
|
if self.random_spread:
|
||||||
|
self.vel.x += random.uniform(-self.random_spread, self.random_spread) * dt
|
||||||
|
self.vel.y += random.uniform(-self.random_spread, self.random_spread) * dt
|
||||||
|
|
||||||
|
# Apply gravity (as an extra acceleration on the y-axis)
|
||||||
|
self.acceleration.y += self.gravity
|
||||||
|
|
||||||
|
# Update velocity using acceleration.
|
||||||
|
self.vel += self.acceleration * dt
|
||||||
|
|
||||||
|
# Apply friction to slow the particle over time.
|
||||||
|
self.vel *= (1 - self.friction * dt)
|
||||||
|
|
||||||
|
# Update the position based on velocity.
|
||||||
|
self.pos += self.vel * dt
|
||||||
|
|
||||||
|
# Bounce off screen edges if enabled.
|
||||||
|
if self.bounce:
|
||||||
|
if self.pos.x - self.size < screen_rect.left or self.pos.x + self.size > screen_rect.right:
|
||||||
|
self.vel.x = -self.vel.x * self.bounce_damping
|
||||||
|
if self.pos.x - self.size < screen_rect.left:
|
||||||
|
self.pos.x = screen_rect.left + self.size
|
||||||
|
elif self.pos.x + self.size > screen_rect.right:
|
||||||
|
self.pos.x = screen_rect.right - self.size
|
||||||
|
if self.pos.y - self.size < screen_rect.top or self.pos.y + self.size > screen_rect.bottom:
|
||||||
|
self.vel.y = -self.vel.y * self.bounce_damping
|
||||||
|
if self.pos.y - self.size < screen_rect.top:
|
||||||
|
self.pos.y = screen_rect.top + self.size
|
||||||
|
elif self.pos.y + self.size > screen_rect.bottom:
|
||||||
|
self.pos.y = screen_rect.bottom - self.size
|
||||||
|
|
||||||
|
# Update spin
|
||||||
|
self.spin += self.spin_rate * dt
|
||||||
|
self.spin_rate *= (1 - self.spin_decay * dt)
|
||||||
|
|
||||||
|
# Decrease size if size_decay is set.
|
||||||
|
if self.size_decay:
|
||||||
|
self.size = max(0, self.size - self.size_decay * dt)
|
||||||
|
|
||||||
|
# Fade out by decreasing alpha based on lifetime.
|
||||||
|
if self.fade:
|
||||||
|
self.alpha = int(255 * (self.lifetime / self.initial_lifetime))
|
||||||
|
if self.alpha < 0:
|
||||||
|
self.alpha = 0
|
||||||
|
|
||||||
|
# Update trail history.
|
||||||
|
if self.trail:
|
||||||
|
self.positions.append(self.pos.copy())
|
||||||
|
if len(self.positions) > self.trail_length:
|
||||||
|
self.positions.pop(0)
|
||||||
|
|
||||||
|
def draw(self, surface):
|
||||||
|
# Set drawing color with alpha if fading.
|
||||||
|
if self.fade:
|
||||||
|
draw_color = (*self.color, self.alpha)
|
||||||
|
else:
|
||||||
|
draw_color = self.color
|
||||||
|
|
||||||
|
# Draw the particle's trail if enabled.
|
||||||
|
if self.trail and len(self.positions) > 1:
|
||||||
|
for i in range(1, len(self.positions)):
|
||||||
|
start = self.positions[i - 1]
|
||||||
|
end = self.positions[i]
|
||||||
|
pygame.draw.line(surface, draw_color, start, end, int(self.size))
|
||||||
|
|
||||||
|
# Draw glow effect if enabled.
|
||||||
|
if self.glow:
|
||||||
|
glow_radius = int(self.size * (1 + self.glow_intensity))
|
||||||
|
glow_color = (*self.color, self.alpha) if self.fade else self.color
|
||||||
|
glow_surface = pygame.Surface((glow_radius * 2, glow_radius * 2), pygame.SRCALPHA)
|
||||||
|
pygame.draw.circle(glow_surface, glow_color, (glow_radius, glow_radius), glow_radius)
|
||||||
|
surface.blit(glow_surface, (self.pos.x - glow_radius, self.pos.y - glow_radius), special_flags=pygame.BLEND_ADD)
|
||||||
|
|
||||||
|
# Draw the particle shape.
|
||||||
|
if self.shape == 'circle':
|
||||||
|
pygame.draw.circle(surface, draw_color, (int(self.pos.x), int(self.pos.y)), int(self.size))
|
||||||
|
elif self.shape == 'square':
|
||||||
|
rect = pygame.Rect(self.pos.x - self.size, self.pos.y - self.size, self.size * 2, self.size * 2)
|
||||||
|
pygame.draw.rect(surface, draw_color, rect)
|
||||||
|
# Additional shapes (e.g., triangles, rotated images) can be added here.
|
||||||
|
|
||||||
|
def is_dead(self):
|
||||||
|
"""Return True if the particle should be removed."""
|
||||||
|
return self.lifetime <= 0 or self.size <= 0
|
Loading…
Reference in New Issue
Block a user