Programmer en langage Pascal avec l’EDI LAZARUS

Qui n’a pas déjà rêvé de créer ses propres programmes ? Quel que soit leur degré de complexité, la programmation aide à résoudre toute sorte de problèmes ; de simple calculs à l’automatisation de tâches sophistiquées. Différentes solutions de programmation sont disponibles suivant la nature du projet envisagé. Du langage bureautique VBA aux langages plus généraux comme Basic, Pascal… Concernant le langage Pascal plusieurs environnements de développement coexistent comme Delphi, une solution payante, et LAZARUS, une solution gratuite. C’est cette dernière qui sera abordée dans le cadre de cet article.

Accueil LAZARUS

LAZARUS, à l’image de Delphi, est un Environnement de Développement Intégré (EDI) comportant un langage Pascal (basé sur le standard Free Pascal), un éditeur de code source et un compilateur. LAZARUS est disponible sur plusieurs plateforme (Windows 32 et 64 bits, Linux, Mac OS) et produit des logiciels sur ces systèmes ainsi que sur Android.

Par rapport à d’autres EDI, LAZARUS présente de nombreux avantages :

  • Il s’agit d’un logiciel téléchargeable gratuitement, utilisable sans limite de temps ou de fonctionnalités,
  • L’EDI est entièrement traduit en Français, sa prise en main est rapide même pour un débutant,
  • Il est possible de programmer sans manier les bibliothèques additionnelles,
  • Le compilateur produit des fichiers exécutables (*.exe) distribuables librement,
  • Ce langage est multiplateforme ; le programmeur pourra porter ses œuvres indifféremment vers Windows, Linux, Mac Os ou encore Android, quelle que soit la plateforme de développement d’origine.

Installation de l’EDI LAZARUS :

Le site de l’éditeur (https://www.lazarus-ide.org/index.php?page=downloads) fournit toutes les informations utiles pour installer l’EDI.

Page de téléchargement LAZARUS

La page de téléchargement est en anglais mais l’interface du logiciel est entièrement traduite en français.

L’installation est entièrement automatisée, il suffit de valider les différentes fenêtres de l’installateur.

Fin de l'installation de LAZARUS

Une fenêtre vient ponctuer l’installation. Cliquer sur Terminer pour la fermer. Il ne reste plus qu’à lancer l’EDI.

Présentation de l’environnement de développement :

L’EDI de LAZARUS présente un éditeur de source, un inspecteur d’objets et différents menus permettant d’accéder à ses différentes fonctionnalités :

EDI LAZARUS

Documentation en ligne :

Pour commencer, un peu de lecture pour prendre en main l’EDI, se familiariser avec le langage Pascal et réaliser ses premiers projets.

Prise en main de LAZARUS :

Je me rends régulièrement sur le site Developpez.com pour parfaire ma pratique de la programmation ou résoudre des problèmes ponctuels. Afin de prendre en main LAZARUS, je propose au lecteur de suivre un des cours de ce site qui permet de réaliser un jeu de Pong, un projet ludique, simple qui permet de poser les bases de la programmation sous l’environnement de développement LAZARUS : https://laurent-dubettier-grenier.developpez.com/tutoriel/lazarus/creation-pong-lazarus/. Pour la petite histoire, Pong, créé en 1972, est un des premiers jeux vidéo d’arcade.

Afin de limiter la taille des exécutables, il est nécessaire de modifier les paramètres suivants dans le menu Projet / Options du projet… :

Cocher la case :

Projet –> Options du projet –> Options du compilateur –> Compilation and Linking –> Style de l’unité –> Lien intelligent (-CX)

Cocher la case :

Projet –> Options du projet –> Options du compilateur –> Compilation and Linking –> Édition des liens –> Lier intelligemment (-XX)

EDI LAZARUS Options - Compilation

Décocher toutes les cases :

Projet –> Options du projet –> Options du compilateur –> Débogage

Sauf Éliminer les symboles de l’exécutable (-Xs).

EDI LAZARUS Options - Débogage

Cocher “Définir comme options par défaut du compilateur” avant valider (bouton Ok).

La fenêtre du projet juste après sa création :

Fenêtre du projet LAZARUS

Fenêtre du projet LAZARUS

Cette même fenêtre avec fond noir :

Fond noir

Fond noir

Le paramétrage des éléments visuels du projet s’effectue à partir de l’inspecteur d’objets. Par exemple, la couleur du fond de la fenêtre se définit dans le champ Color (clBlack) et celle de son titre dans le champ Caption (Pong) :

Inspecteur d'objets LAZARUS

Le projet Pong avec fond noir :

Fond noir (fenêtre projet)

L’éditeur de source affiche le code source du projet :

Editeur de source LAZARUS

L’exécution du projet Pong finalisé :

Jeu Pong terminé

Le code source du projet Pong :

unit unit_pong;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    tmrMvtBalle: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: char);
    procedure FormPaint(Sender: TObject);
    procedure tmrMvtBalleTimer(Sender: TObject);

  private
    MiHauteur: integer;
    MiLargeur: integer;
    PosBalleX: Integer;
    PosBalleY: Integer;
    Direction: Integer;
    Vitesse: Integer;
    PosRaqDrY: Integer;
    PosRaqGaY: Integer;
    ScoreGauche: integer;
    ScoreDroit: integer;

    SauveEcran: TBitMap;

    procedure DessineBalle (const XNew, YNew: Integer);
    procedure DessineRaquetteDroite (const YNew: Integer);
    procedure DessineRaquetteGauche (const YNew: Integer);
    procedure NouveauService;
    procedure AfficheScore;
    procedure AnnoncerGagnant;
    procedure DessineFilet;
    procedure RestaurerEcran (const VarX,VarY: integer);
    procedure EnregistrerEcran (const VarX,VarY: integer);
    procedure AfficherInstructions;

  public


  end;

