BouncingBall

Program BouncingBall has quite a lot in common with program Rebound, but its ball accelerates as it moves downwards and decelerates as it moves upwards. The ball is drawn at regular time intervals, so the distance moved between drawings increases towards the bottom of the window. This may limit the height from which the ball can be dropped for the representation of motion to be acceptable. You can guess one of the suggestions for experimentation!

For a better example of physics applied to a moving ball, try Felix Thompson's BallTrajectory online. Felix uses Smart Mobile Studio to implement restitution and friction in addition to gravity.

program BouncingBall;
 {$mode objfpc}{$H+}
uses
  SysUtils, Graph;
const
  SLEEP_TIME = 20;
  DROP_TIME = 8;
  BOUNCES = 10;
  RADIUS = 10;
var
  Gd, Gm : smallint;
  Error, i, j,  X, Y, YStart : integer;
  PBall : pointer;
  MemoryBall : word;
begin
  Gd := D4bit;
  Gm := m640x480;
  initGraph(Gd, Gm, '');
  //Check graphResult
  Error := graphResult;
  if (error <> grOk) then
    begin
      writeln('640 x 480 x 16 is not supported.');
      sleep(5000);
      halt;
    end;
  //Draw a white ball at the top left of the screen.
  setFillStyle(SolidFill, White);
  fillEllipse(Radius, Radius, Radius, Radius);
  //Find the memory required to hold it in a buffer
  MemoryBall := imageSize(0, 0, Radius * 2, Radius * 2);
  getmem(PBall, MemoryBall); //Reserve the buffer of size MemoryBall
  getImage(0, 0, Radius * 2, Radius * 2, PBall^); //Copy image to buffer
  //Delete the ball, which was put there only to be copied.
  setFillStyle(SolidFill, Black);
  bar(0, 0, Radius * 2, Radius * 2);
  //Calculate suitable coordinates from which to drop the ball
  X := Radius + 50;
  YStart := getMaxY - (2 * Radius) - (DROP_TIME * DROP_TIME);
  for j := 1 to BOUNCES do
    begin
      //Accelerate the ball as it moves down
      for i := 0 to DROP_TIME do
        begin
          //Position the ball lower
          Y := i * i + YStart;
          putImage(X, Y, PBall^, 0);
          sleep(SLEEP_TIME);
          //Delete the ball
          bar(X, Y, Radius * 2 + X, Radius * 2 + Y);
        end;
      //Decelerate the ball as it moves up
      for i := DROP_TIME downto 0 do
        begin
          //Position the ball higher
          Y := i * i + YStart;
          putImage(X, Y, PBall^, 0);
          sleep(SLEEP_TIME);
          //Delete the ball
          bar(X, Y, Radius * 2 + X, Radius * 2 + Y);
        end;
    end;
  //One last drop
  for i := 0 to DROP_TIME do
    begin
      //Position the ball lower
      Y := i * i + YStart;
      putImage(X, Y, PBall^, 0);
      sleep(SLEEP_TIME);
      bar(X, Y, Radius * 2 + X, Radius * 2 + Y);
    end;
  //Position the ball to rest on the ground
  putImage(X, Y, PBall^, 0);
  //Free the buffer
  freeMem(PBall, MemoryBall);
  sleep(2000);
  closeGraph;
  write('Please press return to exit. ');
  readln;
end.
Programming - a skill for life!

Introduction to Motion Graphics