Tragicomedy in NaN Acts: comment nous avons créé un jeu sur JS et l'avons sorti sur Steam

"Eka est invisible", dites-vous, "il n'y a pas votre jeu dans le top 100, donc ce n'est pas sûr." C'est la même chose. Mais au cours de l'année de développement de Protolife, nous avons acquis une expérience que nous pouvons partager avec de futurs igrodelov potentiels. Les vétérans de l'industrie, je le crains, ne trouveront rien d'intéressant pour eux. Mais peut-être au moins amusez-vous du cœur.


Quel genre de jeu est-ce? Et qui sommes nous


Nous sommes une équipe de trois personnes ( GRaAL , A333 , icxon ), par la volonté du destin appelée Volcanic Giraffe sans aucune intention. Nous avons travaillé ensemble pendant longtemps, nous avons tous les trois participé au Ludum Dare (compétition d'écriture de jeux de week-end), et avons décidé une fois de sortir un de nos métiers appelé Protolife.

En bref: il s'agit d'une tour de défense inhabituelle, où vous devez exécuter un curseur de héros et construire une défense de blocs contre la biomasse rouge en constante augmentation.

D'après les commentaires sur le projet d'article:
icxon : vous devez d'abord écrire un peu sur le gameplay. Et puis quelques captures d'écran sur lesquelles le raifort comprend ce qui se passe

Si vous peignez plus en détail, alors qu'est-ce qui est dans le jeu:

  1. Il y a un ensemble de niveaux, à chaque niveau il y a notre base et notre avatar - un robot-constructeur.
  2. Une partie du niveau est remplie de biomasse rouge qui crache des tonnes de foules.
  3. Les foules, bien sûr, courent vers la base et essaient de l'écraser. Et nous construisons une défense contre les tours et nous ne la laissons pas faire.

"Mais qu'est-ce qui est si inhabituel?" - demandez-vous. Et les principales différences avec la plupart des tours de défense sont les suivantes:

  1. Nous contrôlons le robot de construction directement à partir des clés, c'est-à-dire vous devez vous précipiter manuellement sur le niveau et avoir le temps de tout construire / réparer.
  2. Tout ce que le robot peut faire est de construire et de démonter les blocs bleus. Un tel bloc ne fait rien d'utile, mais plusieurs blocs disposés selon un certain modèle se transforment en une structure utile. Exemples de modèles:


  • Modèle 1: un simple pistolet
  • Motif 2: mur
  • Modèle 3: pistolet AA. ici, vous devez également utiliser des cristaux jaunes, qui sont déjà plus difficiles à extraire
  • Modèle 4: mitrailleuse

Et donc le jeu continue: nous courons, construisons, obtenons une réponse, le réparons rapidement. Une visualisation directe du processus de développement du jeu est obtenue.

Mais un tel jeu n'a pas fonctionné tout de suite. En avril 2017, à Ludum Dare 38, cela ressemblait à ceci:

Si vous ne faites pas attention à la différence d'horaire, il semble que peu de choses aient changé. Déjà sur la version LD, il y avait un constructeur de curseurs, la construction de tours à partir de blocs et la confrontation avec la biomasse rouge. Nous l'avons laissé parce qu'il a fonctionné et que les gens l'ont aimé.

Mais en fait, beaucoup de choses ont changé sous le capot en plus de la concentration de graphonium par pixel carré. Sur le chemin d'un an, nous avons dû prendre diverses décisions - gameplay, technique, organisationnel et même marketing. Certains ont réussi, d'autres non.

Je voudrais parler de ces décisions.

Je ferai une réservation tout de suite - il y aura probablement plusieurs articles, car Si vous commencez à creuser, beaucoup de matériel sort. À la fin de cet article, vous trouverez un court sondage - quels sujets vous intéresseraient le plus. Eh bien, des liens vers le jeu lui-même aussi.

Une histoire ennuyeuse de création.


Je ne pense pas que quiconque s'intéresse vraiment à la façon dont le jeu a été pensé, je vais donc le retirer sous le spoiler.

D'une manière ou d'une autre, Conway, Matheson et Petri sont entrés dans le bar ...
Et le barman dit: undefined n'est pas une fonction.

À la veille de la LD38, cela s'est avéré terrible: notre collègue et le seul artiste A333 survolera tous les LD au-dessus de l'Atlantique et ne pourra pas nous aider. Par conséquent, il était nécessaire de rendre le jeu aussi peu exigeant que prévu avec les forces restantes.

Le thème était d'ailleurs "Petit monde". Et puis, pendant le brainstorming, tout s'est passé comme ceci:
  • Il n'y a pas d'artiste - les graphismes sont simples, primitifs
  • Petit monde - petite taille, ou peut-être quelque chose de microscopique, comme toutes sortes de germes
  • Les microbes sont un type de micro-vie.
  • Et la vie est un tel automate cellulaire. Eh bien, les cellules dans tous les sens. Laissez le joueur se battre avec une machine cellulaire contre une autre machine cellulaire.
  • Poked Conway Life - pas bon. Un joueur qui ne connaît pas les règles de la machine est susceptible de construire quelque chose qui sera lui-même détruit. C'est très difficile à contrôler. Que seul l'adversaire suive les règles de la vie et nous bâtirons des structures ordonnées.
  • ... mais l'ennemi s'autodétruit de temps en temps. D'accord, ajustons les règles pour lui. Laissez-le grandir, mais nous devons le détruire.
  • Donc, nous avons déjà: les globules rouges de l'ennemi, qui ne font que croître, et nos bleus, que nous nous construisons selon les schémas donnés. Nous construirons des tours et des murs, c'est-à-dire Il s'avère qu'un tel tower defense. Pour changer, il n'y a toujours pas assez d'ennemis en mouvement (mobs).
  • La veille, j'ai relu «Je suis une légende» de Matheson. Ainsi, le personnage principal la nuit empêche le siège des vampires et pendant la journée, lorsque les vampires sont inactifs, rétablit la défense et élargit également la sphère d'influence. Cela ressemblait à un bon élément de gameplay, donc les phases du jour et de la nuit sont apparues dans le jeu. La nuit, des cellules ennemies partageaient et marquaient des maisons, des foules rampantes, pendant la journée - tout était calme, vous pouviez contre-attaquer.
  • Appelez nos pixels colorés «micro-organismes» et enfoncez-les dans une arène ronde - une boîte de Pétri.
  • Nous prenons notre moteur Phaser.js préféré ...
  • ... et 31ème place dans notre poche

Voici une histoire, pas très intéressante, comme je l'avais prévenu.

"Mais Alexei, qu'est-ce que tu as écrit alors?" Question raisonnable. Le fait est que presque le premier commentaire sur le jeu ressemblait à "lol, vous avez tous arraché Creeper World". Après avoir lu le jeu bien plus tard, LD lui-même, je comprends pourquoi les gens pensent ainsi. Mais encore un peu triste.

Si tout d'un coup vous vous sentez insulté d'avoir passé du temps sur cette lancinante, alors comme consolation, écrivez-moi le code PM «choses ennuyeuses» dans PM, et je vous enverrai l'une des 10 clés si elles ne sont pas terminées à ce moment-là. Malheureusement, les clés sont également terminées.

Choisir un jeu pour une implémentation complète


Comme cela arrive souvent, une fois que nous pensions tous à trois - mais est-il temps d'essayer de créer un jeu à part entière. Souvent, à ce stade, une sorte de concept est pris de la tête, un «jeu de rêve», et le travail se fait avec. Et puis quelle chance de deviner avec les souhaits du public.

Notre tâche a été un peu simplifiée grâce à la présence d'un petit «portfolio» sur Ludum Dare. Nous avons vu comment les gens réagissent aux différents jeux et nous avons pu comparer. Protolife a eu la plus grande réponse, elle a été saluée pour son originalité et son gameplay intéressant - ceci est à un niveau zéro de graphisme et seulement 4 niveaux!

De plus, itch.io nous a aidés à prendre la décision, sur laquelle nous avons publié nos créations. En fait, il y a des gens qui vont sur itch.io pour jouer à des jeux Web. Certains d'entre eux adorent le genre tower defense, et 5 à 10 personnes sont entrées (et entrent toujours!) Pour jouer ce vieil Protolife tous les jours .
Statistiques des appels avant la sortie du jeu sur Steam

On peut dire que c'était notre première recherche marketing. Nous avons pensé et décidé qu'une «défense de tour non standard» pourrait bien tirer. Il n'y a pas tellement de défenses de la Tour, beaucoup d'entre elles sont similaires à deux gouttes d'eau, et nous pouvons tout à fait nous démarquer.

Pour l'avenir, je peux dire que la tactique a porté ses fruits.

Astuce n ° 1 non sollicitée: mieux vaut ne pas agir aveuglément. Le «jeu de rêve» idéal dans votre tête peut ne pas être nécessaire pour personne. Si vous ne participez pas à toutes sortes de jams, il est toujours logique de dessiner un prototype de gameplay (!) Et de le tester sur vous-même, vos amis et connaissances.

Contre-Conseil: Si vous n'avez pas peur qu'une demi-personne joue au «jeu de rêve», alors qui s'en soucie? Faites-le! Peut-être chanceux.

Moteur: pas la meilleure solution


Nous avons fait la version sur Ludum Dare sur le moteur Phaser.js . Nous le connaissons bien, nous connaissons bien le javascript, les jeux Web obtiennent plus de commentaires, c'est assez pratique et facile à apprendre - un conte de fées, pas un moteur.

Et nous avons été confrontés à une question importante: changer le moteur ou tout laisser tel quel?

La question était compliquée. Aucun de nous ne connaissait ou n'a étudié un autre moteur à ce moment-là. Passer du temps à étudier est une bonne chose, mais il a été possible de perdre tout enthousiasme. Et puis - que prendre? Javascript - le seul langage que chacun de nous connaissait, pour prendre le moteur C ++ / Java / C # - signifie perdre instantanément la moitié des développeurs. Et les moteurs de niveau Unity à l'époque semblaient trop encombrants pour un «jeu 2D simple».

Et puis: il y a déjà un jeu. Reste à mettre à jour le graphène, compléter les niveaux - et c'est tout. Travaillez pendant quelques mois. Et puis étudiez, réécrivez ...

En général, nous avons décidé de rester sur Phaser.js. Pire encore - nous avons décidé de rester sur la même base de code, c'est-à-dire Créez un jeu sur le prototype Ludum Dare.

Des commentaires sur un projet d'article
a333 : Désolé, je n'avais pas cette photo avec une béquille à la place de la Tour Eiffel "

Astuce n ° 2 non sollicitée: ne faites jamais ça! Cela est particulièrement vrai pour la réutilisation du prototype. Le code sur les confitures est toujours écrit rapidement et sale, sans tenir compte des développements futurs. Il y a une béquille, il y a une béquille, et maintenant vous comprenez que vous écrivez le code hérité tout de suite, et vous commencez immédiatement à en souffrir. Les prototypes doivent être lus attentivement, puis gravés dans / dev / null et réécrits, seulement déjà complets et propres.

Contre-conseil: prendre en compte, cependant, les caractéristiques de la psychologie. Il arrive qu'un retard de quelques semaines soit suffisant pour «se calmer». Mieux vaut faire un jeu avec une mauvaise architecture que de ne pas le faire du tout.

D'après les commentaires sur le projet d'article:
A333 : Je suis très enclin à cette option. Pour autant que je sache, c'est ainsi que la plupart des jeux se font, car le temps et les fusibles jouent un rôle clé. Si vous avez la possibilité de tout réécrire proprement sur un nouveau moteur, c'est bien, mais ce n'est pas toujours le cas. N'ayez pas peur d'écrire vite et mal, déployer les premiers prototypes, copier et coller des morceaux de code, et libérer zabago ... * sons de coups et gémissements étouffés *

En fait, quel est le problème avec Phaser.js?

  • Comme vous pouvez le deviner, le moteur est basé sur le Web. Vous savez comment sortir un jeu web sur Steam? C'est vrai, donnez-le avec Chrome en utilisant nw.js ou Electron. Je pense que les inconvénients de cette approche n'ont pas besoin d'être expliqués.
  • Les performances de javascript sont certainement assez bonnes, mais le code natif s'exécuterait plus rapidement et vous pourriez économiser sur les correspondances.
  • Contrôle de rendu très faible. Phaser lui-même restitue tout, et le fait globalement assez bien, mais parfois vous voulez entrer dans le processus ou faire quelque chose sur webGL par vous-même. Hélas, la seule chose que Phaser permet est d'appliquer le shader de fragment à l'écran dans son ensemble ou à des sprites séparés sur l'écran, et aussi avec modération. Il ne permet pas du tout de travailler avec des vertex shaders (et en effet de travailler avec des sommets), et de nombreuses décisions dans le jeu avec eux seraient beaucoup plus faciles.
  • Problèmes avec un grand nombre de sprites (objets actifs) à l'écran. De plus, le «grand nombre» est de quelques milliers, pas de millions. Et «l'objet actif» sera même une pierre couchée sans animations. Pour chaque tick, Phaser passera par tous les objets et fera sa propre magie spéciale de phaseur, effaçant le temps de la logique du jeu.

Nous avons résolu bon nombre de ces problèmes en cours de route, certains n'ont pas été résolus jusqu'à la fin. Il est difficile de juger sans expérience avec d'autres moteurs, mais il me semble que n'importe quel autre moteur permettrait de traiter des milliers d'objets de jeu sans astuces infernales. Cependant, je peux me tromper.

Guerre des styles


Vous souvenez-vous encore du «design original» de la version originale du jeu?


Bien sûr, il a son propre charme, mais il n'était pas adapté à un produit sérieux. Oui, et notre artiste vient de rentrer d'un voyage d'affaires, que va-t-il rester inactif?

Il ne s'est pas assis, ayant réalisé plusieurs esquisses d'un dessin possible. L'histoire a conservé deux chaises de style, entre lesquelles il fallait faire un choix.

Candidat 1: design minimaliste. En fait - les mêmes «pixels», seulement plus sympathiques. Tout est lumineux, contrasté. Il a l'air décent, mais, disons, solide. Dans le sens où un jeu qui ressemble à ça aura fière allure sur les téléphones portables ou VKontakte quelque part entre tetris et arkanoid. Mais rapidement et à moindre coût.


Candidat 2: réaliste, fantastique, dur. Ici, vous pouvez déjà voir une certaine histoire, un contexte. De façon inattendue, le contraste fonctionne non seulement dans les couleurs, mais aussi dans les formes - nos bâtiments sont plus ordonnés et carrés, les bâtiments ennemis - de forme ronde et irrégulière.



Cela ne veut pas dire que nous avons longtemps hésité. Nous avons imaginé laquelle des «captures d'écran» nous aimerions jouer le plus, et le premier candidat n'avait tout simplement aucune chance de survivre. Nous ne savions pas ce que nous aurions pour l'intrigue, où tout cela se passe, ce qui se passe - mais nous avons choisi l'option deux.

Bien sûr, il n'y a rien à comparer, mais il me semble que c'était une bonne option. Oui, nous aurions terminé la première option plus rapidement, cela aurait été moins exigeant en termes de performances et de graphisme, et il aurait probablement même été possible de le porter sur des téléphones portables.

Mais nous voulions jouer la deuxième option.

Les micro-organismes et la boîte de Pétri ont donc été remplacés par une planète lointaine, des robots et un mystérieux organisme étranger.

Conseil banal non sollicité numéro 3: faites ce que vous voulez jouer vous-même.

Contre-conseil: si vous avez 3 hypothèques et aucun autre emploi, personne ne vous reprochera de faire quelque chose qui se vend bien, mais vous voulez vous laver les yeux et les mains avec du savon.

Biomasse accroupie, ver caché


J'ai mentionné le contraste des couleurs et des formes, et si vous comparez ce croquis et la version finale - le contraste ne faisait que s'intensifier. Comparez - les carrés de nos bâtiments, les bâtiments ennemis ronds et la rondeur générale de la masse rouge.


Soit dit en passant, la masse rouge, comme presque tout dans le jeu, quelque part à l'intérieur de la logique du jeu, s'intègre dans la grille de la même manière que les blocs. Mais elle a l'air en même temps chaotique, comme si elle était déliée du filet.

J'ai encore une démo où j'ai débogué l'apparence de la biomasse. Tout y est disposé comme suit: un «carré» conditionnel est pris et rempli de cercles de différentes tailles aussi densément que possible. Voici un exemple d'un tel remplissage. Dans le jeu lui-même, le remplissage est plus dense (et donc moins lisible).

Entre les cercles, il y a des lignes - des connexions. Si la biomasse doit se développer en certaines cellules, des cercles appropriés sont sélectionnés qui se croisent avec les cellules nécessaires, et la croissance se produit en elles le long des lignes.


Voici à quoi cela ressemble en mouvement:


D'après les commentaires sur le projet d'article:
icxon : la première fois que je vois cette démo, lol
Dans le jeu lui-même, tout fonctionne exactement de la même manière, sauf que toutes les tailles, couleurs et vitesses sont ajustées par notre artiste pour mieux paraître.


Oh, il me semble que j'ai oublié de dire d'où venait exactement une telle décision, comment les étapes de la discussion se sont déroulées, les candidats ont été balayés ...

Mais non, je n'ai pas oublié. Il n'y en avait pas. Au départ, nous avions prévu de tout faire comme dans la version LD, c'est-à-dire croissance par carrés. Un soir, je me suis ennuyé et j'ai dessiné cette démo pour m'entraîner. Et les gars sont partis. Alors ils l'ont fait.

Astuce n ° 4 non sollicitée: plans, plans, mais n'ayez pas peur d'essayer quelque chose de nouveau. L'intuition peut vous dire une bonne décision.

Contre-conseil: si vous avez déjà fixé une date de sortie et signé un contrat avec un éditeur - vous ne devriez peut-être pas expérimenter.

Animation biomasse


Dans les gifs ci-dessus, vous pouvez remarquer l'animation inactive de la biomasse - même au repos, elle respire intensément, les boutons rouges semblent s'ouvrir et se refermer. Dans un monde idéal, il s'agirait de sprites avec une animation soigneusement dessinée par l'artiste, qui sont disposés dans le même motif avec des cercles. En réalité, ce seraient des milliers d'objets de jeu que Phaser.js ne pouvait tout simplement pas gérer. Et c'est déjà un fait vérifié - dans la version avec Ludum Dare, j'ai déjà rencontré des freins infernaux lorsque la biomasse remplissait au moins la moitié de la carte, et il n'y avait même pas d'animation inactive là-bas.

Un shader vient à la rescousse, qui tourne sur le GPU et ne prend pas de processeur. Encore mieux, si ce shader est vraiment simple - il ne chargera pas trop la carte vidéo.

Le shader doit en quelque sorte dire quoi et comment le dessiner. Quels sont les moyens de transférer des informations vers le shader:

  • Hardcode dans le code shader lui-même. Dans notre cas, cela ne correspond pas, mais en général, cette option a parfois du sens.
  • Via des variables uniformes (ce sont des variables identiques pour n'importe quel pixel de l'image)
  • Via des variables variables (variables interpolées entre deux sommets)
  • Grâce aux textures (encodage de certaines valeurs avec des couleurs)

La méthode 3 pourrait nous être utile, mais dans le cas de Phaser.js, elle n'est pas disponible pour nous. Vous ne passerez pas beaucoup à travers l'uniforme (par exemple, un tableau de tous les cercles avec leurs rayons ne rentrera pas dans les uniformes - il y a des restrictions). La texture reste.

L'astuce est la suivante: je dessine d'abord un état (disons, bourgeons fermés) en bleu:


Ensuite, le deuxième état (bourgeons ouverts) est rouge:


Si vous les ajoutez ensemble, vous obtenez un désordre violet:


Le shader voit la texture, voit l'heure actuelle, et avec une certaine période nous montre cet état «bleu», puis «rouge», qui coule en douceur entre eux. Eh bien, en appliquant lui-même la palette de couleurs souhaitée. Il se présente comme ceci:


D'après les commentaires sur le projet d'article:
a333 : Ah c'est comme ça que ça fonctionne
icxon : c'est cool parce que je ne comprends toujours pas comment ça marche
La même chose, mais avec l'exemple des rectangles:

Texture:

Animation finale:

La texture n'est mise à jour qu'au fur et à mesure qu'elle grandit / s'effondre, le reste du temps, l'animation gpu uniquement fonctionne.

Soins aux joueurs


Dans le processus de développement, nous avons essayé de ne pas oublier les joueurs qui voient notre jeu pour la première fois. Ce n'est pas aussi simple qu'il y paraît - après un certain temps, l'œil devient flou et vous commencez à considérer comme évident tout ce que vous, en tant que développeur, connaissez déjà.

Nous l'avons compris, et donc le premier test bêta a été effectué 8 mois avant la sortie - dès que nous avions les 10 premiers niveaux et 40 à 50% du contenu prêt. Ce test bêta a donné un excellent retour de conception de niveau dont je parlerai la prochaine fois. En même temps, nous avons appris que nous avions nous-mêmes de bonnes prédictions sur certains points.

Situation: il y a une base de joueurs à défendre - sa destruction conduit à l'échec de la mission. Le joueur ne surveille pas constamment la base - il regarde son avatar de robot. De plus, il surveille constamment - le rythme du jeu est assez rapide, il n'y a pas beaucoup de temps pour se tenir debout et contempler. En conséquence, nous, les testeurs, n'avons parfois pas remarqué l'ennemi qui était derrière l'arrière, bombardant la base.

Solution: premièrement, nous montrons les dommages à la base en cercles concentriques passant par une demi-carte.


Deuxièmement, si la base est considérablement endommagée, elle riposte indépendamment, balayant les ennemis, ce qui est clairement visible et exprimé. Cela attire l'attention du joueur sur le problème et donne le temps d'agir.


Situation: comme dans un Tower Defense typique, les ennemis suivent un chemin battu. Cependant, cet itinéraire n'est pas toujours deviné. Et comprendre l'itinéraire est très important pour une défense réussie: certaines tours tirent très près, et une tour qui est trop proche sera démolie par la prochaine vague.

Solution: puiser du sang après avoir tué des ennemis. Après un certain temps, une trace claire apparaît sur le sol, sur laquelle vous pouvez vous concentrer:


Question: mais, en fait, pourquoi les sentiers battus? Savez-vous comment implémenter A *?

Réponse: mis en œuvre plusieurs fois :) nous avons honnêtement expérimenté l'IA ennemie. Nous avions des vers intelligents à la recherche de la route et des boues évitant les balles. Il est devenu impossible de jouer. Le joueur ne pouvait pas construire une défense efficace et ne pouvait pas être content de voir comment cela fonctionne. Le plaisir du jeu a chuté. Cela ne signifie pas que les ennemis «intelligents» sont mauvais. Juste pour la mécanique choisie - lorsque nos bâtiments sont statiques - de tels ennemis ne convenaient pas. Pour les «ennemis intelligents», vous devez attacher une mitrailleuse à un robot ou des jambes aux tours. Et c'est un jeu complètement différent - pas celui que les gens ont aimé sur LD et itchio.
D'après les commentaires sur le projet d'article:
icxon : Mais il y a encore des boues. Et ils esquivent encore
GRaAL : pensez à un peu de fiction

