souris

Les composants Delphi X

ou comment faire un jeu sous DELPHI

Ces composants peuvent être facilement remplacés par la librairie libre ZENGL, suite de Andorra 2D.

Le composant TDXDraw

    C’est l’écran qui va afficher les animations grâce à la commande flip. Pour afficher l’écran et les sprites il faut initialiser TDXDraw. La commande flip a pour utilité d’échanger l’écran d’affichage ( écran physique ) avec l’écran de travail ( écran logique ). Pour avoir une mise à jour régulière de l’écran il faut activer flip dans l’évènement ontimer de TDXTimer.

Le composant TDXTimer.

C’est donc le composant qui va régulièrement exécuter ce qui est introduit dans son évènement ontimer.

On y met donc tout ce qui concerne l’affichage, mais aussi l’ interrogation du clavier, les mouvements, la mise à jour des sprites:

procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);

begin

  DXInput.Update; // ça c’est le contrôle du joueur 1

  DXInput2.Update;// ça c’est le contrôle du joueur 2

  DXInput3.Update;// ça c’est le contrôle du joueur 3

  DXInput4.Update;// ça c’est le contrôle du joueur 4

  SpriteEngine.Move(Ralenti); // Anime les sprites

  SpriteEngine.Dead; // Détruit les sprites morts

  DXDraw.Surface.Draw(0,0,Fond.ClientRect, Fond, False);// Affiche un fond décran par dessus l’ancienne page de travail -> efface donc l’écran

   SpriteEngine.Draw;// Affiche tous les sprites créés dans TDXSpriteEngine

   with DXDraw.Surface.Canvas do //Manipule l’écran pour mettre du texte

   begin

     Brush.Style := bsClear; // style du texte

     Font.Color := clYellow; // Couleur du texte

     Font.Size := 15; // Taille du texte

     Textout(2, 10, IntToStr(Score));//+' Donnee : '+ inttoStr(NBPalettes)); // Affiche sous forme de texte des variables

   end;

end;

 

Le composant TDXDIB

C’est le composant qui sert à stocker une image BMP dans la mémoire. Toutes les images que vous mettrez en mémoire devront avoir la même palette. Pour résoudre ce problème facilement, il faut mettre l’affichage en 16 bits (plus de palette à charger). Généralement, il ne faut stocker que l’image de fond en mémoire. Mais vous devez charger à nouveau le fond en mémoire dans le composant TDirectDrawSurface :

      Fond := TDirectDrawSurface.Create(DXDraw.DDraw);

      {Affichage du fond dans l’évènement TDXTimer.ontimer}

      Fond.Free; Fond := nil;

      Le mieux est de désactiver TDXDIB quand vous ne l’utilisez pas.

Le composant TDXImageList.

Ce composant permet de stocker les sprites. Un sprite est défini par une image BMP chargée mais surtout par sa taille. La taille du sprite doit être exactement égale à la taille du sprite sur l’écran. Pour animer le sprite il faut d’abord commencer par aligner des bitmaps de même taille dans le bitmap du sprite. Ensuite la taille écran (width) doit être un multiple de 16 si par exemple le bitmap fait une largeur de 32 et que vous voulez avoir une animation de 2 sprites. Si par exemple vous avez dans le bitmap une largeur de 33 ou alors si vous avez mis une largeur de 17 pour les deux sprites, alors votre jeu plantera. Il faut donc essayer de lancer le jeu dès que vou n’êtes pas sûr de la taille (width ou height) d’un item de TDXImageList.

Le composant TDXSpriteEngine

La programmation des sprites sera ce qu’il y a de plus long à programmer. En effet le moteur de TDXSpriteEngine anime bien tous les sprites qui lui sont liés met il ne fait qu’appeler les procédures qui sont dans les sprites ou TimageSprite.

Pour commencer il faut quelques règles pour respecter un codage simple et facile à manipuler.

Tout d’abord, un sprite ne doit être appelé que par son composant TDXSpriteEngine. Si il devait être appelé autrement, ce serait par l’intelligence artificielle ou parce que c’est un joueur et encore.

En effet à partir du moment où une sprite est créé, il doit être entièrement autonome jusqu’à sa mort. Normalement le seul moment où vous le manipulez est quand vous le déclarez :

with TImageSprite.Create(DXSpriteEngine.Engine) do

 begin

 X:=30;Y:=40;

 End;

Destruction de tous les sprites pour changement de niveaux : SpriteEngine.Engine.Clear;

La façon dont vous ferez vos sprites sera hiérarchique : Un sprite quelconque aura la possibilité d’être descendant du sprite principal. Cela permet d’introduire des données supplémentaires dans vos sprites. Par exemple, le sprite TSpriteJoueur1 est descendant de TSpriteJoueur. Celui là est descendant de TSpritePrincipal qui lui est un TImageSprite.

Un sprite bouge par la méthode domove :

 TSpriteEnnemi = class(TSpritePrincipal)

   private

   procedure DoMove(MoveCount: Integer); override;

 end;

C’est une procédure propre à delphi x qui est appelée par TDXSpriteEngine.Move ou par Move du sprite.

C’est la procédure DoMove qui anime le sprite. Il est préférable de la mettre dans le sprite hérité qui sera créé. C’est pareil pour les méthodes DoCollision et Create. Ce que vous devez faire par contre pour éviter de saturer la mémoire, c’est de mettre les procédures de mouvement qui concernent tous les sprites ‘par exemple les détections de dépassement de l’écran) dans le TSpritePrincipal. Tout ce qui concerne les ennemis tels l’intelligence artificielle et ses pointeurs doivent être dans TSpriteEnnemi.

Voici par exemple le code d’une déclaration de balle :

type

TSpritePrincipal = class(TImageSprite)

  Procedure CreePrincipal; // procédure d’initialisation appelée par la méthode create située à la fin de la hiérarchie de sprites

 end;

TBalle = class(TSpritePrincipal)

   procedure DoMove(MoveCount: Integer); override; // A mettre à la fin de la hiérarchie

   procedure IntelligenceBalle; // Je l’ai ajoutée mais une balle n’en a que très peu

  procedure BallePlombNormal(Choix:integer);

  Procedure BalleFolle(Joueur : TSpriteJoueur);

   // Gestion des collisions

  procedure DoCollision(Sprite: TSprite; var Done: Boolean); override; // A mettre à la fin de la hiérarchie

  procedure Destruction; // procédure qui joue un son avant d’appeler le destructeur dead.

  public

   constructor Create(AParent: TSprite ); override; // A mettre à la fin de la hiérarchie

  end;

Les procédures Balle folle et balle plomb sont appelée par l’intelligence artificielle qui est appelée par DoMove.

La procédure DoCollision sère à détecter quels sprites ont été touchés. Il est préférable d’appeler DoCollision par la méthode Collision dans DoMove des sprites les moins nombreux à l’écran. Dans mon casse - briques, l’animation devenait trop lente quand les collisions étaient gérées par les briques. DoMove gère par ailleurs certaines des collisions. Par exemple les murs indélibiles.

La procédure Create sert à tout sauf à positionner le sprite sur l’écran. En effet le sprite n’étant pas tout seul, il faut pour chaque sprite créé le positionner après la méthode create. Par contre la méthode create gère le plan (propriété Z) dans lequel se trouve chaque type de sprite. D’ailleurs vous pouvez pour cette propriété décalerer des constantes qui serviront à identifier tous les plans de votre animation. La méthode contient l’initialisation du sprite : si il est visible (propriété visible), si il bouge (propriété Moved), si il est indépendant (propriété Collisioned) . Ou d’autres variables à intialiser : le compteur d’existence du sprite si  c’est une simple animation supplémentaire par exemple.

Le composant TDXInput

Ce composant gère les entrées donc le clavier, le joystick et enfin la souris. Les propiétés à connaître sont :

- TDXInput.Update : à mettre dans OnTimer de TDXTimer.

- TDXInput.States : état des boutons dont certains boutons de direction (clavier).

- TDXInput.X, TDXInput.Y : Déplacement à ajouter au déplacement du joueur.

- TDXInput.Mouse.Enabled : Active/désactive la souris.

- TDXInput.Joystick.Enabled : Active/désactive le joystick.

- TDXInput.Keyboard.Enabled : Active/désactive le clavier.

Le composant TDXSound

C’est le composant qui joue les sons. Il doit être relié à TDXDraw et il doit être initialisé par la commande TDXSound.initialize. L’idéal est de le désactiver dans une option du menu :

procedure TMainForm.OptionSoundClick(Sender: TObject);

begin

  {  Sound }

  OptionSound.Checked := not OptionSound.Checked;

 

  if OptionSound.Checked then

  begin

   if not DXSound.Initialized then

   begin

     try

       DXSound.Initialize;

     except

       OptionSound.Checked := False;

     end;

   end;

  end else

   DXSound.Finalize;

end;

Le composant TDXWave

Ce composant ne sert qu’ à jouer un son. Il est donc préférable d’utiliser TDXWaveList.

Le composant TDXWaveList

C’est l’idéal pour jouer un son. Il suffit d’actionner play sur le son pour le jouer :

procedure TMainForm.PlaySound(const Name: string; Wait: Boolean);

begin

  if OptionSound.Checked then

  begin

   DXWaveList.Items.Find(Name).play(Wait);

  end;

end;

Le composant TDXPaintBox

Ce composant est à utiliser pour récupérer des sprites par programmation. En effet ce composant dispose de méthodes supplémentaires pour dessiner mais ce n’est pas un composant d’animations. Certaines règles sont à respecter :

- Il faut que la palette soit uniformisée entre les différents TDXPaintBox pour ne pas s’apercevoir ensuite que les couleurs changent dans le sprite sauvegardé. Pour charge une image utiliser la méthode LoadFromFile. Pour sauvegarder le sprite récupéré sur la planche des sprites, il suffit d’utiliser la méthode SaveToFile. Ensuite il n’y a plus qu’à charger tous les sprites item par item par la méthode TDXImageList.Items.LoadFromFile. Enfin sauver tous les sprites (TDXimageList.LoadFromFile) dans un fichier DXG pour tous les récupérer par la méthode TDXimageList.LoadFromFile.

Le composant TDX3D

Ce composant ne m’a pas été utile. Mais si vous voulez l’utiliser il faut l’outil pour transformer les fichiers 3DS en fichiers X. D’autres outils aussi utiles se trouvent dans SDK de microsoft.

Le composant TDXPlay

Pour l’instant je n’arrive qu’à faire une CHAT avec. Mais je compte tester un programme de synchronisation de réseau.