aliens.py

Created by schraf

Created on May 31, 2026

3.25 KB


# Alien Fireworks - K Moerman 2026
  # Pour calculatrice NumWorks (320x222, module kandinsky)
  # Inspire de Simone Conradi, traduit du BBC Basic / QuickBASIC

import kandinsky
import math
import random

# --- Constantes ---
W = 160          # demi-largeur  (ecran 320)
H = 111          # demi-hauteur  (ecran 222)
NITER   = 400    # iterations par jeu de parametres
NPARAM  = 180    # nombre de valeurs de a et b (0..2*PI)
NFADE   = 100    # pixels effaces a chaque fondu

PI2 = 2 * math.pi
stepab = PI2 / NPARAM

# --- Palette cyclique de 6 teintes de base (version claire) ---
BASE_COLORS = [
    (80,  80,  180),   # bleu-violet
    (80,  180, 180),   # cyan
    (80,  180, 80),    # vert
    (180, 180, 80),    # jaune
    (180, 80,  80),    # rouge
    (180, 80,  180),   # magenta
]
NCOLORS = len(BASE_COLORS)

def lerp_color(c0, c1, t):
    """Interpolation lineaire entre deux couleurs."""
    return (
        int(c0[0] + (c1[0] - c0[0]) * t),
        int(c0[1] + (c1[1] - c0[1]) * t),
        int(c0[2] + (c1[2] - c0[2]) * t),
    )

def fade_pixel():
    """Assombrit un pixel aleatoire (effet de fondu progressif)."""
    px = random.randint(0, 319)
    py = random.randint(0, 221)
    c  = kandinsky.get_pixel(px, py)
    r, g, b = c[0], c[1], c[2]
    # reduire la luminosite d'environ 15%
    r = max(0, r - 100)
    g = max(0, g - 100)
    b = max(0, b - 100)
    if r > 4 or g > 4 or b > 4:
        kandinsky.fill_rect(px, py, 2, 2, (r, g, b))

def plot(x, y, color):
    """Convertit les coordonnees [-1,1] en pixels et trace."""
    px = int(W + x * W)
    py = int(H - y * H)        # axe Y inverse
    if 0 <= px <= 319 and 0 <= py <= 221:
        kandinsky.fill_rect(px, py, 2, 2, color)

# --- Fond noir ---
kandinsky.fill_rect(0, 0, 320, 222, (0, ) * 3)

# --- Variables d'etat ---
x = 0.0
y = 0.0
color_phase = 0.0          # position continue dans la palette
color_seq   = [BASE_COLORS[i % NCOLORS] for i in range(7)]

a = PI2
while True:
    b = 0.0
    while b <= PI2:

        # --- Fondu : effacer NFADE pixels aleatoires ---
        for _ in range(NFADE):
            fade_pixel()

        # --- Nouvelle couleur par interpolation dans la palette ---
        color_phase += 0.15
        if color_phase >= NCOLORS:
            color_phase -= NCOLORS
            # renouveler la sequence de couleurs
            color_seq[0] = color_seq[6]
            for i in range(1, 7):
                color_seq[i] = BASE_COLORS[random.randint(0, NCOLORS - 1)]

        ci  = int(color_phase) % NCOLORS
        t   = color_phase - int(color_phase)
        base_col = lerp_color(color_seq[ci], color_seq[(ci + 1) % NCOLORS], t)

        # --- Iterations de l'attracteur ---
        for _ in range(NITER):
            xnew = 1.3*math.sin(x * x - y * y + a)
            y    = math.sin(2 * x * y + b)
            x    = xnew

            # variation de luminosite aleatoire (+/- 40)
            dr = random.randint(-40, 40)
            col = (
                max(0, min(255, base_col[0] + dr)),
                max(0, min(255, base_col[1] + dr)),
                max(0, min(255, base_col[2] + dr)),
            )
            plot(x, y, col)

        # swap x,y pour la prochaine iteration (comme l'original)
        x, y = y, x

        b += stepab

    a -= stepab
    if a < 0:
        a = PI2

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.