Using Properties in Smart Mobile Studio

The developers of Delphi give this explanation of properties in a wiki page.

Embarcadero: A property, like a field, defines an attribute of an object. But while a field is merely a storage location whose contents can be examined and changed, a property associates specific actions with reading or modifying its data. Properties provide control over access to an object's attributes, and they allow attributes to be computed.

From the code below, in the condition Mob.Bottom <= GameView.Height, Bottom appears to be a field but it represents the result of the addition Mob.Y + Mob.HEIGHT. The declaration property Bottom: integer read GetBottom effects the required computation by the GetBottom function when the property is required. The absence of a specified write action safeguards the property. Modifying data with the code Mob.Colour := 'red' ensures that the new value is acceptable; the setter method SetColour outputs an error message upon an attempt to set the colour to black.

You can use public getters and setters for private fields without having properties, but properties can make the code slightly easier to read. We prefer Mob.Colour := 'red' to Mob.SetColour('red').

unit Unit1;

interface

uses
  System.Types, SmartCL.System, SmartCL.Components, SmartCL.Application,
  SmartCL.Game, SmartCL.GameApp, SmartCL.Graphics;

type
  TMob = class
  public
    function GetBottom: integer;
    procedure SetColour(NewColour: string);
  private
    const WIDTH = 60;
    const HEIGHT = 30;
    X, Y: integer;
    FColour: string;
    procedure MoveBy(Dist: integer);
    procedure Draw(Canv: TW3Canvas);
    property Bottom: integer read GetBottom;
    property Colour: string read FColour write SetColour;
  end;

type
  TCanvasProject = class(TW3CustomGameApplication)
  private
    Mob: TMob;
  protected
    procedure ApplicationStarting; override;
    procedure ApplicationClosing; override;
    procedure PaintView(Canvas: TW3Canvas); override;
  end;

implementation

function TMob.GetBottom;
begin
  Result := Y + HEIGHT;
end;

procedure TMob.SetColour(NewColour: string);
begin
  if NewColour in ['red', 'yellow', 'green'] then
    FColour := NewColour
  else
    ShowMessage('Colour ' + NewColour + ' not allowed!');
end;

procedure TMob.MoveBy(Dist: integer);
begin
  Y += Dist;
end;

procedure TMob.Draw(Canv: TW3Canvas);
begin
  Canv.BeginPath;
  Canv.FillStyle := Colour;
  Canv.Ellipse(X, Y, X + WIDTH, Y + HEIGHT);
  Canv.Fill;
end;

procedure TCanvasProject.ApplicationStarting;
begin
  inherited;
  Mob := new TMob;
  Mob.SetColour ('red');
  GameView.Delay := 1;
  GameView.StartSession(False);
end;

procedure TCanvasProject.ApplicationClosing;
begin
  GameView.EndSession;
  inherited;
end;

procedure TCanvasProject.PaintView(Canvas: TW3Canvas);
begin
  // Clear background
  Canvas.FillStyle := 'rgb(0, 0, 99)';
  Canvas.FillRectF(0, 0, GameView.Width, GameView.Height);
  // Draw mobile on the screen
  Mob.Draw(Canvas);
  // Move mobile ready for next frame
  if Mob.Bottom <= GameView.Height then
    Mob.MoveBy(1)
  else
    begin
      Mob.SetColour('black');
      Mob.SetColour('green');
      Mob.Draw(Canvas);
      GameView.EndSession;
    end;
end;

end.
Programming - a skill for life!

How to write object-oriented code (including constructors, inheritance and properties) in Smart Pascal