I would like to write a programme that can demonstrate how gravity work by showing bouncing balls on the screen- the idea is that the user can set the strength of the gravity, and then see how the balls react and bounce differently depending on how strong gravity is.

I know how to create objects and draw circles on the screen (to represent the balls) but I have no idea how to make them move around- or how to move them around in real time.

Could anyone please help me and give me some tips?

Recommended Answers

All 6 Replies

first thing, you must learn a lot of physics, until your be able to calculate on paper how a ball is bouncing.
after that chapter is completed then you take the delphi and learn about canvas(which is the base of graphics in delphi) and from there how to draw a circle at a specific position on the screen.

best regards,

Thanks for the help- I've been told that if I want to have the balls bouncing around in real time, a 'thread' is best- I've done this sort of thing in Gamemaker before, and its easy to do, as bouncing is calculated for you, and the screen would update the balls position every frame- Could anyone please help explain how threads work in Delpih?

Thank you for your help- I have figured out how to make a ball bounce, there was no thread needed- It was possible with a while loop.

now, is the moment to help the others:cheesy:. if you can, please post your code, in this way if somebody search the same thing, he can find it here

best regards,

Ok right- here is my code:




unit frm_main;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, ComCtrls, Math;
type
  TForm1 = class(TForm)
    Backround_pnl: TPanel;
    Bouncing_ball_image: TShape;
    Go_btn: TButton;
    EnergyLost_bar: TTrackBar;
    Gravity_strength_bar: TTrackBar;
    Label1: TLabel;
    Label2: TLabel;
    Horizontal_Movement_bar: TTrackBar;
    Label3: TLabel;
    Reset_btn: TButton;
    procedure Go_btnClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Reset_btnClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;
   StartingHeight : Integer; //saves how high the ball starts
   StartingLeft : Integer; //saves where the ball's left position is
implementation
{$R *.dfm}
procedure TForm1.Go_btnClick(Sender: TObject);   //when clicking on the go button
var         
    BallMoving : Boolean;  //checks to see if the ball is moving- to end the loop
    Velocity : Real;  //speed in pixels per loop
    LastTop : Integer;  //Specifies the position of the ball's last position (the top of the ball's x value)
    AddonVelocity : Real;   //speed in pixels per loop one loop ahead
    EnergyLost : Real; //Energy Lost makes the ball bounce less high each time
    LastLeft : Integer;// the last position of the ball's y value
    Sideways_Velocity : Real;        //Sideways speed in pixels per loop- a - speed makes it go to the left, + to the right
    Addon_Sideways_Velocity : Real; //Sideways Speed one loop ahead
    Horizontal_Component : Real;    //controls sideways speed (- is to the left, + is to the right)
   //top, left, width, height, tag are properties of the ball- thus not set as variables here

