Le langage GameMaker (GML) a un certain nombre de caractéristiques qui font partie de la structure essentielle de tout le code écrit avec la langue. Chacun d'entre eux sera utilisé dans n'importe quel code que vous écrivez plusieurs fois, vous devez donc savoir ce qu'ils sont et comment ils fonctionnent avant de commencer à programmer un projet.
Une simple déclaration "if" prend cette forme:if (<expression>) <statement>
ou il peut avoir le formulaire "if... else..." légèrement plus complexe:if (<expression>) <statement> else <statement>
Dans ce cas, l'expression sera évaluée, et si la valeur (arrondie) est <= 0 ( false ) la déclaration après l'autre est exécutée, sinon ( true ) l'autre instruction est exécutée. C'est une bonne habitude de toujours mettre des accolades autour des instructions dans le if, et de prendre une nouvelle ligne dans le bloc pour chaque instruction, de sorte que le code de fin aura cette forme:if (<expression>)
{
<statement>
...
<statement>
}
else
{
<statement>
}
Comme un petit exemple, considérons le code suivant qui va déplacer l'instance vers la position x = 200 dans la pièce:if (x < 200)
{
x += 4;
}
else
{
x -= 4;
}
Notez que vous pouvez également effectuer des contrôles composés dans un if, c'est-à-dire: vérifier différentes valeurs ou expressions dans la même instruction. Lorsque vous effectuez cette opération, GameMaker Studio 2 évalue chacun d'entre eux un par un, et si l'un d'entre eux évalue à false, le reste sera ignoré. Par exemple:if (keyboard_check_pressed(vk_enter) && !instance_exists(obj_Player))
{
go = false
alarm[0] = room_speed
}
Vous pouvez également effectuer des opérations conditionnelles (aussi appelées opérations ternaires ), ce qui est essentiellement une manière "raccourcie" d'effectuer un "si" basique. Il a la syntaxe suivante:variable = condition ? <expression1 (if true)> : <expression2 (if false)>
L'opérateur conditionnel renvoie l'une des deux valeurs données selon que la condition évalue true ou false, par exemple:var temp_x = x < (room_width / 2) ? 32: room_width - 32;
Le code ci-dessus vérifiera la valeur de "x" par rapport à la moitié de la largeur de la pièce et, si elle est inférieure, mettra "temp_x" à 32 sinon "temp_x" sera room_width - 32. Voici quelques exemples de utilisation:draw_text(x, y, "The fee is " + (global.Member ? "$2.00" : "$10.00"));
path_start((global.level > 10 ? path_hard : path_easy;), 2, path_action_reverse, true);
--hp <= 0 ? instance_destroy() : score += 10;
Il est à noter que vous pouvez imbriquer des opérations conditionnelles mais que si vous le faites, chaque opération devra être placée entre parenthèses, par exemple:var c = a ? "foo" : (b ? "bar" : "wii"); // Correct
var c = a ? "foo" : b ? "bar" : "wii"; // Will cause an error
Une instruction "repeat" a la formerepeat (<expression>) <statement>
L'instruction est répétée le nombre de fois indiqué par la valeur arrondie de l'expression. Par exemple, le programme suivant crée cinq balles à des positions aléatoires.{
repeat (5) instance_create_layer(random(400), random(400), "Instances", obj_ball);
}
Cela peut être très utile pour éviter de taper plusieurs fois le même code, ou pour utiliser des tableaux, ou pour compter un certain nombre d'opérations etc... Par exemple:{
var i, total;
i = 0;
total = 0;
repeat (10)
{
total += array[i];
i += 1
}
draw_text(32, 32, total);
}
Une instruction "while" a la formewhile (<expression>) <statement>
Tant que l'expression est vraie, l'instruction (qui peut aussi être un bloc de code) est exécutée. Soyez prudent avec vos boucles while! Vous pouvez facilement créer des boucles infinies, auquel cas votre jeu se bloquera et ne réagira plus à aucune entrée utilisateur. Vous trouverez ci-dessous un exemple de façon typique d'utiliser "while":{
while (!place_free(x, y))
{
x = random(room_width);
y = random(room_height);
}
}
Le programme ci-dessus tente de placer l'objet courant à une position libre (c'est à peu près le même que l'action pour déplacer un objet à une position aléatoire).
Un "do" est vraiment l'instruction "do... until" car vous ne pouvez pas en avoir un sans l'autre. Il a cette forme:do <statement> until (<expression>)
L'instruction (qui peut également être un bloc de code) est exécutée jusqu'à ce que l'expression soit trouvée vraie, et l'instruction initiale est toujours exécutée au moins une fois. Soyez prudent avec vos boucles, car vous pouvez facilement les faire boucler pour toujours, auquel cas votre jeu se bloquera et ne réagira plus à aucune entrée utilisateur. Ci-dessous vous pouvez trouver un exemple d'une façon typique d'utiliser "faire... jusqu'à":{
do
{
x = random(room_width);
y = random(room_height);
}
until (place_free(x, y)); }
Le programme ci-dessus tente de placer l'objet courant à une position libre (c'est à peu près le même que l'action pour déplacer un objet à une position aléatoire).
Une instruction "for" a cette forme:for (<statement1> ; <expression> ;<statement2>) <statement3>
Cela fonctionne comme suit - First statement1 est exécuté, puis l'expression est évaluée et, si elle est vraie, l'instruction 3 est exécutée. Ensuite, l'instruction 2, puis l'expression est évaluée à nouveau. Cette boucle continuera jusqu'à ce que l'expression soit fausse.
Maintenant, cela peut sembler compliqué lorsqu'il est écrit comme ça, mais vous devriez l'interpréter comme:C'est extrêmement utile pour effectuer des tâches répétitives qui impliqueraient plusieurs lignes de code d'une autre manière, et est couramment utilisé comme un compteur pour évaluer des tableaux, ou dessiner des choses. l'exemple de code suivant illustre une utilisation typique pour ce type d'instruction:
- La première instruction initialise la boucle for.
- L'expression teste si la boucle doit être terminée.
- Statement2 est l'instruction "step" qui va à l'évaluation de la boucle suivante.
{
for (var i = 0; i < 10; i += 1)
{
draw_text(32, 32 + (i * 32), string(i) + ". "+ string(scr[i]));
}
}
Le code ci-dessus initialise une boucle for, commençant à 0 et comptant jusqu'à 9, puis utilise la valeur de boucle de "i" pour dessiner les valeurs stockées dans un tableau en bas de l'écran. Notez comment la variable de boucle "for" "i" est utilisée non seulement pour parcourir le tableau, mais aussi pour dessiner un nombre et indiquer à GameMaker Studio 2 où dessiner les valeurs dans la pièce. Cette flexibilité est l'une des principales raisons pour lesquelles les boucles "for" sont si importantes dans la programmation.
Dans un certain nombre de situations, vous souhaitez laisser vos instances effectuer une action en fonction d'une valeur particulière. Vous pouvez le faire en utilisant un certain nombre de " if "instructions mais quand les choix possibles sont au-dessus de deux ou trois, il est généralement plus facile d'utiliser l'instruction" switch ".switch (<expression>)
{
case <expression1>: <statement1>; ... ; break;
case <expression2>: <statement2>; ... ; break;
...
default: <statement>;
}
Cela fonctionne comme suit:Notez que plusieurs instructions de requête peuvent être placées pour la même instruction. En outre, la rupture n'est pas requise et s'il n'y a pas d'instruction break, l'exécution continue simplement avec le code de l'instruction case suivante. Cela signifie que vous pouvez créer un "commutateur" de hiérarchie dans lequel différentes sections de code sont exécutées en fonction de la valeur d'entrée. voici un exemple de "switch" typique d'un jeu:
- D'abord l'expression est exécutée.
- Ensuite, il est comparé avec les résultats des différentes expressions après chacune des déclarations de cas.
- L'exécution continue après la première instruction case avec la valeur correcte, jusqu'à ce qu'une instruction break soit rencontrée.
- Si aucune instruction case n'a la bonne valeur, l'exécution est poursuivie après l'instruction default (il n'est pas obligatoire d'avoir une déclaration par défaut, auquel cas aucune action ne sera prise).
{
switch (keyboard_key)
{
case vk_left:
case ord("A"):
x -= 4;
break;
case vk_right:
case ord("D"):
x += 4;
break;
case vk_up:
case ord("W"):
y -= 4;
break;
case vk_down:
case ord("S"):
y += 4;
break;
}
}
Le code ci-dessus utilise "switch" pour vérifier un événement de clavier, puis compare cela aux cas répertoriés. S'il répond à l'une des valeurs requises, le code correspondant est exécuté. Notez comment dans le code nous avons utilisé la façon dont "switch" peut vérifier plusieurs cas et continuer si aucune rupture n'est rencontrée pour permettre à différentes clés d'être utilisées pour obtenir le même résultat. Ceci est juste l'un des moyens que vous pouvez autoriser plusieurs configurations pour le mouvement dans vos jeux.
L'instruction "break" est utilisée pour terminer prématurément un for, repeat, while, do... until boucle d'une sorte, ou de dire un switch déclaration à mettre fin à ce moment-là, ou de mettre fin prématurément à un with appel. Ci-dessous vous pouvez voir quelques exemples de comment cela peut être utilisé, et sa syntaxe est simple:break;
"break" dans un for boucle:
{
var i;
for (i = 0; i < 10; i += 1)
{
if array[i] = 234 break;
}
num = i;
}
"break" dans un repeat boucle:{
var i, temp;
i = 0;
temp = 0;
repeat (10)
{
temp += array[i];
if temp > max_total break else i += 1;
}
}
"break" dans un while boucle:{
var i;
i = 0;
while (!place_free(x, y))
{
x = random(room_width);
y = random(room_height);
if i > 50 break else i+=1;
}
}
"pause" lors de l'utilisation with:{
var count = 0;
with (obj_Enemy)
{
count++;
if count > 10 break;
hp = 100;
}
}
L'instruction continue a la forme:continue
Si utilisé à l'intérieur d'une instruction formant une boucle ( repeat, while, do... until ou for ), il retournera immédiatement au début de la boucle comme si la boucle avait traversé et rebouclé (s'il est utilisé en dehors d'une boucle, il agit comme un exit déclaration, sortie de l'événement). Il fera également la même chose en utilisant le with fonction, où le code passe à l'instance suivante et s'exécute à nouveau.
Voici un exemple de son utilisation dans une boucle "for":{
var i;
for (i = 0; i < 10; i += 1)
{
if array[i] = "" continue;
array[i] = "";
}
}
Le code ci-dessus reviendra au début de la boucle si la valeur du tableau [i] est déjà une chaîne vide.
L'instruction de sortie a la forme suivante:exit;
"Exit" termine simplement l'exécution du script ou de l'événement en cours. Notez qu'il existe une légère différence d'utilisation ici en fonction de la portée: si vous utilisez exit dans un script est simplement quitter le script et retourner au code qui a appelé le script, cependant si vous utilisez cet événement dans un bloc de code depuis un objet, il quittera l'événement entier même s'il y a plusieurs blocs de code séparés après le la fonction a été appelée. Généralement, il est utilisé pour éviter une instance exécutant un bloc de code spécifique, par exemple un événement de collision. Le code ci-dessous en donne un exemple simple:{
if !visible exit;
while (place_meeting(x, y))
{
x -= lengthdir_x(1, direction - 180);
y -= lengthdir_y(1, direction - 180);
}
}
Le code ci-dessus vérifie une variable et si elle se résout à vrai, alors il existe le bloc de code, sinon il va de l'avant et exécute le reste du code.Note: Cela ne met pas fin à l'exécution du jeu. Pour cela, vous devez utiliser la fonction game_end.
Comme indiqué dans la section Adressage des variables dans d'autres instances, il est possible de lire et de modifier la valeur des variables dans d'autres instances. Mais dans un certain nombre de cas, vous voulez faire beaucoup plus que juste changer une seule variable avec ces autres instances. Par exemple, imaginez que vous voulez déplacer tous les objets de la balle dans votre jeu de 8 pixels. Vous pouvez penser que cela est réalisé simplement par le morceau de code suivant:obj_ball.y = obj_ball.y + 8;
Mais ce n'est pas correct, car le côté droit de l'assignation obtient la valeur de la coordonnée y de la première boule et lui ajoute 8. Ensuite, cette nouvelle valeur est définie en tant que coordonnée y de toutes les billes, de sorte que toutes les billes ont la même coordonnée y, et même si vous utilisez ce qui suit:obj_ball.y += 8;
cela aura exactement le même effet parce que c'est simplement une abréviation de la première déclaration. Alors, comment pouvons - nous y parvenir? Pour cela, il existe l'instruction with dans GML. Sa forme globale est:with (<expression>) <statement>
<Expression> indique une ou plusieurs instances, et pour cela vous pouvez utiliser un identifiant d'instance, le nom d'un objet (qui indique que toutes les instances de cet objet doivent exécuter le bloc de code) ou l'un des mots-clés spéciaux ( all, self, autre ). <Instruction> est maintenant exécuté pour chacune des instances indiquées, comme si cette instance était l'instance (auto) actuelle. Ainsi, pour déplacer toutes les instances de l'objet boule de 8 pixels vers le bas, vous pouvez taper:with (obj_ball) y += 8;
Si vous voulez exécuter plusieurs instructions, placez des accolades autour d'elles, comme vous le feriez pour n'importe quel autre programme. Ainsi, par exemple, pour déplacer toutes les balles dans une position aléatoire, vous pouvez utiliser:with (obj_ball)
{
x = random(room_width);
y = random(room_height);
}
Notez que, dans les instructions, l'instance indiquée est devenue l'instance (auto) cible qui exécute le bloc de code, ce qui signifie que les instructions de l'instance d'origine (qui contient le "avec" et le bloc de code) sont devenues autre instance. Par exemple, pour déplacer toutes les balles à la position de l'instance en cours, vous pouvez taper ceci:with (obj_ball) { x = other.x; y = other.y; }
L'instruction with est un outil extrêmement puissant et utile dans de nombreuses circonstances, il est donc important que vous compreniez parfaitement comment il peut être utilisé. Pour aider, voici quelques autres exemples d'utilisation:with (instance_create_layer(x, y, "Instances", obj_Ball))
{
speed = other.speed;
direction = other.direction;
}
Le code ci-dessus crée une instance de obj_Ball et lui assigne la vitesse et la direction de l'instance qui exécute le bloc de code entier.with (instance_nearest(x, y, obj_Ball))
{
instance_destroy();
}
Le code ci-dessus détruira l'instance d'obj_Ball la plus proche de l'instance exécutant le code.var inst;
inst = noone;
with (obj_ball)
{
if str > other.str inst = id;
}
if inst != noone target = inst;
Le code ci-dessus est légèrement plus complexe que les précédents en raison de l'utilisation d'une variable locale. Cette variable est locale au script et non à l'instance et peut donc être utilisée et accédée par toutes les instances référencées dans le bloc de code. Donc, dans le code, nous l'avons défini sur le mot-clé spécial noone, puis utilisez la construction "with" pour que chaque instance de obj_Ball vérifie leur variable "str" par rapport à celle de l'instance exécutant le bloc de code. Si la valeur de la variable est plus grande, ils stockent leur identifiant unique dans la variable locale "inst", ce qui signifie qu'à la fin du code, seule l'instance avec une valeur supérieure à l'instance appelante (ou le mot - clé noone si aucun sont plus grands) seront stockés dans la variable locale inst. Pour plus d'informations sur les variables locales, voir la section Variables Et variable Portée.
L'instruction de retour a la forme:return (<expression>)
Vous utilisez uniquement le return déclaration dans les scripts, et il est utilisé pour renvoyer une valeur du script à utiliser dans d'autres appels de code ou de script. Il convient de noter que l' exécution du script se termine à l'instruction return, ce qui signifie que tout code qui vient après que le retour a été appelé ne sera pas exécuté. Voici un court exemple de script appelé " scr_sqr "qui calcule le carré de la valeur qui lui est transmise, et il inclut l'erreur catching au cas où l'argument qu'il est passé n'est pas un nombre réel:{
if !is_real(argument0)
{
return 0;
}
else
{
return (argument0 * argument0);
}
}
Pour appeler un script à l'intérieur d'un code, agissez de la même manière que lorsque vous appelez des fonctions, c'est-à-dire, écrivez le nom du script avec les valeurs d'argument entre parenthèses. Donc, le script ci-dessus serait appelé comme ceci:if keyboard_check_pressed(vk_enter)
{
val = scr_sqr(amount);
}