Twinkling Stars  •  Cross Training  •  09/25/2026
TNT — Processing Cross Training  •  Henry’s Ghost Saga

👻 ⭐ Twinkling Stars:
Three Languages, One Sketch

The same Processing sketch — identical logic, identical vocabulary — in JavaScript (p5.js), Java Processing, and Python Processing. Five big ideas that make it work in all three.

The Ideas

Five Concepts at Work in Every Version

These five design decisions appear in all three sketches. Find each one in the code panels below — the pattern is identical; only the language syntax differs.

🏷️
Named Constants — No Magic Numbers

A magic number is a raw value embedded in code with no label — createCanvas(400, 400) tells you nothing about why 400 was chosen. A named constant fixes that: var CW = 400; createCanvas(CW, CH) makes the intent explicit and makes changing the value a one-line edit.

Every configurable value in the sketch gets a name: NUM_STARS, TWINKLE_PERIOD, SKY_H, STAR_HUE. Each language enforces this differently:

var at top final keyword ALL_CAPS convention
🎨
HSB Color Mode

colorMode(HSB, 360, 100, 100, 100) tells Processing to interpret every stroke(), fill(), and background() call as Hue (0–360), Saturation (0–100), Brightness (0–100), Alpha (0–100).

The sky: H=277 (purple on the wheel), S=85 (vivid), B=52 (dark). Stars share H=60 (yellow) but get random saturation, so some are warm-white and others vivid gold. After colorMode() is called, the new interpretation applies globally for the rest of the sketch — in all three languages.

identical in all three
📦
Same Data, Three Containers

100 stars, each with 7 properties: x, y, sw, h, s, b, offset. The data model is identical. The container syntax is not:

JS: stars.push({ x: random(CW), … }) Python: star = {'x': random(CW), …} Java: stars[i] = new Star(random(CW), …)

Java is the only version that requires a formal class definition for Star. Python and JavaScript leave structure optional. That difference is itself a lesson in what each language values.

object literal Star class dict literal
🖱️
Mouse Input — Event Hooks

mousePressed() is a Processing lifecycle function: it is called automatically once each time the user clicks the canvas. You never call it yourself — Processing does, behind the scenes. mouseX and mouseY are Processing globals that update every frame to reflect the cursor position.

The guard clause — if (mouseX >= 0 && mouseX <= CW …) — restricts the response to clicks that land inside the canvas boundary, ignoring any click on the browser chrome. The toggle itself is one line:

JS/Java: shouldTwinkle = !shouldTwinkle Python: should_twinkle = not should_twinkle
identical structure
〰️
Sinusoidal Twinkling

Each star’s alpha (opacity) oscillates using a sine wave:

alpha = A · sin(B · (frameCount + offset)) + C

A = 35 (half the swing: (100−30)/2), C = 65 (center: (100+30)/2), B ≈ 0.0698 (TWO_PI / 90). The key is the per-star phase offset (0–89 frames): adding a unique offset to frameCount before evaluating the sine places each star at a different point in the cycle. Without it, all 100 stars would dim and brighten simultaneously. With it, they sparkle independently — even though every star uses the exact same formula.

identical math in all three

All Three Sketches, Side by Side

Yellow paper = JavaScript  •  Blue paper = Java  •  Green paper = Python. Each panel scrolls independently.

JavaScript henrysGhostTwinklingSketch.js
    Java TwinkleStarJavaSketch.pde
      Python twinkleStarSketch.py

        What’s the Same — and What’s Different

        Scroll through all three panels and look for the same variable names, the same arithmetic, the same function names. The Processing vocabulary — background(), stroke(), colorMode(), sin(), TWO_PI, frameCount, mousePressed() — is the same in all three. What changes is only the host language’s syntax: how you declare a variable, how you access a field, and whether the language enforces a formal class definition. The algorithm is language-independent.

        • JS: star.offset  |  Java: star.offset  |  Python: star['offset']
        • JS: createCanvas(CW, CH)  |  Java / Python: size(CW, CH) — but Java requires a literal, not a variable
        • Java only: requires a class Star definition — JS and Python use plain objects/dicts
        • JS/Java: !shouldTwinkle  |  Python: not should_twinkle