One-a-Day: Amiga Ball Bounce


The Commodore Amiga computer had a famous ‘bouncing ball’ demonstration program, a checkered bouncing ball. It was a bit different than this, but this is certainly reminiscent of it.

We love the Amiga demo so much that we created a special checkered ball primitive, AMIGABALL, and a second ‘oid’ primitive, AMIGABALLOID, which is used to create the ‘compressed’ ball.

Rather than turning the turtle into a ball (one method), this method ‘cleans’ the ‘turtle track’ after rendering each frame of the animation (which we wait for using the NEXTFRAME primitive).

The background voxel is actually an ‘inverted’ voxel, a voxel that is created using a negative size value. Due to the nature of OpenGL, only the insides of negative voxels are visible, which is why we can see inside it, and not see the face directly in front of us. Because we clean the ball each frame, we need to use a HATCHLING to create and hold the voxel in place. The hatchling just sleeps while the program runs.

The CAM: prefix directs the current view turtle (usually ‘Snappy’) to do things. You could also use SNAPPY: in this case but CAM: is shorter.

DOUNTIL PENCOLOR != FILLCOLOR [RANDFC] ensures that the ball has two different colors. The Amigaball(oid) uses both the pen and the fill colors in its construction, the only 3D primitive to do so.

To stop the ball from bouncing, press the Escape key.

TO bounce
  reset fs
  penup lower 120 slideright 120 fd 120
  
  hatch [randomfillcolor voxel -240 forever [wait 10]]
  ;create the cube, using a hatchling so it persists
  
  cam:run [oup 10 ra 5]
  
  home
  setspheroidaxis 1
  ;stretch the spheroid on the vertical, default is horizontal
  dn 90 rr 10
  randpc dountil pencolor != fillcolor [randfc]
  ;set random pen and fill colors
  
  forever [
    
    repeat 14 [
      amigaball 50 10 20
      setx xpos - 1 lo 4 lt 2
      nextframe clean
    ]
    ;move down
    
    repeat 11 [
      amigaballoid 50 10 20 1 - repcount / 20
      lo 2 lt 2 nextframe clean
    ]
    ;compress ball
    
    randpc dountil pencolor != fillcolor [randfc]
    ;change colors
    
    repeat 11 [
      amigaballoid 50 10 20 0.375 + repcount / 20
      ra 2 lt 2 nextframe clean
    ]
    ;expand ball
    
    repeat 28 [
      amigaball 50 10 20
      setx xpos + 1 ra 4 lt 2
      nextframe clean
    ]
    ;move up
    
    repeat 11 [
      amigaballoid 50 10 20 1 - repcount / 20
      ra 2 lt 2 nextframe clean
    ]
    ;compress ball
    
    randpc dountil pencolor != fillcolor [randfc]
    ;change colors
    
    repeat 11 [
      amigaballoid 50 10 20 0.375 + repcount / 20
      lo 2 lt 2 nextframe clean
    ]
    ;expand ball
    
    repeat 14 [
      amigaball 50 10 20 setx xpos - 1
      lo 4 lt 2 nextframe clean
    ]
    ;move back to center
  ]
END