Using a Form-based Project to Provide Options to a Canvas Project

Introduction

This method is more difficult than the one given on the previous page and enables you to develop skills with visual components and a cookie. When you click on the button you pass the settings to an adapted version of our demonstration program Motion2. If you see no display at school, the security system might have blocked it. You can try instead this direct link to the program running on its own page. In order to change the settings from the canvas project, just press the back button on your browser to return to the set-up screen.

If you do not mind risking a deterioration in performance in your canvas game and you have sufficient space you can include widgets in your canvas project as shown on the next page. Yet another alternative is to write your own modal form.

SetupGame.html

Smart Pascal Code of Form

unit Setup;

interface

uses 
  SmartCL.System, SmartCL.Graphics, SmartCL.Components, SmartCL.Forms, 
  SmartCL.Fonts, SmartCL.Borders, SmartCL.Application, SmartCL.Controls.Panel,
  SmartCL.Controls.PaintBox, SmartCL.Slider, SmartCL.Controls.Label,
  SmartCL.Controls.ComboBox, SmartCL.Controls.Listbox, System.Colors,
  SmartCL.CookieStorage, SmartCL.Controls.Button;

type
  TForm1 = class(TW3Form)
    procedure W3Button1Click(Sender: TObject);
    procedure W3ComboBox1Click(Sender: TObject);
    procedure W3ListBox1Selected(Sender: TObject; itemIndex: Integer);
    const strColours: array[0..4] of string = ['red', 'silver', 'yellow', 'white', 'blue'];
    strCookie: string;
    strColour: string := 'red';
    strDelay: string := '20';
    strMobWidth: string := '20';
    strMobHeight: string := '20';

    procedure pbPaint(Sender: TObject; Canvas: TW3Canvas);
    procedure SliderMobHeightChange(Sender: TObject);
    procedure SliderMobWidthChange(Sender: TObject);
    procedure SaveCookie;
  private
    {$I 'Setup:intf'}
  protected
    procedure InitializeForm; override;
    procedure InitializeObject; override;
    procedure DrawMob;
  end;

implementation

{ TForm1 }

procedure TForm1.DrawMob;
begin
  pb.Canvas.FillStyle := 'White';
  pb.Canvas.FillRectF(0, 0, pb.Width, pb.Height);
  pb.Canvas.FillStyle := strColour;
  pb.Canvas.BeginPath;
  pb.Canvas.Ellipse(0, 0, SliderMobWidth.Value, SliderMobHeight.Value);
  pb.Canvas.Fill;
end;

procedure TForm1.SliderMobWidthChange(Sender: TObject);
begin
  strMobWidth := intToStr(round(SliderMobWidth.Value));
  DrawMob;
end;

procedure TForm1.SliderMobHeightChange(Sender: TObject);
begin
  strMobHeight := intToStr(round(SliderMobHeight.Value));
  DrawMob;
end;

procedure TForm1.pbPaint(Sender: TObject; Canvas: TW3Canvas);
begin
  DrawMob;
end;

procedure TForm1.W3ListBox1Selected(Sender: TObject; itemIndex: Integer);
begin
  strColour := strColours[itemIndex];
  DrawMob;
end;

procedure TForm1.W3ComboBox1Click(Sender: TObject);
begin
  strDelay := W3ComboBox1.Values[W3ComboBox1.SelectedIndex];
end;

procedure TForm1.W3Button1Click(Sender: TObject);
begin
  SaveCookie;
  BrowserAPI.Window.location.href := 'Motion3.html';
end;

procedure TForm1.InitializeForm;
begin
  inherited;
  lblTitle.Font.Size := 24;
  lblTitle.Font.Weight := 'bold';
  lblTitle.AlignText := taCenter;
  SliderMobHeight.Value := 20;
  SliderMobWidth.Value := 20;
  for var i := 20 to 80 step 20 do
    begin
      W3Combobox1.Add(intToStr(i));
      W3Combobox1.Values[i div 20 - 1] := i;
    end;

  W3ListBox1.ItemClass := TW3Label;
  for var i := 1 to 5 do
    W3ListBox1.Add;
  W3ListBox1.Styles.SelectedColor := clLightBlue;
  W3ListBox1.ItemHeight := 24;
  W3ListBox1.SelectedIndex := 0;
  W3ListBox1.EnableAnimation := false;
  for var i := 0 to 4 do
  begin
    TW3Label(W3ListBox1.Items[i]).Caption := strColours[i];
    TW3Label(W3ListBox1.Items[i]).Font.Size := 18;
  end;
end;

procedure TForm1.InitializeObject;
begin
  inherited;
  {$I 'Setup:impl'}
  DrawMob;
end;

procedure TForm1.SaveCookie;
begin
  strCookie := strColour + ',' +  strDelay + ',' + strMobWidth + ',' + strMobHeight;
  Cookies.WriteString('GameSetup', strCookie, 50); // 50 days
end;
 
initialization
  Forms.RegisterForm({$I %FILE%}, TForm1);
end.
    

XML Code of Form

