Rechercher - Liste des utilisateurs
Version complète : A.A.A. (Aides Aux Apprentis)
Accueil » FunDelphi » A.A.A. (Aides Aux Apprentis)
1 2 3
sjrd
Oui, et même avec ça, tu ne pourrais pas encore passer depuis de l'Herbe vers un Mon herbe !
Pour ça il faut jouer sur Kind = pmkArriveAt en plus de pmkLeaveFrom, en remplaçant Dest par Src dans les tests de la première ligne.
DerF_44
Oui, on est tout à fait hors sujet là, vu la complexité du code !
C'est d'ailleurs un petit paradoxe de FunDelphi :
Avec quelques notions, ce language permet de faire des choses relativement complexes avec du code relativement simple,
mais là, pour le coup, afin de juste supprimer une carctéristique particulière (les fondus entre terrain et eau)
il est nécessaire d'écrire 15 lignes !!!
Que les lecteurs apprentis se rassurent, cela reste assez rare !

Je re-livre, malgré tout, pour les curieux, le code d'un terrain qui accepte la planche sans fondus avec l'eau ou les trous :

unit AAA;

uses
FunLabyBase;

components
MyGrass: TMyGrass;

field TMyGrass
name 'Mon herbe';
image 'GreenGrass';

on message Plank do
var
Map: TMap;
begin
Map := Master.Map['MainMap'];
if Kind = pmkLeaveFrom then
begin
Result := ((Map[Dest].Field is TMyGrass) or (Map[Dest].Field is TGround)) and
(Map[Src].Obstacle = nil) and (Map[Dest].Obstacle = nil);
end;
if Kind = pmkArriveAt then
begin
Result := ((Map[Src].Field is TMyGrass) or (Map[Src].Field is TGround)) and
(Map[Src].Obstacle = nil) and (Map[Dest].Obstacle = nil);
end;
end;
end;

end.
DerF_44
Revenons à nos A.A.A. avec cette fois-ci :

Un terrain inaccessible :

Nous avons vu que, par défaut, la description d'un terrain ne contenant que son ID (MyGrass), son nom (Mon herbe)
et son image le représentant (GreenGrass) était praticable par le joueur, qu'il pouvait entrer dessus..
Afin de l'en empêcher nous allons utiliser l'instruction Entering, que l'on pourrait traduire par ‘'En train d’entrer''..
(le joueur n'est pas encore sur la case, c'est son intention qui voudrait le placer dessus !)
Pour cet exemple nous allons utiliser une image de la Library, celle du mur rouge sombre (FireWall) qui se situe dans le dossier d'images “Fields”..

unit AAA;

uses
FunLabyBase;

components
MyWall: TMyWall;

field TMyWall
name 'Mon mur';
image 'Fields/FireWall';

on Entering do
begin
inherited;
Cancel;
end;
end;

end.

Grâce au mot-clé Cancel, l'intention du joueur d'entrer sur le terrain sera immédiatement avortée,
il ne pourra pas se placer dessus, il restera bloqué par Mon mur !.
DerF_44
Puisque la ligne de code on Entering do permet de créer des événements
lorsque le joueur tente de pénétrer sur le terrain, nous pourrions tout à fait lui annoncer
qu'il a affaire à un mur… (Avant de le laisser sur place par Cancel) :

on Entering do
begin
inherited;
Player.ShowMessage('Tu n''es pas un fantôme, impossible de traverser ce mur !');
Cancel;
end;

Un petit mystère : À l'enregistrement du code source du même mur créé en .ssq,
"if KeyPressed then" est placé juste avant le message !?.
J'aimerai donc bien connaître la subtile différence qui existe entre les deux méthodes,
et si il y a un inconvénient de s'affranchir de cette ligne de code supplémentaire !?.
sjrd
KeyPressed est une propriété qui sera True (vraie) si la tentative du mouvement a été provoquée par l'appui sur une touche du clavier. Elle sera False (fausse) dans le cas contraire, par exemple si une flèche tente de pousser le joueur vers le mur.

