Skip to content

Progress Bar (BASIC)

Horizontal progress bar with colour thresholds — blue through yellow, red, to white. Useful for health, temperature, or timers.

Taught in BASIC Game 1, Unit 1 barprogresscolourtemperaturebasicdisplay

Overview

A 28-cell horizontal bar that fills proportionally to a value, changing colour at thresholds: blue (cold/low) → yellow (warm/medium) → red (hot/high) → white (maximum). Uses PRINT AT with PAPER colours. Ideal for temperature bars, health bars, timer displays, or any value shown spatially rather than numerically.

True-zero behaviour

The cell count is INT(v*28/vm) clamped to 0-28. When v = 0 the bar is entirely empty — no cells lit. When v = vm (maximum), all 28 cells are lit. When v > vm, the bar saturates at 28. Negative values clamp to 0.

Earlier versions of this pattern used h = INT(v*28/vm) + 1 which always lit at least one cell even at zero. That hid the difference between "empty" and "barely above empty" — fixed in the current version so v=0 visibly means empty.

Underlying mechanism

PRINT AT with PAPER writes a space character (which is "blank" in display memory) plus an attribute byte (which sets the cell's PAPER colour). Because each character cell is 8×8 pixels, the bar is 28 cells × 8 = 224 pixels wide, a whole pixel band tall. The block of solid colour comes from the attribute system, not from drawing pixels.

Code

  10 REM Progress bar
  20 REM Pattern: reusable across games
  30 REM
  40 REM Usage:
  50 REM   LET v=75: LET vm=100: GO SUB 2200
  60 REM
  70 REM Parameters:
  80 REM   v  = current value
  90 REM   vm = maximum value
 100 REM
 110 REM Draws a 28-cell horizontal bar at row br
 120 REM Colour shifts: blue -> yellow -> red -> white
 130 REM Set br before first call (default row 15)
 140 REM
 150 REM Example: temperature bar
 160 REM   LET br=15: LET v=100-ABS(guess-target)
 170 REM   LET vm=100: GO SUB 2200
 180 REM
2200 REM === Progress bar ===
2210 LET h=INT (v*28/vm)
2220 IF h>28 THEN LET h=28
2230 IF h<0 THEN LET h=0
2240 FOR i=1 TO 28
2250 IF i>h THEN PRINT AT br,1+i; PAPER 0;" ": GO TO 2300
2260 IF i<=9 THEN PRINT AT br,1+i; PAPER 1;" "
2270 IF i>9 AND i<=18 THEN PRINT AT br,1+i; PAPER 6;" "
2280 IF i>18 AND i<=24 THEN PRINT AT br,1+i; PAPER 2;" "
2290 IF i>24 THEN PRINT AT br,1+i; PAPER 7;" "
2300 NEXT i
2310 RETURN

Trade-offs

AspectDetail
Speed28 PRINT AT calls maximum — fast enough for per-guess updates
Memory~12 lines of code
LimitationFixed at 28 cells wide. Adjust thresholds for different ranges
VisualCharacter-cell resolution (8px blocks). Chunky but readable

When to use: Any value that benefits from spatial display — health, distance, time remaining.

When to avoid: Values that change every frame — 28 PRINT AT calls per frame is too slow for real-time.

Patterns: Seven-Segment Digits, Attribute Writing (assembly)

Vault: ULA — attribute memory layout | ZX Spectrum