Ils le sont vraiment, mais ils esquivent beaucoup plus paresseusement que dans la version originale

Situation: l'ennemi a des canons à longue portée (mortiers) qui peuvent être hors de la visibilité du joueur. Au tout début, presque tout le champ est caché derrière le brouillard de la guerre, à cause duquel l'arrivée d'obus ennemis pourrait passer inaperçue - ils ont volé hors de l'obscurité et ont immédiatement causé des dommages. Si le joueur regardait ce moment dans la direction opposée, il pourrait ne pas comprendre ce qui s'est passé.

Solution: un projectile volant est visible au-dessus du brouillard de guerre. Cela donne au joueur la possibilité de remarquer la menace et d'agir.


En parlant d'obus. Détournons-nous des problèmes de gameplay-UX.

Gestion des collisions


Dans la version LD des objets en mouvement, il n'y en avait pas tellement - une douzaine de balles et une douzaine de vers à chaque instant. Ce n'était pas suffisant dans le match. Pour relever le défi, vous avez dû augmenter le nombre d'adversaires et en même temps donner au joueur des armes à tir rapide pour contrer. Donc dans le jeu, cette situation n'est pas rare:


Pour tous les objets du jeu, les collisions doivent être prises en compte. Les balles se brisent contre les vers, les vers se brisent dans les blocs, et tous sur l'écran - parfois plusieurs centaines. Et les canons devraient choisir leurs cibles à portée. Si dans la version LD, nous pouvions nous permettre d'itérer sur tous les ennemis à la recherche de ceux qui leur convenaient, alors là, cela commençait déjà à ralentir.