Il est d'usage, dans FunLabyrinthe, de ne pas afficher ce type de message “d'échec” lorsque KeyPressed vaut False. C'est particulièrement important pour les tourniquets, qui, en cas d'échec, vont “voir plus loin”. On obtient cet effet avec le test :
if KeyPressed then
Player.ShowMessage('...');

DerF_44
C'est d'ailleurs un petit paradoxe de FunDelphi :
Avec quelques notions, ce language permet de faire des choses relativement complexes avec du code relativement simple,
mais là, pour le coup, afin de juste supprimer une carctéristique particulière (les fondus entre terrain et eau)
il est nécessaire d'écrire 15 lignes !!!
Oui, je suis d'accord. FunLabyrinthe 5 a été un énorme progrès par rapport aux versions 1-4, en matière de possibilités. Et les choses qui extrêmement difficiles (mais possibles et faites) à faire ont reçus un support dédié dans FL 5, ce qui les rend assez simples à réaliser.
Le revers de la médaille, c'est que du coup, on a envie d'en faire encore plus. Et là de nouveau on rencontre des difficultés.
DerF_44
Ok !. Merci de la précision.
Reprenons le code initial de notre mur qui parle, agrémenté de cette vérification if KeyPressed

Un terrain inaccessible + message :

unit AAA;

uses
FunLabyBase;

components
MyWall: TMyWall;

field TMyWall
name 'Mon mur';
image 'Fields/FireWall';

on Entering do
begin
inherited;
if KeyPressed then
Player.ShowMessage('Tu n''es pas un fantôme, impossible de traverser ce mur !');
Cancel;
end;
end;

end.