var
  Form1: TForm1;

implementation

uses
  LCLType;

{$R *.lfm}

{ TForm1 }

const
  HauteurJeu = 600;
  LargeurJeu = 800;
  TailleBalle = 15;
  RaqHauteur = 80;
  DecalageRaquette = 30;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Color:= clBlack;
  Height:= HauteurJeu;
  Width:= LargeurJeu;
  Position:= poScreenCenter;
  BorderStyle:= bsNone;
  PosBalleX:= 0;
  PosBalleY:= 0;
  Direction:= 25;
  Vitesse:= 20;
  PosRaqDrY:=0;
  PosRaqGaY:=0;
  ScoreGauche:= 0;
  ScoreDroit:= 0;
  SauveEcran:= TBitMap.Create;
  SauveEcran.SetSize(TailleBalle, TailleBalle);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  SauveEcran.Free;

end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: char);
begin
  MiHauteur:= HauteurJeu div 2;
  MiLargeur:= LargeurJeu div 2;
  if ord(Key) = VK_ESCAPE then
    Close;
  If Ord(Key) = VK_SPACE then
  Begin
    DessineFilet;
    AfficheScore;
    DessineBalle(MiLargeur, MiHauteur);
    tmrMvtBalle.Enabled:=True;
    DessineRaquetteDroite (MiHauteur);
    DessineRaquetteGauche (MiHauteur);
  End;
  if Key in ['m', 'M'] then
    DessineRaquetteDroite(PosRaqDrY + 20);
  if Key in ['k', 'K'] then
    DessineRaquetteDroite(PosRaqDrY - 20);
  if Key in ['f', 'F'] then
    DessineRaquetteGauche(PosRaqGaY + 20);
  if Key in ['s', 'S'] then
    DessineRaquetteGauche(PosRaqGaY - 20);
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
  DessineFilet;
  AfficherInstructions;
  DessineRaquetteDroite(MiHauteur);
  DessineRaquetteGauche(MiHauteur);
  OnPaint:= nil;
