|
|||||||||||||||||||||||||||||||||||||||||||
|
Introduction J'ai commencé à parler des coordonnées cartésiennes dans un précédent article, et j'ai pensé qu'il valait mieux clarifier pour les non-mathématiciens ce que c'est, puis ajouter le concept de coordonnées polaires, que j'ai commencé à utiliser sporadiquement à partir de mon jeu Morpheus, c'est-à-dire en 1987. J'avais joué à Gyruss dans les salles d'arcade, puis sur C64. Lors de mon voyage à Chicago en 1986 pour lancer Uridium sur les machines 16 bits, j'ai rencontré le programmeur qui a écrit la version C64. Je me suis intéressé aux motifs circulaires produits par Gyruss. C'était un voyage vraiment précipité car je devais obtenir un passeport et un visa américain en une semaine environ. Cela a nécessité des voyages pour trouver le bureau des passeports de Peterborough et l'ambassade des États-Unis à Londres (sans GPS !). Un autre article entier pourrait probablement être consacrée à Chicago. Coordonnées cartésiennes Nous utilisons les coordonnées cartésiennes sur les cartes et les écrans, entre autres choses. Dans un système à deux dimensions, nous utilisons deux coordonnées, ce qui n'est pas une petite coïncidence. Par convention, nous utilisons X pour l'horizontale et Y pour la verticale. En ce qui concerne la mémoire du Commodore 64, qui est utilisée pour afficher l'écran en caractères de 8x8 pixels, le caractère en haut à gauche est le premier octet, le suivant est à sa droite, pour 40 caractères. Après 40 octets, nous arrivons au deuxième caractère en bas, sur le bord gauche, suivi de 39 autres octets en travers. Coordonnées du monde et d'écran Pour un jeu en défilement 2D sur C64, nous aurions toute la carte disposée en caractères dans un gros tampon mémoire. Ce tampon mémoire ne serait pas dans la mémoire vidéo de 16 ko. La carte pourrait représenter une zone de six écrans de large et quatre écrans de profondeur, comme l'exemple de mon jeu Gribbly. Cela représente un tampon de 256 caractères de large sur 80 de profondeur, soit environ 20 ko des 64 ko de mémoire disponibles. C'est une estimation, je n'ai pas mes listes sous la main. Nous devons savoir où se trouvent tous les objets du jeu sur la carte, nous avons donc besoin de coordonnées cartésiennes du monde qui nous permettent d'indexer la carte. Vous devrez peut-être faire cela pour la détection de collision en arrière-plan et pour empêcher les objets de quitter les bords de la carte. Il est logique que les coordonnées du monde et celles de l'écran soient du même signe afin de pouvoir passer rapidement de l'une à l'autre. La position du joueur dans le monde détermine la position de défilement de l'écran, qui détermine à son tour la position relative de tout ce qui se trouve à l'écran, par une simple soustraction de sa position dans le monde de la position de défilement. Il y a donc un ordre hiérarchique strict. Commencez toujours par le joueur, déterminez la position de la "caméra", c'est-à-dire la position de défilement de l'écran, puis déterminez le reste des objets. Toujours pour Gribbly, une fois que vous avez déterminé la position relative de l'écran, vous pouvez décider si un autre objet est à l'écran ou non. S'il est hors écran, il n'a pas besoin d'un sprite. J'utilisais seize objets maximum, mais je partageais cinq sprites pour les afficher tous, donc ils devaient se partager. Une fois qu'un objet était à l'écran, il gardait un sprite jusqu'à ce qu'il quitte la zone de l'écran ou soit éjecté. Cela a conduit à des décisions brutales sur ce qui arrive à un sixième objet essayant d'entrer dans la zone de l'écran. Manettes et écrans Les manettes non proportionnelles utilisent quatre commutateurs pour détecter le mouvement cartésien X et Y, ou l'absence de mouvement, dans quatre directions, ce qui donne neuf combinaisons valides, y compris centrées. Certains modes de contrôle bruts appliquent simplement des vitesses au joueur en fonction de l'entrée de la manette. J'ai toujours préféré appliquer les accélérations aux vitesses avant d'appliquer les vitesses à la position, de sorte que la vitesse soit appliquée progressivement. Vous pouvez également appliquer un taux de freinage différent si la direction d'entrée est opposée à la direction du mouvement actuel. Bien qu'il y ait eu des modes de contrôle polaires, tels que dans Lunar-Lander ou Asteroids, ceux-ci contrôlent la rotation et la vitesse par bouton, il est rare que nous ayons vu un contrôleur proportionnel circulaire au début. Potentiellement, nous les voyons sur certains contrôleurs de jeu modernes, bien qu'ils puissent toujours être carrés, il faut donc modifier les valeurs reçues par le logiciel pour rendre le contrôle circulaire. Vitesse polaire Pour accéder aux vitesses polaires, vous devez commencer à manipuler des vecteurs et calculer des sinus et des cosinus. Ce que nous voulons, c'est représenter la même vitesse globale à des angles arbitraires, pas seulement vers le haut, vers le bas, vers la gauche et vers la droite. Cela implique de calculer les composantes cartésiennes X et Y, avec une précision inférieure au pixel, d'angles et de vitesses arbitraires. Le C64 n'a pas de gestion de virgule flottante, et pas même d'instruction de multiplication. Heureusement, je ne pensais pas vraiment aux mathématiques, je pensais juste que je voulais obtenir de jolis effets. Il faut penser en hexadécimal pour savoir comment faire les choses. La clé est toujours la puissance de deux. J'avais besoin de sinus et de cosinus, et d'un moyen de les multiplier par des vitesses pour obtenir des distances en pixels. Vous devez également être capable de convertir du cartésien au polaire afin de déterminer dans quelle direction se trouve un objet arbitraire et à quelle distance. Nous avons réussi à trouver une routine d'approximation beaucoup plus rapide que de faire le gros calcul. De plus, l'addition de vecteurs polaires est plus facile à réaliser en convertissant au cartésien, en ajoutant, puis en reconvertissant au polaire. La gravité doit parfois être appliquée à des objets qui se déplacent de manière polaire. Vous pouvez choisir de passer du polaire au cartésien une fois que vous avez commencé. Il est rare que vous souhaitiez continuer avec un mouvement polaire dans un environnement avec gravité. C'est une différence majeure entre un jeu vu de haut et un jeu e, latéral. Il est plus utile de connaître la direction polaire d'une cible que la distance, bien que les robots dans Paradroid 90 ne puissent "voir" qu'une certaine distance. Si vos calculs polaires sont précis plutôt que rapides, vous pouvez les utiliser pour la détection de collision. Notre algorithme 16 bits était précis à environ 10 %, ce qui est suffisant pour la visibilité, mais nous ne l'avons pas utilisé pour les collisions. L'algorithme a été publié, nous ne l'avons pas inventé, mais il était basé sur une estimation et une boucle d'environ trois fois pour améliorer l'estimation, ce qui impliquait un calcul de racine carrée, donc nous ne voulions pas faire cela trop souvent. De nos jours, vous pouvez obtenir des réponses rapides et précises en virgule flottante. Parfois, vous ne vous déplacez pas dans la même direction que celle à laquelle vous faites face. Imaginez une voiture de drift roulant sur une piste, vous voudrez donc peut-être stocker la direction d'orientation d'un objet séparément du mouvement. Les deux voudront s'aligner au fil du temps, mais certaines actions peuvent les faire différer. Morpheus Je jouais à un jeu de tir en vue de dessus avec défilement vers le haut sur mon Amiga et quelque chose a attiré mon attention. Dans le grand schéma des choses, ce n'était pas particulièrement important, mais cela m'irritait. Une tourelle au sol tirait huit balles à la fois, espacées de 45 degrés, donc en haut, à droite, en bas et à gauche et les quatre diagonales. Dans le monde réel, les balles diagonales sortiraient à la même vitesse que les autres, formant un octogone, mais celles-ci sortiraient en forme carrée. Maintenant, je peux voir que l'initialisation serait légèrement plus rapide lors du réglage des vitesses des huit balles. Vous utilisez simplement zéro et une valeur pour les différentes vitesses X et Y, négatives ou positives. Si vous aviez simplement une vitesse X et Y plus faible pour les balles diagonales, que vous pouvez calculer à l'avance, vous pouvez obtenir un meilleur modèle et égaliser les vitesses globales des balles diagonales. J'ai alors pensé que j'aimerais faire de jolis motifs avec des pixels tirant depuis le milieu de l'écran. Tout cela a fini par devenir l'écran titre de mon jeu Morpheus, ainsi que les étoiles d'arrière-plan du jeu, et fait également partie du mode de contrôle. J'ai décidé que j'avais besoin de valeurs de sinus et de cosinus pour représenter un certain nombre d'angles. On vous a peut-être dit à l'école qu'il y a 360 degrés dans un cercle. Je suis ici pour vous dire qu'ils se sont trompés, il y en a 256. Au moins, il y en a dans le monde informatique, la matrice, si vous voulez. Rechercher des valeurs dans une table de 256 octets est une tâche facile pour le processeur, et je crois que j'ai répété 64 valeurs depuis le début pour pouvoir ajouter un quart de cercle aux valeurs de sinus pour obtenir les cosinus correspondants. Je me suis assis là avec ma calculatrice hexadécimale et j'ai calculé les valeurs hexadécimales pour les 256 sinus de direction en utilisant SOH-CAH-TOA qu'on nous avait donné à l'école : sinus égal opposé sur hypoténuse, cosinus=adjacent sur hypoténuse et tangente=opposé sur adjacent. Nous savons que l'hypoténuse est un balayage constant d'une aiguille autour du cadran d'une montre. En raison du faible niveau de précision, certaines valeurs de 8 bits sont sorties identiques, mais lorsque le sinus de deux angles voisins est sorti identique, le cosinus est différent, et vice versa, donc il n'y a pas de duplication. J'ai ensuite dû choisir une échelle pour la vitesse. C'est en grande partie arbitraire, mais en fonction de notre méthode de calcul, nous devons travailler dans les unités qui facilitent les calculs du processeur. Encore une fois, nous voulons travailler sur quelques emplacements binaires de sous-pixels pour obtenir une certaine précision. Rien ne va bouger de plus de huit pixels par image, en gardant à l'esprit que nous déplaçons tout à la vitesse magique de 50 images par seconde. Tout ce qui se passe à cette vitesse traversera l'écran en moins d'une seconde. Je me souviens que pour le système polaire Amiga, j'avais envisagé d'augmenter le nombre d'angles possibles à 1024, un autre nombre finement arrondi. L'idée de calculer autant de valeurs et de les saisir dans l'assembleur m'a rebuté, nous sommes restés avec 256, que j'ai quand même recalculé avec une plus grande précision. La distance polaire d'un pixel était de 0,400, et les valeurs de la table des sinus étaient cette fois des nombres signés de 14 bits. Lorsque la vitesse polaire a été multipliée par la valeur sinusoïdale appropriée, nous avons obtenu une réponse de 32 bits avec le nombre de pixels dans l'octet supérieur et les pixels partiels dans le reste. Nous aurions alors décalé arithmétiquement le nombre de 8 bits vers la droite pour nous donner 16 bits de pixels et 16 bits de sous-pixels. Les coordonnées du monde et relatives seraient à cette échelle, ce qui donnerait dix écrans de large en utilisant les nombres positifs. Je me souviens également d'avoir saisi l'ensemble original de 256 valeurs 8 bits pour la table sinusoïdale et de les avoir toutes testées. Il y avait quelques fautes de frappe qui se sont révélées lorsque j'ai monté un banc d'essai pour déclencher un groupe de pixels à des angles légèrement différents en même temps. Je pense que mon collègue chez Graftgold, Steve Turner, a trouvé toutes ces absurdités polaires plutôt déroutantes au début. Bien sûr, je pouvais obtenir de jolis effets d'explosion, mais à quoi bon ? Nous ne savions pas que bientôt, nous ferions du MotoX sur la PlayStation et que nous aurions besoin de connaissances polaires. Intensity Le joueur et les vaisseaux drones dans ce jeu utilisent le mouvement polaire. L'entrée cartésienne de la manette est convertie en une direction polaire souhaitée et le vaisseau du joueur pivote dans cette direction en une courbe douce. J'essayais juste quelque chose de différent. Le drone suit également un chemin polaire, ce qui peut être vu si vous lui donnez une nouvelle destination pendant qu'il est en vol. Les ennemis utilisent tous le mouvement polaire pour suivre l'équipage, bien que les ennemis "pétillants" en fin de niveau prennent un chemin en zigzag vers le vaisseau du joueur. Ils ont toujours besoin de connaître la direction polaire car ils modifient cette direction cible pour leur vol. Paradroid 90 Les robots de ce jeu utilisent le mouvement polaire et tirent. Les têtes de certains robots pivotent également et la ligne de visée est utilisée par la plupart des robots. Vous pouvez donc vous faufiler derrière beaucoup d'entre eux. Comme beaucoup d'entre eux ont également l'ouïe, si vous tirez, ils se tourneront vers vous et riposteront, bien sûr. Les routines polaires sont utilisées partout pour permettre aux robots de tirer sous n'importe quel angle pour toucher le joueur. Ils ratent rarement. Fire And Ice Le mouvement polaire est utilisé pour les différentes armes de glace, mais la gravité cartésienne est également appliquée. Vous pouvez voir les multiples balles de glace tirer dans un jet net mais être déformées par la gravité. Il y avait beaucoup de physique simulée dans celui-ci car j'ai encodé les caractères au sol avec des pentes et j'ai permis à la glace de rouler sur les pentes. Le plus délicat était d'arrêter la glace lorsqu'elle roulait lentement dans une vallée, car les petites accélérations dues aux deux pièces adjacentes de pente opposée maintenaient la glace en oscillation. Les chiots appliquent également un peu de physique pour pouvoir sauter vers une autre plate-forme. C'est la même équation physique que celle utilisée par les Gribblets, qui font également une apparition ici. Si vous connaissez votre accélération de gravité et que vous savez que vous voulez sauter à une autre hauteur en seize mouvements, vous pouvez alors déterminer la vitesse initiale dont vous avez besoin. J'ai calculé cela à chaque fois au moment de l'exécution, mais en fait, dans Gribbly, il y a un nombre assez limité de possibilités, j'aurais donc été plus intelligent de stocker le nombre limité de réponses dans une table de consultation. Je pense toujours que cela semble vraiment intelligent lorsque les Gribblets ou les chiots sautent vers le haut ou vers le bas. Uridium 2 Les missiles à tête chercheuse utilisent tous un algorithme de tête chercheuse polaire, les Uridimines non. J'avais vu les missiles à tête chercheuse du jeu d'arcade SlapFight et je pensais qu'ils éliminaient beaucoup de tracas du jeu, mais j'ai ensuite noté leur clin d'oeil effronté au sort de la tête chercheuse polaire. Comme ils ne peuvent tourner qu'à une certaine vitesse, s'ils effleurent une cible, ils doivent refaire le tour et peuvent facilement rater à nouveau. Ils semblent laisser les missiles à tête chercheuse sortir directement avant de poursuivre la cible. Ils incluent peut-être une distance minimale par rapport à la cible avant de passer en mode "poursuite". Ma solution était légèrement différente : au départ, les missiles à tête chercheuse sortent du Manta vers l'avant, puis sélectionnent une cible. S'il n'y en a pas, ils avancent jusqu'à ce qu'il y ait une cible, ou ils quittent l'écran, ce qui n'arrive généralement pas car il y a presque toujours beaucoup de cibles. Si le missile à tête chercheuse parvient à faire un tour complet sur 360 degrés, il sait qu'il doit faire le tour de la cible, il se met donc en vol rectiligne forcé pendant quelques cycles, puis recommence à se diriger vers la cible. Vous ne verrez peut-être cela se produire qu'une fois par partie, cela se produit très vite et vous êtes probablement trop occupé pour le remarquer, mais vous remarquerez qu'un missile à tête chercheuse tourne en rond sans toucher la cible. Une fois, j'ai été interrompu au travail par un courrier électronique d'un gars... qui me demandait comment fonctionnait l'algorithme d'Uridimine. Ce courrier électronique m'est parvenu via le directeur général et les RH, ce qui est devenu plutôt embarrassant. S'il vous plaît, ne faites pas ça aux gens. Juste pour mémoire : les Uridimines accélèrent simplement de, disons, un pixel par cycle dans la direction X vers le joueur, et font de même dans la direction Y. Les vitesses X et Y sont alors plafonnées à, disons, cinq pixels par cycle. Ce n'est vraiment pas beau, et plutôt embarrassant, cela signifie qu'elles se déplacent plus vite en diagonale qu'horizontalement ou verticalement, où elles oscillent. Heureusement, vous n'avez rien avec quoi les comparer, car les Uridimines poursuivent toutes le joueur dès le départ ! La vitesse maximale doit être inférieure à la vitesse maximale du Manta, car elles sont destinées à inciter le joueur à se précipiter à grande vitesse, ou à faire une boucle en hauteur pour éviter une collision. J'aurais aimé faire un vaisseau ennemi qui en libère toute une bande. Peut-être la prochaine fois... Je ne vois pas pourquoi elles ne devraient pas aller haut et pouvoir éliminer le Manta en boucle non plus. Coordonnées cartésiennes 3D Tous les jeux 3D qui permettent le vol utiliseront une sorte de système polaire 3D, ainsi que leur système de coordonnées cartésiennes 3D. En plus d'une coordonnée X et Y, nous ajoutons un Z. Traditionnellement, X et Y parcourent généralement la surface du sol, et Z est la hauteur. Il y a deux façons différentes de faire ça, vous ne le saviez pas ? On les appelle les systèmes gauchers et droitiers. Si vous continuez à faire aller X de gauche à droite et aller Z vers le haut, dans un système gaucher, Y vient vers vous, dans un système droitier, il s'en va. DirectX utilise un monde gaucher. Ça me va bien ; il est temps que nous, les gauchers, ayons notre mot à dire. Ensuite, il y a la disposition des pixels de l'écran. Traditionnellement, nous nous débrouillions avec X allant de gauche à droite et Y allant de haut en bas. Vous pouvez utiliser les coordonnées X et Y pour calculer simplement et rapidement (merci pour le slogan, Rich) l'adresse et la position des pixels pour le traçage. Tout cela change sur PC, mais c'est une autre histoire, pour un autre article. Peut-être aussi l'histoire de la façon dont nous pouvons simplement construire une échelle vers la Lune (à partir d'allumettes). Facile à demander... Mon problème avec la 3D, c'est que tout doit être fait correctement. Uridium a triché en ce sens que les balles du Manta pouvaient atteindre des hauteurs importantes pour toucher les vaisseaux ennemis qui survolaient le joueur, et pouvaient atteindre des cibles au sol en bas. Vu d'en haut, on ne peut pas dire que c'est ambigu. Peut-être que le Manta tire deux balles, une haute et une basse, avec Bluetooth, de sorte que si l'une explose, l'autre aussi ? Hé, si un photon peut passer à travers deux fentes, alors tout est possible ! Si nous obtenons un jour un Uridium 3D, il faudra des armes supplémentaires sur le Manta, et le mode de contrôle sera plus extra-dimensionnel. Heureusement qu'il y a plus de commandes sur une manette de jeu de nos jours.
|