Bonjour, Bonsoir… Peu importe l’heure à laquelle vous lisez
ce tutoriel, il sera toujours très utile.
(Prétentieux ? Oui mais justifié…)
Tout d’abord ça parle de quoi ? Et bien d’une manière simple, rapide, propre et de qualité permettant de réaliser des collisions fines, précises sur des formes compliquées, incurvées, courbes etc.
Ce n’est cependant pas un système de collision que nous allons créer, mais utiliser celui préconçu de GameMaker et l’adapter pour le mapping.
Oui car souvent, ce qui pêche dans les jeux réalisés avec GameMaker, sont les map trop carrés et dont les collisions sont trop abruptes et irrégulières, c'est-à-dire qu’on ne fait pas dans l’arrondi, pixel oblige. Toutefois, l’autre soir je programmai un de mes jeux, et en réalisant une map d’essai, je me suis dit : « Mince, jamais j’ai mappé aussi mochement, ça va pas comme ça, faut que je trouve une solution ». Car en fait j’avais dessiné un beau background avec des parois censées être solides etc.
Et je désirai que mes parois courbes soit respectées et ne pas mettre des cubes ou des barres avec des angles trop différents par dessus, cela aurait été d’une qualité de jeu déplorable, l’idée de mettre mon background en sprite ne m’a même pas effleuré l’esprit, ce serait primordialement trop gourmand en mémoire, et puis le background n’était pas prévu pour être transparent.
Alors s’est fait un déclic, pourquoi ne pas utiliser un path ? Mais oui ! C’était tout bête, tout au plus quelques lignes de codes et c’était bon. Le principe est tout bête et je suis certain qu’il est présent dans votre esprit depuis que j’ai dit le mot : « path », mais bon pour ceux qui sont long à la détente, voici mes explications :
Tout d’abord on crée un nouveau path, on fait afficher la room en arrière plan (petite icône en forme de fenêtre en haut à droite) ensuite on dessine le contour de nos parois à l’aide des vecteur, cela peut être fait avec un seul path si on a des parois qui se rejoigne, sinon avec plusieurs différents pour chaque parois. Ensuite on crée un petit sprite de 16*4 non transparent, suivi de deux objets, le premier auquel on assignera ce sprite et dont on mettra la variable image_angle égale à la direction dans un événement step.
Le second objet quant à lui sera constitué d’un simple script dans l’événement create qui créera un nombre suffisant d’objets du type du premier objet pour couvrir toute la longueur du path (une simple boucle repeat ou for), ajoutées à cela quelques lignes définissants le path, et la position sur celui-ci assigné à chaque objet.
Après la théorie, la
pratique !
|
Légende: |

Bien passons à la pratique, car la théorie c’est bien, mais ça n’influe pas sur grand-chose…
Mettons que dans un accès de folie, nous décidions de créer un « hit the ball » avec des maps complexes ! (Je sais faut être idiot…) Et que nous désirons que les collisions avec les parois de la map soient parfaites, pour donner une impression de réalisme profonde au joueur. C’est bon j’arrête de tourner autour du pot. Vous pouvez admirez cette map ci-dessus.

Nous allons la charger dans notre gm6 en tant que Background, l’afficher dans le room editor, et décocher par la même occasion : Tile Hor et Tile Ver.
Puis nous créerons un path (path_collide_1), qui servira pour le grand contour, nous cliquerons sur l’icône : room pour la faire afficher et nous suivrons les contours petit à petit en mettant la grille sur 1*1, de la même manière que vous le feriez dans un programme de dessin avec l’outil de sélection lasso ou polygone. Nous décocherons pour le moment : Closed ainsi que nous sélectionnerons straight lines. (A gauche). Une fois fini tout proche du point de départ vous cocherez à nouveau : closed puis sauvegarderez les propriétés de ce path.
Maintenant nous devons créer un second path (path_collide_2), pour la petite île, de la même manière que pour le premier.
Une fois ceci fait, nous allons programmer nos parois. Bien créons l’objet qui créera les parois nous le nommerons : Ynit_coll.
Dans l’événement de création nous y placerons donc le code suivant :
/*
Grand Contour */
pos_n =
0;/*Variable
de
position des objets nécessaires à la collision.*/
indice_collide =
6;/*Indice
de
longueur des objets nécessaires à la collision.*/
path = path_collide_1;
repeat(path_get_length(path)/indice_collide)/*Création
de ces objets puis
configuration de leur position.*/
{
with(instance_create(x,y,obj_coll_inst))
{
path_start(other.path,0.001,2,true);
pos_n = other.pos_n;
other.pos_n
+= other.indice_collide;
path_position =
((other.indice_collide+pos_n)/path_get_length(other.path));
}
}
/*
Petite île */
pos_n =
0;/*Variable
de
position des objets nécessaires à la collision.*/
indice_collide =
6;/*Indice
de
longueur des objets nécessaires à la collision.*/
path = path_collide_2;
repeat(path_get_length(path)/indice_collide)/*Création
de ces objets puis
configuration de leur position.*/
{
with(instance_create(x,y,obj_coll_inst))
{
image_xscale =
0.5;
path_start(other.path,0.001,2,true);
pos_n = other.pos_n;
other.pos_n
+= other.indice_collide;
path_position =
((other.indice_collide+pos_n)/path_get_length(other.path));
}
}
! Pensez aussi à créer l’objet : obj_coll_inst, le mettre invisible et surtout à placer dans step : image_angle = direction;
| §Vous
en êtes
là, Step Final: Récapitulatif: - Vous avez ajouté en tant que Background la map - Vous avez créé les paths: path_collide_1 et path_collide_2 - Vous avez créé et programmé les objets: Ynit_coll & obj_coll_inst - Vous avez testé le tout. :p |
Bien voilà qui est fait, les objets envers lesquels vous
devez déclarer les collisions sont les obj_coll_inst.
Vous remarquerez que dans certains cas il risque d’y avoir un problème
de
collision à cause de la paroi fine créée (dans le cas de projectiles
très
rapide), qu’à cela ne tienne, il est une solution simple, vous pouvez
grâce
à : path_scale changer
la taille du path
et ainsi en mettre plusieurs les uns derrière les autres pour assurer
la
détection de la collision, vous pouvez également pour améliorer la
qualité cocher Smooth Curve, c'est à voir selon la map.
D’ailleurs c’est un point sur lequel Mark Overmars devrait se pencher, il devrait créer un meilleur système de collision, je me rappelle que sous Div Game Studio c’était bien plus performant, mais bon tout ceci date d’un autre âge.
Il y a plein de moyen de « bricoler » ce système, à l’aide de image_(x/y)scale et autre fonctions, cependant méfiez vous de ne pas faire de trop courts objets car plus ils seront courts plus il y en aura, et donc à terme cela risque de lagger, si j’ai un conseil c’est d’utiliser de long (16 px) sprites pour les courbes amples, larges, et de petits pour les petits détails et contours, je vous fait confiance pour trouver divers moyens par vous-même.
Aller, j’arrêtte de
vous ennuyez,
vous pouvez partir, ah, je vous laisse
programmer le
reste de ce fameux « hit the ball »…
Fichier
Source du Tutoriel: Cliquez ici