end;

procedure TForm1.tmrMvtBalleTimer(Sender: TObject);
Var
  XChange: Integer;
  YChange: Integer;
begin
  Xchange:= trunc(cos(Pi / 180 * Direction) * Vitesse);
  Ychange:= trunc(sin(Pi / 180 * Direction) * Vitesse);
  DessineBalle (PosBalleX + XChange,PosBalleY + Ychange);
  If (PosBalleX<=0) or (PosBalleX >= (LargeurJeu - TailleBalle)) then
    Direction:= Direction + (90 - Direction) * 2
  else if (PosBalleY<=0) or(PosBalleY >= (HauteurJeu - TailleBalle)) then
    Direction:= Direction + (180 - Direction) *2
  else if (PosBalleX + TailleBalle >= LargeurJeu - DecalageRaquette - TailleBalle) and (PosBalleY >= PosRaqDrY) and (PosBalleY + TailleBalle <= PosRaqDrY + RaqHauteur) then
    Direction:= Direction + (90 - Direction) * 2
  else if (PosBalleX <= DecalageRaquette + TailleBalle) and (PosBalleY >= PosRaqGaY) and (PosBalleY + TailleBalle <= PosRaqGaY + RaqHauteur) then
    Direction:= Direction + (90 - Direction) * 2;
  If (PosBalleX<=0) then
  begin
    Inc (ScoreDroit);
    NouveauService;
  end
  else if (PosBalleX >= (LargeurJeu - TailleBalle)) then
  begin
    Inc (ScoreGauche);
    NouveauService;
  end
end;

procedure TForm1.DessineBalle(const XNew, YNew: Integer);
begin
  RestaurerEcran(PosBalleX, PosBalleY);
  EnregistrerEcran(XNew, Ynew);
  Canvas.Brush.Color:=clWhite;
  Canvas.Rectangle(XNew,YNew,Xnew + TailleBalle,YNew + TailleBalle);
  PosBalleX:= XNew;
  PosBalleY:= YNew;
end;

procedure TForm1.DessineRaquetteDroite(const YNew: Integer);
const
   RaqDrXPos = LargeurJeu - DecalageRaquette - TailleBalle;
begin
  if (YNew <= 0) or (YNew + RaqHauteur >= HauteurJeu) then
    Exit;
  Canvas.Brush.Color:=clBlack;
  Canvas.Rectangle(RaqDrXPos, PosRaqDrY, RaqDrXPos + TailleBalle, PosRaqDrY + RaqHauteur);
  Canvas.Brush.Color:=clWhite;
  Canvas.Rectangle(RaqDrXPos , YNew, RaqDrXPos + TailleBalle, YNew + RaqHauteur);
  PosRaqDrY:= YNew;
end;

procedure TForm1.DessineRaquetteGauche(const YNew: Integer);
const
  RaqGaXPos = DecalageRaquette;
begin
  if (YNew <= 0) or (YNew + RaqHauteur >= HauteurJeu) then
    Exit;
   Canvas.Brush.Color:=clBlack;
   Canvas.Rectangle(RaqGaXPos, PosRaqGaY, RaqGaXPos + TailleBalle, PosRaqGaY + RaqHauteur);
   Canvas.Brush.Color:=clWhite;
   Canvas.Rectangle( RaqGaXPos , YNew, RaqGaXPos + TailleBalle, YNew + RaqHauteur);
   PosRaqGaY:= YNew;
end;

procedure TForm1.NouveauService;
begin
  tmrMvtBalle.Enabled:= False;
  DessineFilet;
  AfficheScore;
  If (ScoreDroit >= 10) OR (ScoreGauche >= 10) then
    AnnoncerGagnant
  else
  begin
    DessineBalle (MiLargeur,MiHauteur);
    DessineRaquetteDroite (MiHauteur);
    DessineRaquetteGauche(MiHauteur);
    sleep(500);
    tmrMvtBalle.Enabled:= True;
  end;
end;

procedure TForm1.AfficheScore;
begin
  Canvas.Font.Name:= 'Courier New';
  Canvas.Font.Size:= 24;
  Canvas.Font.Style:=[fsBold];
  Canvas.Font.Color:= clWhite;
  Canvas.Brush.Color:= clBlack;
  Canvas.TextOut (MiLargeur - 50, 30, IntToStr(ScoreGauche));
  Canvas.TextOut (MiLargeur + 50, 30, IntToStr(ScoreDroit));
end;

procedure TForm1.AnnoncerGagnant;
begin
  tmrMvtBalle.Enabled:= False;
  Canvas.Font.Name:= 'Courier New';
  Canvas.Font.Size:= 48;
  Canvas.Font.Style:=[fsBold];
  Canvas.Font.Color:= clWhite;
  Canvas.Brush.Color:= clBlack;
  if ScoreGauche >= 10 then
    Canvas.TextOut (MiLargeur - 50 - Canvas.TextWidth('Gagnant'), 100, 'Gagnant')
  else
    Canvas.TextOut (MiLargeur + 50, 100, 'Gagnant');
  AfficherInstructions;
end;

procedure TForm1.DessineFilet;
var
  VarY: integer;
begin
   Canvas.Brush.Color:= ClBlack;
   Canvas.Rectangle (0,0,LargeurJeu,HauteurJeu);
   Canvas.Pen.Color:= clWhite;
   VarY:= 0;
   While VarY <= HauteurJeu do
   begin
     Canvas.Line(MiLargeur, VarY, MiLargeur, VarY + 20);
     Inc (VarY, 40);
   end;
   Canvas.Pen.Color:= clBlack;
end;

procedure TForm1.RestaurerEcran(const VarX, VarY: integer);
begin
  Canvas.Draw (VarX, VarY, SauveEcran);
end;

procedure TForm1.EnregistrerEcran(const VarX, VarY: integer);
begin
  SauveEcran.Canvas.CopyRect(
  Rect(0, 0, TailleBalle, TailleBalle),
  Canvas,
  Rect(VarX, VarY, VarX+TailleBalle, VarY+TailleBalle));
end;

procedure TForm1.AfficherInstructions;
begin
   Canvas.Font.Name:= 'Courier New';
   Canvas.Font.Size:= 24;
   Canvas.Font.Style:=[fsBold];
   Canvas.Font.Color:= clWhite;
   Canvas.Brush.Color:= clBlack;
   Canvas.Rectangle (140, 240, 700, 450);
   Canvas.Pen.Color:= clBlack ;
   Canvas.TextOut (150, 250, '<Espace> pour démarrer');
   Canvas.TextOut (150, 300, '<Echap> pour quitter');
   Canvas.TextOut (150, 350, '<F> et <S> raquette gauche');
   Canvas.TextOut (150, 400, '<M> et <K> raquette droite');
end;

end.

Le lecteur est maintenant à même de programmer ses propres projets !

___

Pour découvrir ou approfondir la programmation en langages Basic ou VBA (ces langages diffèrent du langage Pascal, toutefois les principes de programmation sont semblables) : 

Approfondir le sujet : Initiation au langage Basic (série d’articles) / Maîtriser le langage VBA

Share Button
The following two tabs change content below.
Benoît RIVIERE
Après seize années passées en cabinet d’expertise-comptable et de commissariat aux comptes (où j’ai exercé comme expert-comptable et chef de mission audit), j’ai pris le poste de directeur comptable d’un groupe de distribution automobile en novembre 2014. Au cours de ma carrière, j’ai acquis une expérience significative en audit et en exploitation des systèmes d’information (analyse de données, automatisation des tâches, programmation informatique) au service de la production des comptes annuels et consolidés. C’est cette expérience personnelle et ma passion pour l’informatique que je partage sur ce blog. Mon CV / Réalisations personnelles et projets informatiques / Ma collection / Me contacter

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.