AccueilAccueil  FAQFAQ  RechercherRechercher  Dernières imagesDernières images  S'enregistrerS'enregistrer  Connexion  
Le deal à ne pas rater :
Coffret dresseur d’élite ETB Pokémon EV06 Mascarade Crépusculaire
56.90 €
Voir le deal

 

 [Tutoriel] Les déplacements en GML et sans bogues.

Aller en bas 
2 participants
AuteurMessage
Caly
Utilisateur confirmé: Rang ****
Caly


Messages : 1285
Localisation : Haute Normandie
Projet Actuel : Capturer, apprivoiser et dresser des Pokémons sauvages pour faire des spectacles de rue et en faire mon métier.

tutoriel plateform - [Tutoriel] Les déplacements en GML et sans bogues. Empty
MessageSujet: [Tutoriel] Les déplacements en GML et sans bogues.   tutoriel plateform - [Tutoriel] Les déplacements en GML et sans bogues. EmptyDim 23 Oct 2011 - 21:29

Bonjour,

Quant on commence dans "Game Maker" on a tendance à utiliser le drag&drop (sélectionner et déplacer) et les variables/fonctions de déplacements natives.
-hspeed
-vspeed
-speed
-friction
-motion_set(dir, speed)
-motion_add(dir, speed)
-etc...

Malheureusement ces fonctions sont source de pas mal de problèmes dans les projets.
Et on se retrouve vite bloqué par des bogues dans notre jeu.

Cela s'explique avec deux raisons principales:

- La première est que les variables de déplacements de GM sont des valeurs flottantes, c'est à dire que c'est des valeurs avec des virgules.

Les conséquences de ce problème c'est que quant on veux qu'un objet se rende à une position bien précise hé bien notre objet va se mettre à trembler quant il se retrouve proche de la position qu'on a fixée.


- La seconde quant à elle est que GM vérifie les collisions après les déplacements.

Donc quant on se déplace à droite et que la place n'est pas libre, voilà ce qui se passe si on utilise les fonctions de déplacements de GM:
-On se déplace.
-On est en collision avec un objet solide.
-On "rebondi" sur cet objet et on fini par revenir à notre position d'origine.

Le problème c'est que parfois on ne "rebondi" pas et on se retrouve bloqué, malheureusement nombreux sont les jeux réalisés sous GM où ce bogue est présent.


Pour régler ces deux défauts et bien d'autres sources de problèmes des variables/fonctions et D&D de GM je vais vous expliquer certaines méthodes.

____


Pour les problèmes des positions flottantes il existe une solution simple, il s'agit d'arrondir les positions de l'objet concerné.
Pour ce faire on va utiliser la fonction "floor(x)", cette fonction retourne la valeur plancher de x à l'entier inférieur.

Dons si la position est "15,6" et qu'on lui applique un "floor" cette valeur vaudra "15".

Oui mais je le met où ce "floor" moi? rouge

Bonne question, il va y avoir deux solutions.
Cela va dépendre si ce code va être utilisé par un objet ou par plusieurs, car un bon développeur et un développeur "fainéant", et ça il faut le retenir à chaque fois que vous programmez.
Il ne faut jamais coder deux fois la même chose.
Si dans votre projet il y a deux fois la même ligne de code c'est qu'il y a une meilleur façon de faire.

Donc si le code va être utiliser pour un seul objet on va le mettre dans une "action" de l'objet en question, cette action se trouve dans l'onglet "Control" et se nome "Execute a piece of code".

Et si le code est utilisé par plusieurs objets on va le placer dans un "script".
Pour avoir accès aux "scripts" il faut cependant être dans le mode avancé (File -> Advanced Mode).

Exemple pour créer un script:
Donc créez un nouveau "script" et donnez lui un nom explicite, par exemple "scr_gravite".
Ensuite si vous voulez l'utiliser dans un objet il suffis d'écrire "scr_gravite();" dans un "execute a piece code" dans ce dit objet.


Si vous êtes attentif vous avez dût voir que "floor" contient une paire de parenthèse, comme "scr_gravite();" que je viens de vous montrer, ce qui veux dire que "floor" est lui même un "script" plus communément appelé "fonction" dans le monde de la programmation.

Maintenant que vous savez où placer vos codes on reviens à notre "floor()".

Donc pour que la position d'un objet ne soit pas un flottant on va mettre ceci dans son "Step" ou "Draw" ou dans un "Script".

Code:

x=floor(x);
y=floor(y);

Heu, on a vus à quoi sert "floor" mais le reste c'est quoi ?

Et bien "x" et une variable native qui représente l'abscisse de la position de votre objet et y l'ordonnée en sachant que l'origine(0/0) est le coin supérieur gauche de la "room".

Pour ce qui est du point virgule en fin d'instruction il est là justement pour dire que l'instruction est fini.
Ce point virgule n'est pas une obligation en GML mais il l'est dans beaucoup d'autres langages informatique, je vous conseille donc de prendre l’habitude de le mettre systématiquement au cas ou vous veniez à programmer sous un autre langage.