Ainsi, si c'est bien l'intention du joueur de tenter de pénétrer sur le terrain (par l'appui sur une touche du clavier) le message sera affiché.
Si c'est un effet de direction (flèches ou tourniquets) qui le projette sur le mur, point de message.
DerF_44
Nous allons aborder ici une fonctionnalité riche en possibles et très facile à mettre en œuvre : les property !
(''properties'' au pluriel, mais je préfère conserver le mot-clé, au singulier)

C'est une propriété spécifique à un élément qui va contenir une variable de type integer (un nombre entier) ou boolean (vrai ou faux).
(Il existe certainement d'autres types de variables possibles, mais cela dépasse mes modestes connaissances.)

Reconsidérons notre mur qui annonce de manière frustrante et répétitive que le joueur n'est pas un fantôme !..
Si le joueur se trouve dans un labyrinthe comportant des passages secrets,
cela va être relativement pénible de s'entendre dire à chaque appui sur MyWall qu'il ne peut le franchir !..
Nous allons donc introduire une propriété de notre terrain (notre mur) qui va compter le nombre de fois où le joueur tente d'y entrer !.
Après cela, comme nous allons le voir, différentes possibilités de gestion du message s'offrent à nous.

(C'est là qu'intervient mon côté non-anglophone, puisque je vais nommer cette property ''NbOfTouched'' !. Il doit y avoir plus pertinent et plus joli comme nom !!).

Un terrain inaccessible + message conditionnel :

field TMyWall
name 'Mon mur';
image 'Fields/FireWall';

property NbOfTouched: Integer;

on Entering do
begin
inherited;
if KeyPressed then
begin
if NbOfTouched = 0 then
Player.ShowMessage('Tu n''es pas un fantôme, impossible de traverser ce mur !');
NbOfTouched := NbOfTouched + 1;
end;
Cancel;
end;
end;

Que se passe-t-il !?..
Lorsque le joueur tente d'entrer sur le terrain par sa volonté (il a appuyé sur une touche)
il y a un test de valeur de notre property, si cette valeur est égale à 0, le message est affiché..
Ensuite, la valeur de NbOfTouched est augmentée de 1..
Du coup, à la prochaine tentative d'entrer sur le terrain, il n'y aura plus de message puisque la valeur de notre property ne vaut plus 0 !
Nous avons donc ici un mur qui livre son message qu'à la première tentative du joueur !

Dans le cas d'un labyrinthe compliqué, comportant de nombreux murs différents,
il pourrait être judicieux d'avertir régulièrement le joueur qu'il ne peut franchir MyWall,
pas de manière systématique, à chaque tentative, mais de temps en temps,
disons toutes les 5 tentatives de pénétrer sur le terrain…
Très facile !.
Puisque notre mur possède un compteur, il suffit de tester si sa valeur à atteint la limite désirée
et, si c'est le cas, de réinitialiser le compteur à 0 :

on Entering do
begin
inherited;
if KeyPressed then
begin
if NbOfTouched = 0 then
Player.ShowMessage('Tu n''es pas un fantôme, impossible de traverser ce mur !');
NbOfTouched := NbOfTouched + 1;
if NbOfTouched = 5 then
NbOfTouched := 0;
end;
Cancel;
end;


Remarque :
if LaCondition then
Une seule ligne de code exécutée si LaCondition est vraie;
if LaCondition then
begin
Plusieurs lignes de code exécutées si LaCondition est vraie;
Plusieurs lignes de code exécutées si LaCondition est vraie;
end;
DerF_44
Après avoir utilisé une instruction permettant de gérer les événements qui surviennent lorsque
le joueur tente d'entrer sur un terrain, nous allons nous pencher sur la fonction inverse,
créer des événements lorsque le joueur à quitté le terrain..
Grâce à on Exited do, nous allons fabriquer de l'herbe magique qui se transforme en eau lorsque le joueur a marché dessus !.

De l'herbe magique :

Le code est très simple :

unit AAA;

uses
FunLabyBase;

components
MagicGrass: TMagicGrass;

field TMagicGrass
name 'Herbe magique';
image 'Fields/Meadow';

on Exited do
begin
Square := Water;
end;
end;

end.

Après avoir déclaré notre terrain MagicGrass, lui avoir attribué un nom et une image,
on décrit son comportement lorsque le joueur l'a quitté…
Le mot-clé Square permet de prendre en considération la case où se trouve le joueur,
plus exactement dans ce cas la case où il se trouvait !.
DerF_44
L'orsque j'ai commencé d'élaborer des labyrinthes,
j'ai souvent souhaité cacher des blocs en or, les dissimuler par un passage secret !.
Mais, au sein de l'éditeur, impossible de poser un obstacle sur un autre..
Grâce au FunDelphi, cela est tout à fait possible et de manière très simple..

Bloc en or secret :

unit AAA;

uses
FunLabyBase;

components
SecretGoldenBlock: TSecretGoldenBlock;

obstacle TSecretGoldenBlock
name 'Bloc or caché';
image 'Fields/Wall';

on AfterConstruction do
begin
inherited;
EditVisualTag := 'or';
end;

on Pushing do
begin
inherited;
if not KeyPressed then
Exit;
Square.Obstacle := nil;
Square.Obstacle := GoldenBlock;
end;
end;

Le groupe d'instructions on AfterConstruction do permet de taguer l'obstacle par le mot “or”,
afin de le différencier d'un mur normal au sein de l'éditeur..
Nous avons vu qu'avec les terrains nous pouvions décrire des événements lorsque que le joueur
tente d'entrer sur le terrain (on Entering do) ou qu'il en est sorti (on Exited do)..
Avec les obstacles, c'est l'action “en train de pousser” (on Pushing do) que nous utiliserons.
L'instruction “if not KeyPressed then Exit” permet de s'assurer que c'est bien le joueur qui pousse sur l'obstacle,
(dans le cas contraire, par exemple flèches ou tourniquets qui pousse le joueur, le bloc en or ne sera pas dévoilé)
Square.Obstacle := nil élimine l'obstacle,
pour le remplacer instantanément par un bloc en or : Square.Obstacle := GoldenBlock
sjrd
L'instruction “Square.Obstacle := nil;” n'est pas nécessaire, puisque l'obstacle est quand même remplacé par GoldenBlock juste après. Comme une case ne peut avoir deux obstacle, l'instruction “Square.Obstacle := GoldenBlock” seule remplacera l'obstacle par un bloc en or.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB