Au lieu de l'avant-propos
À l'école d'Odessa, les élèves de 8e année dans les cours d'informatique utilisent l'environnement de développement multiplateforme Lazarus gratuit (
site officiel ), qui ressemble et ressemble beaucoup à la bien-aimée de nombreux Delphi, utilisant la version d'Object Pascal appelée Free Pascal et simplifiant vraiment considérablement le processus d'entrée en programmation.
Mais les enfants ne sont pas intéressés à écrire un programme de calcul de la gravité en utilisant la formule F = mg, qui leur est encore incompréhensible. Presque tous les enfants à qui j'ai essayé d'enseigner la programmation veulent écrire un jeu de la première leçon. Heureusement, Lazarus est idéal pour écrire des jeux simples.
Certes, pour créer des sprites animés, j'avais besoin d'un composant qui affiche un fragment arbitraire de l'image (qui représente plusieurs projections différentes du même personnage dans différentes phases de mouvement), mais il n'y a pas un tel composant dans la livraison standard. Il s'est avéré très facile de l'écrire vous-même, et je veux parler de cette technologie dans cet article.
Pour afficher un contenu graphique amusant au lieu d'un ensemble commercial sec de composants standard dans Lazarus (comme dans Delphi), il y a 3 composants sur l'onglet Supplémentaire:
- TImage (affichage d'une image à partir d'un fichier arbitraire);
- TShape (affichage de l'une des primitives graphiques prédéfinies);
- TPaintBox (affichant un canevas sur lequel vous pouvez dessiner par programmation).
La chose la plus spectaculaire pour un étudiant est de charger un petit sprite dans TImage et d'écrire un programme pour le déplacer sur l'écran - en fonction des événements de la souris / du clavier, automatiquement en boucle ou automatiquement par un événement d'une minuterie.
Dès que cela commence à fonctionner, l'étudiant a la question légitime suivante: est-il possible de faire bouger le personnage? Et est-il possible de faire en sorte qu'il ne nous regarde pas constamment, mais tourne dans le sens qui coïncide avec le sens du mouvement?
Sur le Web, vous pouvez trouver un grand nombre d'images prêtes à l'emploi à utiliser dans le développement de jeux. Et de nombreux personnages sont pré-conçus dans plusieurs projections et plusieurs images d'animation (comme, par exemple,
ici sur ce site ).
Voici un exemple d'image où les sprites sont disposés sous la forme d'un tableau, dans lequel chaque ligne correspond à une certaine projection, et chaque colonne correspond à une certaine phase d'animation:
Pourquoi tant de photos?Pour afficher un tel sprite, il suffit de placer à l'écran un composant simple qui n'affiche pas l'image entière, mais seulement un fragment de celle-ci; puis, en modifiant le décalage du fragment sélectionné horizontalement et verticalement, vous pouvez faire tourner le personnage dans différentes directions et effectuer des mouvements cycliques (par exemple, battre des ailes ou des pas avec des jambes). Cette technique est souvent utilisée dans le développement Web: même de simples ensembles d'icônes pour les graphiques commerciaux sont souvent placés dans un fichier et affichés à différents endroits sur des pages avec différents décalages, donnant l'impression de différentes images.
Malheureusement, le composant TImage, qui fait partie de la distribution standard Lazarus (et Delphi), ne permet pas d'afficher un fragment arbitraire d'une image: en modifiant ses propriétés, nous pouvons le forcer à n'afficher que l'image entière, le coin supérieur gauche ou sa partie centrale. Pour afficher un fragment arbitraire de l'image définie par le décalage et les dimensions le long des deux axes, vous avez besoin d'un autre composant. Mais, il s'est avéré que le faire vous-même à Lazare n'est pas difficile du tout!
Créer un nouveau composant
Comme instruction pour créer des composants, j'ai utilisé le
guide officiel .
Tout y est écrit avec suffisamment de détails, la duplication n'a pas de sens. Je ne m'attarderai que sur certains points.
1. L'assistant de projet standard ne nous propose pas de créer un package, et pour accéder en quelque sorte à l'éditeur, sélectionnez «Nouveau projet» (dans la version russe - «Nouveau projet»)
puis "Application" (dans la version russe - "Application"):
2. En agissant davantage selon les instructions, dans le menu "Package" (dans la version russe - "Package"), sélectionnez l'élément supérieur "Nouveau package ..." (dans la version russe - "Nouveau package ..."), sélectionnez le nom et le chemin du fichier pour sauver. J'ai nommé mon nouveau package «Game» et l'ai placé dans un dossier séparé du même nom:
J'ai créé un dossier Lazarus / Cmp distinct avec l'espoir d'avoir plusieurs packages différents avec des composants, et j'ai déjà créé le dossier «Game» dans ce dossier.
Si tout est fait correctement, une fenêtre d'un nouveau paquet (jusqu'ici vide) devrait apparaître à l'écran.
3. Continuez à nouveau selon les instructions, pour créer un nouveau composant dans la fenêtre du package, cliquez sur le bouton Ajouter (dans la version russe - "Ajouter") et sélectionnez "Nouveau composant" dans la liste déroulante (dans la version russe - "Nouveau composant"):
Nous spécifions TCustomImage comme classe ancêtre - cette classe est en fait utilisée pour implémenter le composant TImage, mais en diffère par le fait qu'elle ne contient pas de propriétés publiées et nous permet de déterminer l'ensemble de propriétés qui sera disponible dans le concepteur pour notre composant.
Quelles sont les propriétés publiées?Pour ceux qui ne le savent pas, je préciserai que publié est une section de la classe (comme public) qui décrit de nouvelles ou indique simplement des propriétés héritées qui devraient être disponibles dans l'éditeur de propriétés visuelles au stade du développement du programme. Les classes intermédiaires ne déclarent rien dans cette section, laissant au programmeur la possibilité de faire ressortir ce qu'il juge bon. Ainsi, la classe TImage n'ajoute aucune fonctionnalité, mais place uniquement un certain nombre de propriétés héritées du parent TCustomImage dans la section publiée. Nous devons masquer certaines de ces propriétés, nous allons donc hériter également de notre nouveau composant de TCustomImage et afficher uniquement ce qui ne contredit pas la logique de notre composant publié.
Icône (icône) pour le composantCe serait un bon style de dessiner une icône personnelle pour chaque nouveau composant, mais comme notre tâche est de montrer à quel point c'est simple, nous laisserons ce champ vide, ce qui conduira à l'icône standard utilisée dans Lazarus / Delphi pour tous les composants faits maison sur la barre d'outils .
Soit dit en passant, l'instruction mentionnée ci-dessus contient une section distincte sur la création d'icônes pour les composants - c'est pour ceux qui ne sont pas satisfaits de l'icône "par défaut".
Après avoir rempli tous les champs, cliquez sur le bouton «Créer un nouveau composant» (dans la version russe - «Créer un nouveau composant»).
Ajoutez du code au nouveau composant.
Immédiatement après la création d'un nouveau composant, son code source ressemble à ceci:
unit ImageFragment; {$mode objfpc}{$H+} interface uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs; type TImageFragment = class(TCustomImage) private protected public published end; procedure Register; implementation procedure Register; begin RegisterComponents('Game', [TImageFragment]); end; end.
Comme prévu, la déclaration de classe est complètement vide et il n'y a aucune implémentation. Tout ce qui est est la fonction d'enregistrement des composants sur l'onglet «Jeu».
Nous devons ajouter plusieurs propriétés publiées héritées, en créer deux et redéfinir une fonction virtuelle. Commençons!
0. Dans la section d'importation, nous avons besoin de deux modules supplémentaires: ExtCtrls et LCLProc - ajoutez-les à la section uses:
uses Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, ExtCtrls, LCLProc;
1. Ajoutez une liste de propriétés publiées qui est complètement similaire au composant TImage, à l'exception de quelques propriétés qui vous permettent de modifier l'échelle et la position de l'image:
published property AntialiasingMode; property Align; property Anchors;
Pour des raisons de persuasion, je n'ai pas supprimé, mais commenté les propriétés qui se trouvent dans le composant TImage, mais qui interfèrent dans notre nouveau composant TImageFragment.
2. Ajoutez deux nouvelles propriétés à la déclaration de classe pour définir les décalages d'image horizontaux et verticaux:
private FOffsetX: Integer; FOffsetY: Integer; procedure SetOffsetX(AValue: Integer); procedure SetOffsetY(AValue: Integer); published property OffsetX: Integer read FOffsetX write SetOffsetX default 0; property OffsetY: Integer read FOffsetY write SetOffsetY default 0;
et n'oubliez pas d'ajouter deux procédures déclarées à l'implémentation de la classe:
implementation procedure TImageFragment.SetOffsetX(AValue: Integer); begin if FOffsetX = AValue then exit; FOffsetX := AValue; PictureChanged(Self); end; procedure TImageFragment.SetOffsetY(AValue: Integer); begin if FOffsetY = AValue then exit; FOffsetY := AValue; PictureChanged(Self); end;
3. Nous redéfinissons la fonction virtuelle DestRect:
public function DestRect: TRect; override;
et ajouter son implémentation à l'implémentation de la classe:
function TImageFragment.DestRect: TRect; begin Result := inherited DestRect(); if (FOffsetX <> 0) or (FOffsetY <> 0) then LCLProc.OffsetRect(Result, -FOffsetX, -FOffsetY); end;
Compilez le paquet et reconstruisez Lazarus
1. Dans la fenêtre du package, cliquez sur le bouton "Compiler" (dans la version russe - "Compiler"). Si tout est fait correctement, un message vert sur la compilation réussie apparaîtra dans la fenêtre de message; sinon, le message sera jaune ou rouge.
2. Dans la même fenêtre, cliquez sur le bouton "Utiliser" (dans la version russe - "Utiliser") et sélectionnez le deuxième élément "Installer" dans le menu déroulant (dans la version russe - "Installer"). Le programme proposera de reconstruire et de redémarrer l'IDE - nous sommes d'accord:

3. Après le redémarrage, un nouvel onglet "Jeu" apparaîtra sur la barre d'outils, et sur celle-ci - une icône pour notre nouveau composant.
Au lieu d'une postface
Dans le prochain article de
Lazarus - une animation simple utilisant le composant TImageFragment, j'ai
expliqué comment utiliser un tel composant - en 5 minutes, créez une fenêtre dans laquelle le personnage animé se déplacera dans différentes directions et tournera dans la direction du mouvement.
Si le sujet est intéressant pour les lecteurs, je peux compléter cette série avec un article sur la façon dont, après avoir passé un peu plus de temps, vous pouvez créer, par exemple, un terrain de football avec quelques joueurs de football contrôlés par clavier.
Et s'il y a assez de temps et de désir - j'essaierai d'écrire différents algorithmes de contrôle des personnages (par exemple, des joueurs de football) et d'organiser des compétitions entre eux!