C'est quoi une instruction?

Une instruction c'est en quelque sorte un ordre.
On donne un ordre à l'ordinateur et quant on fini de le décrire on met notre point virgule pour dire "voilà c'est bon tu peut le faire".

Donc si on résume ce code avec comme valeur x = 158.48 et y = 509.02 ce petit bout de code va placer notre objet en 158/509, ce qui évite pas mal de bogues.

Passons maintenant aux déplacements avec collisions, que beaucoup de monde redoute mais qui n'est en somme pas du tout difficile.

Donc voici comment déplacer un objet horizontalement vers la droite:
Code:
x = x+6;
Je pense que je n'ai pas besoin d'expliquer ce code si vous avez bien suivi jusqu'ici.
Cependant vus qu'un développeur se doit d'être fainéant il y a plus cour.
Code:
x +=6;
Ces deux codes sont exactement les mêmes mais le second est plus rapide à écrire.
Si vous avez compris le principe vous savez maintenant comment procéder pour un déplacement vers la gauche:
Spoiler:

Le chiffre 6 est le nombre de pixel qu'on se déplace, on peut donc le changer pour aller plus vite ou moins vite.
On peut même le mettre dans une variable et c'est ce que nous allons faire.
On va donc la créer dans l’évènement "create" pour éviter de la déclarer (assigner sa valeur) à chaque step alors que sa valeur ne change pas pour cet exemple.

create:
Code:
vitesse = 6;

step:
Code:
x+=vitesse;

Reste cependant le soucis des flottants, il ne devrait pas y en avoir dans ce code mais par sécurité on va appliquer un "floor" pour en être réelment sûr.

Code:
x = floor(x+vitesse);

Je vous laisse exécuter votre projet, et vous constaterez que votre objet va se déplacer de 6 pixels par step vers la droite.

Reste maintenant à le stopper s'il se trouve à coter d'un objet solide.

Il va nous falloir apprendre une nouvelle fonction:
"place_free(x, y)"
Cette fonction retourne si l'instance placée à la position (x,y) est en collision avec une instance "solide".
A noter que vous avez un très bon tutoriel de M@d_Doc sur les collisions ici : Les collisions en gml.

On va donc écrire quelque chose du genre :

"S'il n'y a rien à coter de x on déplace l'objet".

Ce qui donne:
Code:
if( place_free(x+1,y) ){
    x = floor(x+vitesse);
}

Ce code fonctionne très bien dans la plupart des cas mais malheureusement il a un défaut.

On vérifie s'il y a un objet à un pixel de x mais on le déplace de 6 pixels.
Ce qui fait que s'il y a un objet de 3 pixels à 2 pixels de x et bien on va passer à travers.

Pour remédier à ça on va utiliser une boucle qui va déplacer notre objet pixel par pixel tant qu’il n'y a pas d'objet solide à coter de x et qu'on ne dépasse pas les 6 pixels (vitesse).
Code:
var i;
for( i=0; place_free(x+1,y) and i<vitesse; i+=1){
    x = floor(x+vitesse);
}

Tadam; on y est, un déplacement garanti sans bogues Wink
Je vais cependant vous expliquer les nouveaux éléments dans ce code .

"var" est un mot clef qui sert à "détruire" la/les variable(s) initialisée(s) dans son instruction à la fin de l’évènement.

"i" est le nom des variables généralement utilisés dans les boucles, vous pouvez utiliser n'importe qu'elle nom mais je vous conseille d'utiliser "i" pour que vos codes ressembles aux autres et qu'on comprenne votre code plus facilement si vous nous le montrez.

"for" est une boucle.
Je vous laisse regarder la doc ici pour comprendre comment elle fonctionne.

Voilà, normalement si vous avez bien lus et si vous êtes attentif vous devriez avoir compris ce code.

Merci, donc je n'ai plus qu'à mettre ce code dans l’évènement "Keyboard events" et c'est bon Smile

En fait oui et non.
C'est une possibilité mais votre code va être séparé dans plusieurs évènements et vous aller vite ne plus vous retrouver dans tout ça.

Pour remédier à ça on va donc utiliser une condition et une autre fonction:
"keyboard_check(key)" expliqué ici.

Ce qui donne ça :
Code:
if(keyboard_check(vk_right)){
    //on se déplace ver la droite
}

Oui mais si on veux aller à gauche il faut tout réécrire mais avec des "-" au lieu des "+"?

Hé bien c'est une solution, mais pas la meilleure, car comme je vous l'ai déjà dit il faut être fainéant.

On va donc se débrouiller pour pouvoir exécuter ce code pour les deux direction horizontales.
Pour cela on aura besoin d'autres fonctions (hé oui encore une fois).
Ces fonctions sont :

- "abs(x)" Retourne la valeur absolue de x.
- "sign(x)" Retourne le signe de x (-1, 0 ou 1).

