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

Részecskeszimulációt (gravitációs vonzás és taszítás)

Vizuálisan összetett interaktív részecskeszimulációt (gravitációs vonzás és taszítás) készítettem el, amely a képernyőn lévő folyadék- és fényhatásokat modellezi.
-------------
import pygame
import sys
import math
import random

# Inicializálás
pygame.init()

# Képernyő beállítások (teljes képernyő vagy adott felbontás)
WIDTH, HEIGHT = 1000, 750
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Komplex Pygame Grafikai Szimuláció")
clock = pygame.time.Clock()

# Színpaletta
BLACK = (10, 10, 15)
PARTICLE_COLOR = (0, 255, 200)

# Részecske osztály fizikai szimulációhoz
class Particle:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.vx = random.uniform(-2, 2)
        self.vy = random.uniform(-2, 2)
        self.radius = random.randint(2, 5)
        self.color = (
            random.randint(50, 255),
            random.randint(50, 150),
            random.randint(200, 255)
        )

    def update(self, mouse_pos):
        # Egér gravitáció (vonzás)
        dx = mouse_pos[0] - self.x
        dy = mouse_pos[1] - self.y
        dist = math.hypot(dx, dy)
        
        if dist > 20:
            force = 5000 / (dist ** 2 + 1) # Gravitációs képlet: $F = \frac{G \cdot m_1 \cdot m_2}{r^2}$
            self.vx += force * (dx / dist)
            self.vy += force * (dy / dist)

        # Súrlódás (energiavesztés)
        self.vx *= 0.97
        self.vy *= 0.97

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

        # Ütközés a falakkal
        if self.x - self.radius < 0 or self.x + self.radius > WIDTH:
            self.vx *= -1
            self.x = max(self.radius, min(self.x, WIDTH - self.radius))
        if self.y - self.radius < 0 or self.y + self.radius > HEIGHT:
            self.vy *= -1
            self.y = max(self.radius, min(self.y, HEIGHT - self.radius))

    def draw(self, surface):
        pygame.draw.circle(surface, self.color, (int(self.x), int(self.y)), self.radius)

# Szimuláció inicializálása
particles = [Particle(random.randint(100, WIDTH-100), random.randint(100, HEIGHT-100)) for _ in range(600)]

# Fő ciklus
running = True
trail_surface = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA) # Fény- és nyomeffektushoz

while running:
    # 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:
                # Új részecskék generálása szóközre
                particles.extend([Particle(WIDTH/2, HEIGHT/2) for _ in range(100)])
            elif event.key == pygame.K_c:
                # Törlés
                particles.clear()

    mouse_pos = pygame.mouse.get_pos()

    # Háttér rajzolása "halványító" felülettel a szép fény- és mozgásnyomokért (trail effect)
    trail_surface.fill((BLACK[0], BLACK[1], BLACK[2], 20)) 
    screen.blit(trail_surface, (0, 0))

    # Részecskék frissítése és kirajzolása
    for p in particles:
        p.update(mouse_pos)
        p.draw(screen)
        
        # Láncolt vonalak rajzolása a közeli részecskék között (háló hatás)
        for other in particles:
            if p != other:
                dx = p.x - other.x
                dy = p.y - other.y
                if math.hypot(dx, dy) < 35: # Csak a közeli részecskék közt
                    alpha = int(255 - (math.hypot(dx, dy) * 7))
                    line_color = (*p.color[:3], max(0, min(alpha, 255)))
                    pygame.draw.line(screen, line_color, (p.x, p.y), (other.x, other.y), 1)

    # FPS kiírása
    fps = int(clock.get_fps())
    font = pygame.font.SysFont(None, 24)
    fps_text = font.render(f'FPS: {fps} | Particles: {len(particles)}', True, (255, 255, 255))
    screen.blit(fps_text, (10, 10))

    pygame.display.flip()
    clock.tick(60)

pygame.quit()
sys.exit()
----------


Nincsenek megjegyzések:

Megjegyzés küldése