2026. június 29., hétfő

Részecskeszimuláció


Az alábbiakban egy interaktív valós idejű részecskeszimulációt és fraktálgenerátort láthatsz, amely gravitációs vonzással, örvénylő erőkkel és dinamikus színátmenetekkel dolgozik.
---------------
import pygame
import math
import random

# Inicializálás
pygame.init()
WIDTH, HEIGHT = 1280, 720
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Procedurális Részecskeszimuláció és Erőtér")
clock = pygame.time.Clock()

# Színpaletta generálás (idővel változó)
def get_color(t):
    r = int((math.sin(t * 0.03) + 1) * 127)
    g = int((math.sin(t * 0.05) + 1) * 127)
    b = int((math.sin(t * 0.07) + 1) * 127)
    return (r, g, b)

# Részecske osztály
class Particle:
    def __init__(self):
        self.x = random.randint(0, WIDTH)
        self.y = random.randint(0, HEIGHT)
        self.vx = random.uniform(-1, 1)
        self.vy = random.uniform(-1, 1)
        self.size = random.uniform(1, 4)
        self.color = (255, 255, 255)
        self.life = random.uniform(50, 250)
        self.max_life = self.life

    def update(self, mx, my):
        # Erőtér számítás (vektormező - Perlin zaj jellegű örvény)
        dx = mx - self.x
        dy = my - self.y
        dist = math.hypot(dx, dy)
        
        if dist > 50:
            # Gravitációs vonzás a kurzor felé
            self.vx += (dx / dist) * 0.5
            self.vy += (dy / dist) * 0.5
        else:
            # Kaotikus taszítás, ha túl közel van
            self.vx -= (dx / dist) * 2
            self.vy -= (dy / dist) * 2

        # Örvény (Curl) hatás
        angle = math.atan2(dy, dx)
        self.vx += math.sin(angle) * 0.5
        self.vy += math.cos(angle) * 0.5

        # Súrlódás / Ellenállás
        self.vx *= 0.93
        self.vy *= 0.93

        # Pozíció frissítése
        self.x += self.vx
        self.y += self.vy

        # Élettartam csökkentése
        self.life -= 1.5

    def draw(self, surface):
        alpha = int((self.life / self.max_life) * 255)
        if alpha < 0: alpha = 0
        
        # Átlátszó (alpha) felület létrehozása a ragyogáshoz
        s = pygame.Surface((int(self.size*3), int(self.size*3)), pygame.SRCALPHA)
        pygame.draw.circle(s, (*self.color, alpha), (int(self.size*1.5), int(self.size*1.5)), int(self.size))
        surface.blit(s, (self.x - self.size*1.5, self.y - self.size*1.5))

# Fő ciklus
particles = []
time_passed = 0
running = True

while running:
    # Háttér törlése minimális átlátszósággal a mozgás elmosásához (Motion Blur)
    s = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
    s.fill((10, 5, 20, 20))
    screen.blit(s, (0, 0))

    # Eseménykezelés
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                # Robbantás space-re
                for _ in range(100):
                    p = Particle()
                    p.x, p.y = pygame.mouse.get_pos()
                    particles.append(p)

    # Egér pozíció
    mx, my = pygame.mouse.get_pos()

    # Új részecskék generálása folyamatosan
    if len(particles) < 800:
        for _ in range(10):
            particles.append(Particle())

    # Részecskék frissítése és rajzolása
    for p in particles[:]:
        p.color = get_color(time_passed)
        p.update(mx, my)
        p.draw(screen)
        
        # Újraélesztés vagy törlés
        if p.life <= 0:
            particles.remove(p)

    # Dinamikus fraktál / visszacsatolási effektus a képernyő közepén
    time_passed += 1
    
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
-----------------

 

Nincsenek megjegyzések:

Megjegyzés küldése