Comment réaliser un système simple de collision ?
Posté le 16/10/2018 11:24
Bonjour !
Je ne vais pas vous le cacher, depuis que mes études ont repris, il devient difficile pour moi d'entretenir une activité aussi soutenue que pendant ces dernières vacances. Bref, pour faire court, je souhaitais vous demander conseil sur la programmation en Basic casio. Comment faites-vous pour gérer un système de collision dans un jeu (Zelda-like, par exemple) ?
On part plutôt du principe que nous avons une carte divisée en cases dans lesquelles le joueur se déplace (une grille, en quelques sortes). Je le répète, je suis bien sur de la programmation en Basic. L'idée est de trouver un système assez simple et efficace, afin que je puisse continuer de produire des TDM sur ce sujet, puisque je pense que ça sera utile pour beaucoup de nos jeunes programmeurs.
J'aimerais juste connaître vos méthodes pour gérer les collisions dans un jeu (c'est-à-dire faire en sorte que le personnage ne puisse pas passer au travers des murs ou de certains objets), afin de voir ce qu'il est possible de faire !
Merci d'avance pour vos réponses !
Citer : Posté le 16/10/2018 11:52 | #
Je vois deux solutions assez évidente, la première qui passe par l'utilisation d'une matrice qui contient la map avec des blocs définies comme non franchissable, ou alors un peu comme sur la chip8, utiliser un pltest pour savoir si il y a collision (les case utilisable ne peuvent donc pas être autre chose que blanche..
Citer : Posté le 16/10/2018 12:54 | #
Je suis égalent intéressé pas ces méthodes !
Dans le cas d'une carte affichée par matrice comment s'y prendre ?
Citer : Posté le 16/10/2018 14:43 | #
Je suis égalent intéressé pas ces méthodes !
Dans le cas d'une carte affichée par matrice comment s'y prendre ?
Pour commencer, via la fonction Getkey tu enregistre la direction vers laquelle le joueur veut aller (Haut/Bas/Gauche/Droite). En fonction de cette direction et de la position actuelle du joueur dans la matrice (B, A) par exemple, tu obtiens les coordonnées d'une case de cette même matrice (B+1,A), (B-1,A), (B,A+1) ou (B,A-1). Ensuite il suffit de tester si cette case de matrice contient un valeur assimilable à un obstacle (Souvent, par convention, la valeur 0 signifie "pas d'obstacle" et tout le reste signifie "obstacle"). Si il y a un obstacle, il suffit d'empêcher le déplacement du joueur.
Il faut bien s'assurer que les indices utilisés pour vérifier la future case du joueur ne dépassent pas les dimensions de la matrice (D,C) par exemple. De simples conditionnelles suffisent à éviter ces cas. De toute façon dans 99% des jeux si le personnage se trouve déjà au bord de l'écran et qu'il veut en sortir, soit on empêche le mouvement, soit on l'affiche de l'autre côté (La fonction Mod ou Rmdr peuvent aider ).
Bien sûr ce même système permet de détecter le passage au travers de portes, de déclencher des actions en fonction d'objets, j'en passe et des meilleurs.
Concernant cette approche matricielle, mon conseil est de gérer la matrice de façon "naturelle", c'est à dire de choisir le même repère d'index entre l'affichage, les déplacements et la définition des matrices en Basic CASIO. Dit autrement : la position (0,0) du personnage devrait se trouver en haut à gauche de l'écran. Sauf erreur de ma part, mon dernier jeu (Ouf je suis vieux) Arkenstone utilise ce concept.
En ce qui concerne les alternatives raisonnables et déjà éprouvées, il y a l'utilisation des chaînes de caractères. Le principe est exactement le même sauf qu'au lieu d'avoir un tableau de valeurs, on utilise une suite de caractères. Le lien entre les deux est très vite fait car au lieu de chercher la case de coordonnées (A,B), on cherche le caractère d'indice C*B+A, où C est simplement le nombre de colonnes de notre map. Il faut voir la chaîne de caractères comme une matrice mise à plat, où chaque ligne succède à la ligne précédente pour ne garder qu'une seule dimension.
Chaque caractère de la chaîne symbolise un objet/obstacle, tout comme chaque valeur de case d'une matrice symbolise un objet/obstacle. La recherche des cases à droite ou à gauche de la position actuelle du personnage dans la map est immédiate (Ce sont les caractères respectivement avant et après la position actuelle : C*B+A-1 et C*B+A+1). La seule "difficulté" est de trouver les cases "au dessus" et "au dessous" de la position actuelle. Mais ceux qui ont déjà bien compris la formule qui permet de calculer la position actuelle auront vite compris : le "caractère au dessus" est celui d'indice C*(B-1)+A et celui "au dessous" a pour indice C*(B+1)+A.
Il va de soi que pour utiliser cette seconde méthode il faut savoir manipuler les chaînes de caractères et en particulier la fonction StrComp(. Si je ne me trompe pas Calcraft utilise magnifiquement cette méthode. L'avantage que j'y vois est qu'il est plus rapide d'afficher le contenu d'une Str que d'une Matrice. De plus, il me semble que cette seconde technique est moins gourmande en mémoire que les matrices (Bien que je n'aie pas d'élément pour le confirmer dans l'immédiat).
La Planète Casio est accueillante : n'hésite pas à t'inscrire pour laisser un message ou partager tes créations !
Citer : Posté le 16/10/2018 15:18 | #
De plus, il me semble que cette seconde technique est moins gourmande en mémoire que les matrices
Je confirme : une matrice pleine de 1 de 3*3 cases prend plus de place qu'une chaîne de caractères contenant 9 "1".
Citer : Posté le 16/10/2018 15:27 | #
Après bien sûr tout dépend de l'usage. La technique matricielle a tout de même un avantage lorsque l'on souhaite stocker davantage d'information qu'un simple numéro d'objet dans une case (En tirant profit de la partie décimale, de la partie complexe etc).
La Planète Casio est accueillante : n'hésite pas à t'inscrire pour laisser un message ou partager tes créations !
Citer : Posté le 16/10/2018 18:01 | #
la technique matricielle est exactement celle que j'utilise dans SnowCrash. Je vais jussqu'a user des positifs pour les dialogues et évents ( sauf le 1 qui est pour les collisions ) et les négatifs pour les changements de maps. Et je ne vois pas comment reproduire ces fonctions avec une seule pauvre Str...
Dijkstra - The Witcher
Citer : Posté le 16/10/2018 18:03 | #
Alors allons-y !
Qu'est-ce qui coince dans mon message plus haut sur la méthode des chaînes ?
La Planète Casio est accueillante : n'hésite pas à t'inscrire pour laisser un message ou partager tes créations !
Citer : Posté le 16/10/2018 19:39 | #
Bonjour,
J'ai pas lu les autres commentaires
(Par manque de temps),
Mais j'ai une technique toute simple,
Tu crées une matrice de {7 , 21}
Puis tu fais :
(Juste après les fonctions getkey et déplacement)
a=variable horizontal du point a déplacer
b=variable vertical du point a déplacer
a→c
b→d
'fonctions getkey et deplacements
If Mat a[b , a]=1
Then c→a : d→b
IfEnd
LpWhile 1
Et si tu utilises des fonctions graphiques, tu fais pareil mais au lieu de faire et utiliser une matrice, tu utilise un PxlTest.
J'ai appris cette technique grâce au merveilleuses vidéos de l'incroyable Totoyo.
Au revoir et à bientôt,
Cordialement,
Manolo.
Citer : Posté le 16/10/2018 20:49 | #
@NeOtux: j'aurais pas dit mieux comme explication
-Planétarium 2
Citer : Posté le 16/10/2018 21:25 | #
la technique matricielle est exactement celle que j'utilise dans SnowCrash. Je vais jussqu'a user des positifs pour les dialogues et évents ( sauf le 1 qui est pour les collisions ) et les négatifs pour les changements de maps. Et je ne vois pas comment reproduire ces fonctions avec une seule pauvre Str...
Eh bien, c'est bien des Str que j'utilise dans mon propre jeu : Aventura. C'est aussi beaucoup moins gourmand en place que des matrices. Par ailleurs, merci Ne0tux pour ton explication détaillée !
Dans le cas des matrices, vous stockez les map comment ? Est-ce que vous hardcodez les matrices ou vous faites autrement ?
Citer : Posté le 16/10/2018 21:27 | #
Tu mets un morceau de programme qui hardcode la matrice sous la forme [[...]]→Mat A, ou bien tu vends la matrice avec.
Le premier est meilleur car plus compact (tu as deux copies une fois la matrice chargée mais tant que t'en charges pas 20 à la fois, ça reste largement rentable).
Citer : Posté le 11/12/2018 20:07 | #
Du coup quelle solution est la plus rapide a l’exécution entre l'utilisation de la matrice et celle d'une str ?
Citer : Posté le 11/12/2018 20:15 | #
C'est la matrice. La lecture et l'ecriture sont directes
Citer : Posté le 11/12/2018 20:32 | #
@Ninestars merci beaucoup.