String Manipulation in Smart Pascal

Introduction

Although your games are likely to consist in the main of images and shapes, you might need to manipulate strings for tasks such as these:
  • display of the instructions and stats;
  • transfer of game data to and from local storage;
  • handling colours;
  • handling keyboard input from the player;
  • constructing shader programs for 3D graphics.
You will have seen how the frame rate is displayed in the canvas project template with the code:
Canvas.FillTextF('FPS:' + IntToStr(GameView.FrameRate), 10, 20, MAX_INT);
This demonstrates the widely used IntToStr function for converting an integer to a string and the joining together (concatenation) of strings with the + operator.

Even although keyboard input in Smart Pascal uses JavaScript key codes, the usual Pascal functions ord and chr still exist to convert from character to ASCII code and from ASCII code to character, respectively. Remember that a character in Smart Pascal is a single-character string.

You may access a single character in a string by considering it to be composed of an array of single-character strings. Following the declaration var str := 'qwerty';, str[3] evaluates to 'e'.

Commonly Used Inbuilt Functions

Commonly used functions are described in the following table, taken from the corresponding page of the main String Manipulation tutorial. In the table, Str, Str1 and Str2 are strings and n and m are positive integers. The first character is numbered 1 in Pascal. Thus, the position of ‘g’ in the string ‘program’ is 4.

Function Result
Pos(Str1, Str2) Returns the start position of Str1 in Str2. Returns 0 if Str1 is not in Str2
LeftStr(Str, n) Returns the first n characters of Str as a string
MidStr(Str, m, n) Returns, as a string, the next n characters of Str, starting at the mth character
RightStr(Str, n) Returns the last n characters of Str
Length(Str) Returns the number of characters in Str

Demonstration

In this demonstration of the preparation for a game, we obtain the player's name using the inbuilt w3_prompt function. The player is greeted personally for a fixed number of frames before the game begins, during which time we could load images. Procedure ApplicationStarting demonstrates the pos, length, leftStr and rightStr functions.

unit Unit1;

interface

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

type
  TCanvasProject = class(TW3CustomGameApplication)
  private
    forename, surname, full_name: string;
    frame_num: integer;
  protected
    procedure ApplicationStarting; override;
    procedure ApplicationClosing; override;
    procedure PaintView(Canvas: TW3Canvas); override;
    procedure Greeting(Canvas: TW3Canvas);
  end;

implementation

procedure TCanvasProject.ApplicationStarting;
begin
  inherited;
  GameView.Delay := 20;
  full_name := w3_prompt('Please enter your forename then surname separated by a space');
  var space_pos := pos(' ', full_name);
  forename := leftStr(full_name, space_pos - 1);
  surname := rightStr(full_name, length(full_name) - space_pos);
  GameView.StartSession(False);
end;

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

procedure TCanvasProject.Greeting(Canvas: TW3Canvas);
begin
  Canvas.Font := '10pt verdana';
  Canvas.FillStyle := 'rgb(255, 255, 255)';
  Canvas.FillText('Hello, ' + forename + '!', 10, 20);
  Canvas.FillText('Enjoy the game!', 10, 40);
  Canvas.FillText('See if you can top our leader board ...', 10, 60);
  Canvas.FillText('or at least be the best ' + surname + '.', 10, 80);
end;

procedure TCanvasProject.PaintView(Canvas: TW3Canvas);
begin
  inc(frame_num);
  //Clear background
  Canvas.FillStyle := 'rgb(0, 0, 99)';
  Canvas.FillRectF(0, 0, GameView.Width, GameView.Height);
  if frame_num < 5000 div GameView.Delay then
    Greeting(Canvas);
end;

end.

Other Routines

From the page of internal string functions for DWScript you can see the existence of many string routines such as floatToStr, strToFloat, delete, insert, lowerCase, upperCase, posEx, revPos, trim, trimLeft, trimRight, compareText, compareStr, dupeString, strAfter and strBefore. This section of code demonstrates the syntax for the use of some of these:

  var assessment := 'Your score is good.';
  insert('quite ', assessment,  15);
  ShowMessage(assessment);
  delete(assessment, 15, 6);
  ShowMessage(assessment);
  ShowMessage(upperCase(assessment));
  var firstWord := strBefore(assessment, ' ');
  ShowMessage('First word: ' + firstWord);
  var spacePos1 := pos(' ', assessment);
  var spacePos2 := posEx(' ', assessment, spacePos1 + 1);
  var secondWord := midStr(assessment, spacePos1 + 1, spacePos2 - SpacePos1 - 1);
  ShowMessage('Second word: ' + secondWord);
  assessment := format('Your score of %d is %s.', [90, 'excellent']);
  ShowMessage(assessment);
  var strCaps := 'JOE';
  var strLowerCase := 'joe';
  if compareText(strCaps, strLowerCase) = 0 then ShowMessage('JOE and joe same by compareText') else
    ShowMessage('JOE and joe different by compareText');
  if compareStr(strCaps, strLowerCase) = 0 then ShowMessage('JOE and joe same by compareStr') else
    ShowMessage('JOE and joe different by compareStr');

Storing and Loading Data

In the tutorial section entitled Storing and Loading Data we demonstrate for a console application the use of strSplit and strJoin for storing and loading the contents of arrays. You might have disparate data to store such as the current score and the coordinates and health of player and enemies. You should be prepared to write your own routines for converting these to and from the comma-separated lists of strings that are convenient for storage.

Programming - a skill for life!

How to learn the Smart Pascal language the fun way by making games. Use Blockly blocks at first if coming from Scratch.