En général, ce problème a des solutions, sur un habr j'ai souvent rencontré des articles sur ce sujet (en voici un ). Comme nous avons une grille logique à l'écran et que la plupart des objets actifs ne dépassent pas 2x2 cellules de jeu, nous avons décidé d'utiliser cette grille pour déterminer les collisions.

Chaque cellule a une liste d'objets qui se trouvent dans cette cellule. Il existe des objets statiques (tels que des blocs ou des pierres) qui occupent exactement une cellule dans son ensemble et ne se déplacent nulle part. Et il y a des dynamiques qui se déplacent le long de la grille, «circulant» d'une cellule à l'autre.


Parce que un objet peut être situé quelque part à la frontière de deux cellules (bien que son centre se trouve clairement à l'intérieur d'une seule), puis, lorsque les collisions sont prises en compte, toutes les cellules voisines sont examinées. C'est-à-direnous prenons une puce avec les coordonnées X, Y et voyons ce qui se trouve dans les cellules (X, Y), (X + 1, Y), (X-1, Y), (X, Y + 1), (X, Y -1). S'il y a des objets avec lesquels la balle peut interagir, alors pour chacun d'eux exactement la collision est calculée en fonction de la forme et de la taille.

Afin de ne pas se lever deux fois, la même grille est utilisée pour sélectionner les cibles par tours. Après sa création, la tour «s'abonne» à certaines cellules de la grille. Si quelque chose qui peut être tiré pénètre dans la cage, la tour reçoit une notification (et généralement après cela tire). Ainsi, si mille ennemis rampent évidemment loin de la tour, la tour ne perdra pas de temps à compter la distance qui les sépare.


Si la carte est grande, les cellules de la grille deviennent également nombreuses et toutes les mises à jour et vérifications commencent à prendre plus de temps. De plus, les problèmes commencent s'il y a des bâtiments / unités de la taille de plusieurs cellules - pour eux, vous devez vérifier plus de cellules autour.

Pour niveler ces moments, nous avons mis un grand, 16 x 16 cellules de taille, au-dessus du maillage fin. Tout est considéré comme le même pour elle, et il est utilisé pour éliminer rapidement les situations où il n'y a rien dans le rayon de plusieurs cellules autour des objets et les collisions ne peuvent pas être vérifiées.

Liens promis et enquête


L'article s'est avéré être déjà assez long, et Dieu nous en préserve, ma liste de sujets dans un cahier a diminué d'un quart. Dites-moi, que seriez-vous intéressé d'entendre dans le prochain article? Vous pouvez voter pour quelques points.

Eh bien, s'il y a soudainement des questions spécifiques sur la façon dont cela est fait ou pourquoi c'est fait - écrivez dans les commentaires. Nous répondrons si nous nous souvenons :)

Liens vers le jeu:


Merci à tous pour votre attention.

Source: https://habr.com/ru/post/fr429920/


All Articles