Using Mouse and Touch Inputs on DIY Buttons to Move an Object

For control of movement by a button you want a continuous press with mouse or touch to keep the object moving up, down, left or right. This is achieved by setting a Boolean variable to True at the start of the press and changing it back to False at the end. In the drawing routine, which is rerun with high frequency, the object moves if one of the Boolean direction variables is True.

We obtained the arrows on the buttons by copying the characters on this useful page.

The code of the canvas application follows the demonstration. See the following page if you want to use inbuilt TW3Buttons instead of doing it yourself.

ArrowButtons.html

If you do not see the demonstration, your school security system might have blocked it. Click here to try it on a separate page.

Smart Pascal Code

unit Unit1;

interface

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

type
  TCanvasProject = class(TW3CustomGameApplication)
  private
    const PANEL_HEIGHT = 40;
    const SCENE_WIDTH = 300;
    const SCENE_HEIGHT = 250;
    const MOB_WIDTH = 10;
    const MOB_HEIGHT = 10;
    const X_SPEED = 2;
    const Y_SPEED = 2;
    FirstFrame := True;
    MobRect, btnLeft, btnRight, btnUp, btnDown, Panel, Scene: TRect;
    MouseClickedLeft: Boolean := False;
    MouseClickedRight: Boolean := False;
    MouseClickedUp: Boolean := False;
    MouseClickedDown: Boolean := False;
  protected
    procedure HandleButtonPressed(x, y: integer);
    procedure HandleButtonReleased;
    procedure ApplicationStarting; override;
    procedure ApplicationClosing; override;
    procedure PaintView(Canvas: TW3Canvas); override;
  end;

implementation

procedure TCanvasProject.HandleButtonPressed(x, y: integer);
begin
  var Point := TPoint.Create(x, y);
  if btnLeft.ContainsPoint(Point) then
    MouseClickedLeft := True
  else if btnRight.ContainsPoint(Point) then
    MouseClickedRight := True
  else if btnUp.ContainsPoint(Point) then
    MouseClickedUp := True
  else if btnDown.ContainsPoint(Point) then
    MouseClickedDown := True;
end;

procedure TCanvasProject.HandleButtonReleased;
begin
  MouseClickedLeft := False;
  MouseClickedRight := False;
  MouseClickedUp := False;
  MouseClickedDown := False;
end;

procedure TCanvasProject.ApplicationStarting;
begin
  inherited;
  GameView.Delay := 5;
  Scene := TRect.CreateSized(0, 0, SCENE_WIDTH, SCENE_HEIGHT);
  Panel := TRect.CreateSized(0, SCENE_HEIGHT, SCENE_WIDTH, PANEL_HEIGHT);

  btnLeft := TRect.CreateSized(5, SCENE_HEIGHT + 5, 40, 30);
  btnRight := TRect.CreateSized(55, SCENE_HEIGHT + 5, 40, 30);
  btnUp := TRect.CreateSized(105, SCENE_HEIGHT + 5, 40, 30);
  btnDown := TRect.CreateSized(155, SCENE_HEIGHT + 5, 40, 30);

  MobRect := TRect.CreateSized(50, 50, 10, 10);
  GameView.OnMouseDown := procedure(o: TObject; b: TMouseButton; t: TShiftState; x, y: integer)
    begin
      HandleButtonPressed(x, y);
    end;
  GameView.OnMouseUp := procedure(o: TObject; b: TMouseButton; t: TShiftState; x, y: integer)
    begin
      HandleButtonReleased;
    end;
  GameView.OnTouchBegin := Procedure(Sender: TObject; info: TW3TouchData)
    begin
      HandleButtonPressed(info.Touches.Touches[0].PageX, info.Touches.Touches[0].PageY);
    end;
  GameView.OnTouchEnd := Procedure(Sender: TObject; info: TW3TouchData)
    begin
      HandleButtonReleased;
    end;
  GameView.StartSession(False);
end;

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

procedure TCanvasProject.PaintView(Canvas: TW3Canvas);
begin
  if FirstFrame then
    begin
      // Draw bottom panel and buttons
      Canvas.FillStyle := 'rgb(220, 220, 220)';
      Canvas.FillRectF(Panel);
      Canvas.FillStyle := 'rgb(80, 80, 80)';
      Canvas.FillRectF(btnLeft);
      Canvas.FillRectF(btnRight);
      Canvas.FillRectF(btnUp);
      Canvas.FillRectF(btnDown);
      Canvas.FillStyle := 'white';
      Canvas.Font := '18pt verdana';
      Canvas.FillText('←', btnLeft.Left + 8, btnLeft.Bottom - 8);
      Canvas.FillText('→', btnRight.Left + 8, btnRight.Bottom - 8);
      Canvas.FillText('↑', btnUp.Left + 10, btnUp.Bottom - 5);
      Canvas.FillText('↓', btnDown.Left + 10, btnDown.Bottom - 5);
      FirstFrame := False;
    end;
  // Clear background
  Canvas.FillStyle := 'rgb(0, 0, 99)';
  Canvas.FillRectF(Scene);
  // Move mob if button pressed and if a move would not take it outside the scene
  Canvas.FillStyle := 'rgb(99, 0, 0)';
  if MouseClickedLeft and (MobRect.Left > X_SPEED) then
    MobRect.MoveBy(-X_SPEED, 0)
  else if MouseClickedRight and (MobRect.Right + X_SPEED < SCENE_WIDTH) then
    MobRect.MoveBy(X_SPEED, 0)
  else if MouseClickedUp and (MobRect.Top > Y_SPEED) then
    MobRect.MoveBy(0, -Y_SPEED)
  else if MouseClickedDown and (MobRect.Bottom + Y_SPEED < SCENE_HEIGHT)  then
    MobRect.MoveBy(0, Y_SPEED);
  // Draw white mob
  Canvas.FillStyle := 'white';
  Canvas.FillRectF(MobRect);
end;

end.    
Programming - a skill for life!

Input from the keyboard, mouse and touch using Smart Mobile Studio