<SMART>
  <Form version="2" subversion="1">
    <Created>2015-08-31T18:17:02.880</Created>
    <Modified>2015-09-24T14:01:57.193</Modified>
    <object type="TW3Form">
      <Caption>W3Form</Caption>
      <Name>Form1</Name>
      <object type="TW3Panel">
        <Width>280</Width>
        <Height>248</Height>
        <Name>W3Panel1</Name>
        <object type="TW3PaintBox">
          <Width>32</Width>
          <Top>152</Top>
          <Left>16</Left>
          <Height>32</Height>
          <Color>65408</Color>
          <Name>pb</Name>
          <OnPaint>pbPaint</OnPaint>
        </object>
        <object type="TW3Slider">
          <Value>20</Value>
          <Minimum>10</Minimum>
          <Maximum>25</Maximum>
          <Width>64</Width>
          <Top>120</Top>
          <Left>8</Left>
          <Height>24</Height>
          <Color>255</Color>
          <Name>SliderMobWidth</Name>
          <OnChange>SliderMobWidthChange</OnChange>
        </object>
        <object type="TW3Slider">
          <Value>20</Value>
          <Minimum>10</Minimum>
          <Maximum>25</Maximum>
          <Width>64</Width>
          <Top>160</Top>
          <Left>56</Left>
          <Height>24</Height>
          <Color>255</Color>
          <Name>SliderMobHeight</Name>
          <OnChange>SliderMobHeightChange</OnChange>
        </object>
        <object type="TW3Label">
          <Caption>Mob Width</Caption>
          <Width>128</Width>
          <Top>96</Top>
          <Left>8</Left>
          <Height>32</Height>
          <Name>W3Label1</Name>
        </object>
        <object type="TW3Label">
          <Caption>Mob Height</Caption>
          <Width>128</Width>
          <Top>136</Top>
          <Left>56</Left>
          <Height>32</Height>
          <Name>W3Label2</Name>
        </object>
        <object type="TW3ComboBox">
          <Width>128</Width>
          <Top>64</Top>
          <Left>8</Left>
          <Height>24</Height>
          <Name>W3ComboBox1</Name>
          <OnClick>W3ComboBox1Click</OnClick>
        </object>
        <object type="TW3Label">
          <Caption>Frame Delay (ms)</Caption>
          <Width>128</Width>
          <Top>40</Top>
          <Left>8</Left>
          <Height>24</Height>
          <Name>W3Label3</Name>
        </object>
        <object type="TW3ListBox">
          <Width>87</Width>
          <Top>64</Top>
          <Left>176</Left>
          <Height>136</Height>
          <Name>W3ListBox1</Name>
          <OnSelected>W3ListBox1Selected</OnSelected>
        </object>
        <object type="TW3Label">
          <Caption>Game Setup</Caption>
          <Width>280</Width>
          <Top>8</Top>
          <Height>32</Height>
          <Name>lblTitle</Name>
        </object>
        <object type="TW3Button">
          <Caption>Finished</Caption>
          <Width>128</Width>
          <Top>208</Top>
          <Left>136</Left>
          <Height>32</Height>
          <Name>W3Button1</Name>
          <OnClick>W3Button1Click</OnClick>
        </object>
        <object type="TW3Label">
          <Caption>Mob Colour</Caption>
          <Width>88</Width>
          <Top>40</Top>
          <Left>176</Left>
          <Height>32</Height>
          <Name>W3Label4</Name>
        </object>
      </object>
    </object>
  </Form>
</SMART>

Smart Pascal Code of Motion3

unit Unit1;

interface

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

type
  TCanvasProject = class(TW3CustomGameApplication)
  private
    MOB_WIDTH, MOB_HEIGHT, MobX: integer;
    MobY: integer = 100;
    GoingRight, GoingUp: Boolean;
    StartupValues: array of string;
  protected
    procedure ApplicationStarting; override;
    procedure ApplicationClosing; override;
    procedure PaintView(Canvas: TW3Canvas); override;
  end;


implementation

procedure TCanvasProject.ApplicationStarting;
begin
  inherited;
  //strCookie := strColour + ',' +  strDelay + ',' + strMobWidth + ',' + strMobHeight;
  var cookie := Cookies['GameSetup'];
  StartupValues := strSplit(cookie, ',');
  MOB_WIDTH := strtoInt(StartupValues[2]);
  MOB_HEIGHT := strtoInt(StartupValues[3]);

  GameView.Width := 100;
  GameView.Height := 200;
  GoingRight := True;
  MobX := 5;
  GameView.Delay := strToInt(StartupValues[1]);
  GameView.StartSession(True);
end;

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

procedure TCanvasProject.PaintView(Canvas: TW3Canvas);
begin
  // Clear background to green
  Canvas.FillStyle := 'Green';
  Canvas.FillRectF(0, 0, GameView.Width, GameView.Height);
  Canvas.FillStyle := StartupValues[0];
  Canvas.BeginPath;
  Canvas.Ellipse(MobX, MobY, MobX + MOB_WIDTH, MobY + MOB_HEIGHT); // leftX, topY, rightX, bottomY
  Canvas.Fill;

  // Change position of mobile before next paint.
  if GoingRight = True then // If ball is going right then
    begin                   // do whatever is below
      MobX += 5;  //increase MobX by 5
    end
  else               // Otherwise
    begin
      MobX -= 2;     // decrease MobX by 2
    end;
  // Change direction when right of ellipse is at right of GameView or beyond.

  if MobX + MOB_WIDTH >= GameView.Width  then //If the ball is on the right of the screen
    begin
      GoingRight := False;   // Going right is no longer true i.e it will go left
    end
  // Change direction when left of ellipse is at left of GameView or beyond.
  else if MobX <= 0 then
    begin
      GoingRight := True;
    end;

  if GoingUp = true then
    begin
      MobY -= 3;
    end
  else
    begin
      MobY += 6;
    end;

  if MobY <= 0 then
    begin
      GoingUp := False;
    end
  else if MobY + MOB_HEIGHT >= GameView.Height then
    begin
      GoingUp := True;
    end;
end;

end.
    
Programming - a skill for life!

How to provide the user with game options in Smart Pascal