begin
    Bouncing_ball_image.Top := StartingHeight;
    Velocity := 0;
    BallMoving := true;
    tag := 0;                 //-----------setting starting values-----------------------
    lasttop := 0;
    Sideways_Velocity := 0;
    LastLeft := 0;

    with Bouncing_ball_image do  //--------------------------Starting repeat loop with the ball's position------------------------
    repeat
      AddonVelocity := Velocity + 1;     //Adds one pixel per loop onto the speed each loop, simulating acceleration
      if Velocity >= 0 then   //means the ball is going down
      Begin      //only starts next statement if velocity is bigger or equal to 0  (Ball going down)
           //------------------ball going down code--------------------------
          If (top + AddonVelocity) >= (Backround_pnl.Height - height)//checks if ball hits floor( if ball's x + speed (distance moved
                                                                     //next loop) > = the panel's height - ball height, it'll be on the floor
          then                                                          
          begin
            LastTop := top;
            Top := Backround_pnl.Height - height;  //so that the ball cannot go throught the floor- it bounces right on the surface
           //Makes the ball's x = panel hegith - ball's height, therefore won't go through bottom of panel
            EnergyLost := (EnergyLost_bar.Position / EnergyLost_bar.Max); //Works out energy lost- has to be > 1 else the ball stops at once.
            AddonVelocity := ((AddonVelocity * EnergyLost)* -1); //this makes the ball turn around (reverses vertical speed, therefore it goes up)

            if AddonVelocity > (-5) then BallMoving := false; //if the ball bounces less than 5 pixels it'll stop-
        end                                                   //to avoid the ball bouncing- but not high enough to be noticed.
          else
            top := top + round(AddonVelocity); //If its not hitting the ground...ball's x = ball's x + speed. (rounded else you get incompatible types error- float with integer)
          end
      else //----------if the ball is going up--------------------------
      Begin
              If top + round(AddonVelocity) < 0 then //If ball's x + speed (how many pixels it'll move next loop) < 0 then it'd go through the top of the panel
                  begin
                  Top := 0 //would prevent the ball going through the top of the form

                  end
                  else
                  If LastTop  > 0 then  //if the ball's x > 0...
                  Begin
                    Top := LastTop;
                    LastTop  := 0;
                    AddonVelocity := AddonVelocity - 1; //now each loop u take away speed (one less pixel per loop)-  to simulate deacceleration
                  end
                  else
                  Begin
                    Top := top + round(AddonVelocity); //else ball's x = ball's x  + speed
                  end;
    end;

    //the sideways bouncing code
        //--------------------------------------------Code below works out bouncing on the right wall---------------------------
      Horizontal_Component := Horizontal_Movement_bar.Position;   //Horizonal bar thingy
      Addon_Sideways_Velocity := Horizontal_Component;      //Adds one pixel per loop onto the speed each loop, simulating acceleration
      if Sideways_Velocity >= 0 then   //means the ball is going right
      Begin      //only starts next statement if Sideways_Velocity is bigger or equal to 0  (Ball going right)
             //if y + pixels/loop >=  1009 - 65 then...
          If (left + Addon_Sideways_Velocity) >= (Backround_pnl.Width - width)   //the next loop would put the ball through the walls-
          then                                                           // if statement below is to stop that happening
          begin
            //LastLeft := left;
            Left := Backround_pnl.Width - Width;  //so that the ball cannot go throught the wall- it bounces right on the surface
            Horizontal_Movement_bar.Position := (Horizontal_Movement_bar.Position*-1);  //the horizontal bar position is made negative as that is what controls sideways bouncing
            Addon_Sideways_Velocity := ((Addon_Sideways_Velocity * Horizontal_Component)* -1); //this makes the ball reverse direction

            if Addon_Sideways_Velocity > (-5) then Sideways_Velocity := 0; //if the ball bounces less than 5 pixels it'll stop- and just fall
        end
          else
            left := left + round(Addon_Sideways_Velocity);
          end
      else 
    // -----------------------------Code Below works out bouncing on left wall---------------------------------
    Begin        //y + Pixels/loop < 0 then...
              If left + round(Addon_Sideways_Velocity) < 0 then      //Code is for when it hits left wall
                  begin
                  left := 0;  //prevents the ball going through the walls of the form
                  Horizontal_Movement_bar.Position := Horizontal_Movement_bar.Position * -1; //reverses direction
                  end
                  else
                  If LastLeft  > 0 then
                   //ball going left
                  Begin
                  LastLeft  := 0;
                    Left := LastLeft;
                    Addon_Sideways_Velocity := Addon_Sideways_Velocity -1;
                    //Addon_Sideways_Velocity := Horizontal_Component;
                    Horizontal_Movement_bar.Position := Horizontal_Movement_bar.Position * -1;
                    Addon_Sideways_Velocity := Horizontal_Component * -1 ;
                  end
                  else
                  Begin
                    Left := Left + round(Addon_Sideways_Velocity);
                  end;    //--------------end of left wall bouncing---------------------
    end;
          If Bouncing_ball_image.Tag > 0 then
                          Begin
                          BallMoving := false;
                          end;

         Sideways_Velocity  :=  Addon_Sideways_Velocity ;
         Velocity := AddonVelocity;
         Application.processmessages;
         sleep(Gravity_strength_bar.Max - Gravity_strength_bar.position);
   If Bouncing_ball_image.Left > Backround_pnl.Width then
   Begin
   Bouncing_ball_image.Left := Backround_pnl.Width -1;
   end;


  until BallMoving = false; //while loop ends when the ball is not moving

end;
procedure TForm1.FormCreate(Sender: TObject);   //when form is created
begin
  Bouncing_ball_image.Brush.Color := clRed; //Makes the ball red
  Backround_pnl.DoubleBuffered := true;   //a function to make the moving look smoother
  StartingHeight := Bouncing_ball_image.Top; //Sets the default hieght (x)
  StartingLeft := Bouncing_ball_image.Left;  //sets default starting left (y)
  end;
procedure TForm1.Reset_btnClick(Sender: TObject);  //resetting button
begin
  //Tag := 1;
  Bouncing_ball_image.Left := StartingLeft;
  Bouncing_ball_image.Top := StartingHeight;
  Horizontal_Movement_bar.Position := 0;
  Gravity_strength_bar.Position := 10;
  EnergyLost_bar.Position := 20;
  end;
end.
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.