Mais cette fois ci je ne vais pas vous écrire le code, je vais vous laisser chercher un peut tout seul p
Je vais cependant vous faire un plant.

Citation :

- si on ne presse n'y la touche droite n'y la gauche on ne bouge pas.
- si on presse la touche droite et qu'il n'y a pas d'objet solide à droite de l'objet on ajoute la vitesse pixel par pixel.
- si on presse la touche gauche et qu'il n'y a pas d'objet solide à gauche de l'objet on va soustraire la vitesse pixel par pixel.

Et bien entendu en une seule boucle, je ne veux pas voir deux fois le même code avec juste les signes inversés Wink

A vos clavier!


Solution (a ne regarder que si vous avez essayé) :
Spoiler:

Normalement vous avez dût trouver si vous avez bien suivi jusqu'ici.
Vous savez maintenant vous déplacer horizontalement en GML !
Comme vous pouvez le voir il n'y a pas grand chose de bien compliquer.

Ce que je vous propose maintenant c'est de trouver par vous meme le code pour:
- vous déplacer verticalement (hyper simple).
- vous déplacer en diagonal (il vous faudras utiliser les fonctions lengthdir_x et lengthdir_y expliquées ici).
- appliquer une gravité.

J’espère avoir réussi à vous convaincre de passer au GMl Wink


Dernière édition par Caly le Jeu 27 Oct 2011 - 13:51, édité 4 fois
Revenir en haut Aller en bas
Caly
Utilisateur confirmé: Rang ****
Caly


Messages : 1285
Localisation : Haute Normandie
Projet Actuel : Capturer, apprivoiser et dresser des Pokémons sauvages pour faire des spectacles de rue et en faire mon métier.

tutoriel plateform - [Tutoriel] Les déplacements en GML et sans bogues. Empty
MessageSujet: Re: [Tutoriel] Les déplacements en GML et sans bogues.   tutoriel plateform - [Tutoriel] Les déplacements en GML et sans bogues. EmptyLun 24 Oct 2011 - 21:36

Première ébauche de ce tutoriel fini, je le compléterai/modifierai peut être par la suite.
Si vous avez des idées d'améliorations je suis preneur.

albinoblacksheep albinoblacksheep albinoblacksheep
Revenir en haut Aller en bas
marty
Utilisateur confirmé: Rang ***
marty


Messages : 697
Projet Actuel : laby-ereinte !

tutoriel plateform - [Tutoriel] Les déplacements en GML et sans bogues. Empty
MessageSujet: Re: [Tutoriel] Les déplacements en GML et sans bogues.   tutoriel plateform - [Tutoriel] Les déplacements en GML et sans bogues. EmptyLun 24 Oct 2011 - 21:53

merci pour tes explications!
doit on intégrer la largeur des sprites?
Spoiler:
Revenir en haut Aller en bas
Caly
Utilisateur confirmé: Rang ****
Caly


Messages : 1285
Localisation : Haute Normandie
Projet Actuel : Capturer, apprivoiser et dresser des Pokémons sauvages pour faire des spectacles de rue et en faire mon métier.

tutoriel plateform - [Tutoriel] Les déplacements en GML et sans bogues. Empty
MessageSujet: Re: [Tutoriel] Les déplacements en GML et sans bogues.   tutoriel plateform - [Tutoriel] Les déplacements en GML et sans bogues. EmptyLun 24 Oct 2011 - 22:03

Bonsoir Marty.

Pour ce qui touche les masques c'est GM qui gère tout.
On n'a pas besoin de ce soucier des sprites dans quasiment tout les cas.

Citation :
for (i=0;i<vitesse;i+=1)
if (place_free(x+i,y))
attention là "i" va augementer à chaque "tour" de boucle ce qui va faire:

if (place_free(x+0,...
if (place_free(x+1,...
if (place_free(x+2,...
etc..



Ce qu'on recherche c'est de faire "x+1" ou "x-1" dans tout les tours de la boucle.

Citation :
x=floor(x+vitesse)
Là tu rajoute ta vitesse à chaque "tour" de boucle.
Pour ton cas tu va rajouter 4 quatre fois ce qui fait 16 au bout de ta boucle Wink
Revenir en haut Aller en bas
Contenu sponsorisé





tutoriel plateform - [Tutoriel] Les déplacements en GML et sans bogues. Empty
MessageSujet: Re: [Tutoriel] Les déplacements en GML et sans bogues.   tutoriel plateform - [Tutoriel] Les déplacements en GML et sans bogues. Empty

Revenir en haut Aller en bas
 
[Tutoriel] Les déplacements en GML et sans bogues.
Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» [Tutoriel] Deplacements et animations A-RPG
» Réduction de poid super sans plomb sans mayonaise
» déplacements t-rpg
» deplacements
» Deplacements GML

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
Forum Le CBNA :: Développement :: Game Maker-
Sauter vers: