Skip to content

FireMonkey Classic "Deep Space" Starfield Simulation in 3D

Yesterday I was playing with implementing "parallax" starfield simulation in a Delphi XE2 iOS HD project as documented here. To be honest at the beginning my plan was to implement a classic "deep space" starfield simulation, but could not find any code samples, so decided to go for a simpler "parallax" approach.

I have posted my demo internally for other Embarcadero technical evangelists to enjoy and got back almost instantaneous feedback from David I: "Looks like falling rain. Was hoping for a Star Trek type flying though space and having star field flying past."

There was not choice left! I had to implement the real thing:-)

First I did a little of googling to see if I could adapt to Delphi and FireMonkey some existing code. I found one really interesting example of a starfield simulation code at the Chrome Experiments website. It is JavaScript so you can just select "View Source" in a web browser and you can inspect the actual code. If you move the mouse the direction of the star movement changes and if you change mouse position quickly enough you can even see star paths bended. Very cool. But still quite a lot math involved…

Why should I try to translate from a complex JavaScript code? Why not to try with a FireMonkey "3D" application to avoid spending time on calculating perspective view?

The end result was VERY encouraging. I was able to create a very nice starfield simulation in a FireMonkey 3D iOS application in a matter of about 15 minutes.

My steps were the following:

  • Start Delphi XE2 and create a new "FireMonkey 3D iOS Application" and "Save All".
  • Change application main form background color to "Black".
  • Add a "TCamera" component to the form and "TLight" component to the camera.
  • Change application main form "UseDesignCamera" property value to "False"
  • Drop a "TDummy" component on the form, which will act as "parent" for all dynamically created spheres that will represent stars.
  • Add "TTimer" component to the form. Set its "Interval" property to 20 ms. Double-click its "OnTimer" event to create an empty event handler.
  • Double-click in the "OnCreate" event for the form to create an empty event handler.
  • Copy and paste all the remaining code from the complete code listing below.

Now just export the project to XCode with the "dpr2xcode" and build it for the iOS simulator or iOS device.


unit FormStarsUnit;

interface

uses
  SysUtils, Types, UITypes, Classes, Variants, FMX_Types, FMX_Controls, FMX_Forms,
  FMX_Dialogs, FMX_Types3D, FMX_Objects3D;

const
  STAR_COUNT = 250;
  DELTA_Z = 10; // Timer1.Interval=20 ms
  MAX_X = 200;
  MAX_Y = 200;
  MAX_Z = 500;

type
  TForm1 = class(TForm3D)
    Camera1: TCamera;
    Light1: TLight;
    Dummy1: TDummy;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    procedure Form3DCreate(Sender: TObject);
  private
    function RandomLocation: TPoint3D;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

procedure TForm1.Form3DCreate(Sender: TObject);
var i: integer; sph: TSphere;
begin
  for i := 0 to STAR_COUNT-1 do
  begin
    sph := TSphere.Create(Dummy1);
    sph.Position.Point := RandomLocation;
    sph.Parent := Dummy1;
  end;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var i: integer; ctrl: TControl3D; obj: TFmxObject;
begin
  for i := 0 to Dummy1.ChildrenCount-1 do
  begin
    obj := Dummy1.Children[i];
    if obj is TControl3D then
    begin
      ctrl := TControl3D(obj);
      ctrl.Position.Z := ctrl.Position.Z - DELTA_Z;

      if ctrl.Position.Z < 0 then
        ctrl.Position.Point := RandomLocation;
    end;
  end;
end;

function TForm1.RandomLocation: TPoint3D;
begin
  Result.X := -MAX_X + random * 2 * MAX_X;
  Result.Y := -MAX_Y + random * 2 * MAX_Y;
  Result.Z := random * MAX_Z;
end;

end.

That’s it! No 3D math code at all! Just create some spheres in code, put them in random location and decrease the "Z" coordinate every 20 ms.

That’s the power of FireMonkey and Rapid Application Development with components, like "TSphere" or "TCamera"!

The source code for this demo application can be downloaded from Embarcadero CodeCentral. Enjoy!

{ 2 } Comments

  1. Vsevolod Leonov | June 13, 2012 at 10:11 am | Permalink

    Great! As simple as that!
    You discovered an interesting trend in a) FireMonkey learning b) making something for iOS - respect!

    Could you please also rotate the camera (may be with the help of TFloatAnimation) around the horizontal axis? In this case we could not only fly forward, but get 3d-feel. :)

  2. Pawel Glowacki | June 13, 2012 at 2:24 pm | Permalink

    Hi Vsevolod,
    Thanks for the comment. Good point!
    I’m looking to use Accelerometer to change the rotation of the dummy component:-)
    Pawel

Post a Comment

Your email is never published nor shared. Required fields are marked *

Bad Behavior has blocked 2 access attempts in the last 7 days.

Close