Code:
'====================================================
' PARALLAX AUTO-SCROLL DEMO v2 - 3 minute cycle
' - blinking stars (sin-driven alpha twinkle)
' - moon drawn with draw ellipse + glow halo
' - mountain silhouettes from sin() contours
' - treeline & trees with varied heights
'====================================================
set window "Parallax Demo", 384, 224, false, 2
set redraw off
constant SCROLL_SPEED = 90.0 ' camera pixels per frame
constant WORLD_W = 1535.0 ' one-way travel distance
visible CYCLE = 4 * WORLD_W / SCROLL_SPEED ' = 180 seconds
constant GROUND_Y = 180
visible cam = [] ; cam.x = 0
' --- Build foreground trees with VARIED sizes (once, at startup) ---
' Deterministic per run. Add "randomize time()" above for a new forest each run.
visible trees = [] ; trees.num = 0
for i = 0 to 9
trees[i] = []
trees[i].x = i * 100 + rnd(0, 60) ' scattered across world 0..960
trees[i].w = 14 + rnd(0, 16) ' width varies 14-30
trees[i].h = 28 + rnd(0, 38) ' height varies 28-66
next
trees.num = 10
' ================= MAIN LOOP =================
do
' --- AUTO-SCROLL CAMERA (triangle wave / ping-pong) ---
' phase 0..0.5 : camera moves RIGHT (0 -> WORLD_W)
' phase 0.5..1 : camera moves LEFT (WORLD_W -> 0)
t = (clock() / 1000) % CYCLE
phase = t / CYCLE
if phase < 0.5 then
cam.x = WORLD_W * (phase * 2)
else
cam.x = WORLD_W * (2 - phase * 2)
endif
' ==================== DRAWING ====================
' LAYER 0: Night sky (fixed, depth 0 - never moves)
set color 10, 10, 30; draw rect 0, 0, 384, 224, true
' LAYER 1: BLINKING STARS (depth 0.5, wrapped with %)
' Alpha oscillates via sin(); each star gets its own phase offset
' so they twinkle independently instead of pulsing in sync
tw = clock() / 500
for s = 0 to 5
alpha = int(128 + 127 * sin(tw + s * 1.7))
set color 255, 255, 255, alpha
sx = int((150 + s * 73 - cam.x * 0.5) % 440)
sy = 14 + (s * 29) % 70 ' deterministic y scatter
sz = 2 + s % 2 ' sizes alternate 2px / 3px
draw rect sx, sy, sz, sz, true
next
set color 255, 255, 255, 255 ' restore full opacity
' LAYER 2: MOON with soft glow (depth 0.1, now draw ellipse)
moonX = int(300 - cam.x * 0.1)
set color 200, 200, 255, 40
draw ellipse moonX, 60, 26, 26, true ' faint glow halo
set color 200, 200, 255
draw ellipse moonX, 60, 16, 16, true ' moon body
set color 170, 170, 225
draw ellipse moonX - 5, 56, 4, 4, true ' craters
draw ellipse moonX + 6, 64, 3, 3, true
' LAYER 3: MOUNTAIN SILHOUETTES via sin() contours (depth 0.2)
' made of TWO blended sine frequencies = natural mountain outline
set color 40, 40, 60
for mx = 0 to 384
wx = mx + cam.x * 0.2 ' world x under this column
mh = 70 + 45 * sin(wx / 45) + 18 * sin(wx / 19)
draw rect mx, int(GROUND_Y - mh), 7, int(mh), true
next
' LAYER 4: TREELINE with varying canopy heights (depth 0.5)
' Same slicing trick, higher frequencies = bumpy treetops
set color 30, 50, 30
for tx = 0 to 384
wx = tx + cam.x * 0.5
th = 28 + 14 * sin(wx / 23) + 9 * sin(wx / 11 + 1)
draw rect tx, int(GROUND_Y - th), 11, int(th), true
next
' LAYER 5: FOREGROUND TREES, varied sizes (depth 0.8)
' Precomputed table + tiled copies every 1000px = infinite forest
set color 20, 30, 20
for j = -1 to 1
for i = 0 to trees.num - 1
fx = int(trees[i].x + j * 1000 - cam.x * 0.8)
if fx > -80 and fx < 460 then
draw rect fx, GROUND_Y - trees[i].h, trees[i].w, trees[i].h, true
endif
next
next
' LAYER 6: Ground = player layer (depth 1.0 - "real" world)
set color 60, 40, 20; draw rect int(-cam.x), GROUND_Y, 1500, 50, true
' cycle timer proof
set color 255, 255, 255
set caret 8, 8
'wln "Cycle : " + str(int(t)) + " / " + str(int(CYCLE)) + " sec"
wln "cam.x : " + str(int(cam.x))
wln "ESC to quit"
redraw
fwait 60
until keydown(KEY_ESCAPE)