2017-01-13 1 views
2

Tout d'abord à épargner qui que ce soit pas très intéressé par ce roman tout, il n'y a pas de code à cette question, il est purement théorique. Je suis sur mon téléphone et c'est une question sur le choix qui convient le mieux et le plus facile à travailler dans la situation.C# XNA - int [,] tableau ou carreaux [,] tableau pour tilemap

donc à la question, je travaille sur ce que je crois, devrait être un moteur de base tilemap * et je suis dans le doute au sujet de mon approche. Je l'ai déjà réécrit plusieurs fois. Pas que cela ait pris trop de temps, le projet est encore dans sa couche pour dire le moins.

Fondamentalement, j'ai une classe Sprite avec ce constructeur: string name, int Id, texture Texture2D.

Et puis il y a ma classe Tile qui dérive de la classe Sprite, avec ceux-ci ajoutés au constructeur: Int X, int Y, bool walkable.

Dans ma première tentative, j'utilise un tableau d'entiers 2D et reçoit la valeur d'identification de la tuile à la position désirée sur la matrice. Et puis lors du dessin du tilemap je doublerais la boucle ** le tableau entier et trouverais la tuile avec le même ID que la position de tableau actuellement dans la boucle avec une fonction de tuile, qui retournerait une nouvelle tuile, que j'aurais alors continuer à dessiner avec les boucles X et Y actuelles (multipliées par la taille de la texture, pour des raisons évidentes). Parce qu'à ce stade, ma classe Tile n'avait pas de valeurs X et Y. Ce qui m'a semblé être un sacré bond en avant et, pour une raison ou une autre, j'ai senti que c'était une sorte d'approche primitive.

Ensuite, je suis allé avec une autre approche, j'ai fait un tableau 2D Tile et au lieu de devoir assigner une valeur ID à chacune des positions des tableaux, puis l'assortir, en faire une nouvelle instance, puis je dessine pourrait simplement boucler le tableau et faire de la table une nouvelle instance de la tuile désirée avec les X et Y actuels dans le constructeur, puis dessiner avec le Tile.X et Tile.Y. Semblait plus approprié.

au moins pendant environ une seconde avant que je courais le code, il l'a fait. Voir, maintenant je devais peupler entièrement le tableau avec des tuiles avant que j'aie essayé de le dessiner, sinon il renverrait une référence d'objet nul (bien sûr), parce qu'auparavant j'avais une tuile avec l'ID de 0, ce qui serait Dessinez simplement par défaut si rien d'autre n'a été assigné. Quelque part dans tout le désordre que j'avais avant, j'ai aussi eu un petit "si" qui disait simplement de ne pas dessiner si l'ID était 0, mais c'est plus tard que j'ai ajouté cela. Je me rends compte maintenant que je pourrais faire la même chose avec le tableau Tile, juste au lieu de vérifier si 0, puis en vérifiant si null je suppose. Mais, je m'en fous de vérifier si null. Encore une fois, cela semble primitif d'une certaine façon pour moi, comme si le code n'est pas entièrement pensé et fait quelque chose qu'il n'est pas censé faire. Aussi, je serais maintenant dans une sorte de cornichon si j'essayais d'analyser un simple fichier xml en tant que tilemap, parce que je ne saurais pas comment faire correspondre le xml avec une tuile, où j'aurais pu auparavant utiliser les ID. Btw, je n'ai jamais travaillé avec xml auparavant, donc je ne peux que deviner si ce serait un problème.

* bien que si quelqu'un préciserait exactement quand ou pourquoi un « projet » pourrait être considéré comme un moteur, mais de base, il peut être, alors ce serait cool aussi. Parce que je ne pense pas que je comprends tout à fait encore.

** J'ai réalisé qu'il serait plus approprié d'utiliser foreach dans cette situation, mais cela ne fonctionnerait qu'avec le tableau Tile, afaik. Donc, pour finir ma question .. Qu'est-ce qui convient le mieux? L'int [,] ou le Tile [,] pour un tilemap? Et, devrais-je au lieu d'utiliser 2 ints X et Y non liés utiliser vector2 dans la classe Tile pour le positionnement?Note - Je suis un étudiant en informatique, et nous n'avons eu que la formation de base «bonjour monde» jusqu'à présent, le reste que j'ai appris est d'intérêt personnel. Aussi, s'il vous plaît corrigez-moi s'il y a des défauts, ou des termes mal utilisés. Je demande ici parce que je veux de l'aide, et je vais prendre toute aide offerte, que ce soit sur ou hors sujet. Cependant, j'apprécierais que cela soit donné de manière appropriée et constructive, s'il vous plaît. Edit: Sht Sht, je ne savais même pas que j'avais écrit autant. Pour celui qui lit tout cela, vous êtes le vrai MVP!

+0

J'ai aimé lire ceci mais je n'ai pas de réponse pour vous. Positif impressionnant pourtant au sujet de Monogame et de la théorie de tuile! – jhhoff02

+0

Ma structure de carte pour une carte relativement petite et bien délimitée est généralement un tableau 2d de 'TileStack'. Avec 'TileStack' possédant des métadonnées sur les coords, et une' List' de 'Tile'. 'Tile' contiendra alors l'identifiant du Tile, et des informations supplémentaires sur l'occurrence du tile, telles que la couleur, les offsets, la rotation, etc. –

Répondre

1

Il est possible que certaines régions de votre jeu ne comportent pas qu'une seule case, elles peuvent avoir plusieurs cases les unes sur les autres. Par exemple, une table qui se trouve sur le sol pour que vous puissiez voir à la fois les carreaux de sol et les carreaux de table semi-transparents. Cela signifie qu'un simple tableau 2d de tuiles ne sera pas suffisant dans ce cas.
Peut-être une liste d'occurrences de tuiles ayant chacune ses coordonnées de dessin? Ensuite, il vous suffit de faire défiler la liste et de dessiner des carreaux sur l'écran dans l'ordre de leur choix.

0

Je ne sais pas si c'est encore pertinent, mais de toute façon. D'après mon expérience, certainement utiliser Tile [,] et pas seulement int [,], penser à l'avenir (surtout quand vous construisez des moteurs, qui doivent être très génériques), peut-être quelqu'un voudra que la tuile soit animée ou entrer logique à la tuile.

Ce que vous pouvez faire est de construire le tilemap en utilisant int [,] mais il est préférable d'utiliser XML. Astuce: au lieu de boucler sur TileID ou d'utiliser un long switch-case (ou beaucoup de ifs ofc), vous pouvez les stocker dans un dictionnaire (qui est l'implémentation C# de HashMap) et vous les obtiendrez avec une complexité de O (1) au lieu de O (n) (Ce qui peut être crucial et non dépend de la quantité de tuiles que vous avez). Vous pouvez stocker dans un dictionnaire le délégué de la fonction de création.

Le principal problème de ne pas utiliser Tile [,] ou int [,] est la détection de collision. Vous devrez boucler sur l'ensemble de la collection de tuiles, au lieu de simplement calculer les index corrects (ou la gamme d'index). Le calcul devrait ressembler à ceci: j = x/tilewidth; (Encore une fois O (1) au lieu de O (n), ici c'est très important).

Si vous voulez avoir plus d'une couche sur votre tilmap (pour les tables, chaises, plantes, etc.), vous pouvez créer une classe Layer (qui doit contenir Tile [,]) ou utiliser Tile [,,,] où le premier index est la couche. Je pense que le premier est meilleur car le dernier est plus complexe à travailler et moins générique.

0

Vous pourriez faire les deux! Stockez vos "données de tuile générales" quelque part, et stockez des données spécifiques aux tuiles de carte (les données relatives à 1 tuile dans la carte, pourraient être appelées MapTile ou quelque chose) dans une liste. Ainsi, votre classe Tile contiendrait le sprite, l'état "walkable" et ainsi de suite, et votre MapTile contiendrait une référence à son modèle de tuile, sa position dans la carte, sa couche, et peut-être son état, dans Bref, toute donnée propre à cette case spécifique de la carte.

Lorsque vous voulez dessiner vos tuiles, il vous suffit de faire défiler la liste de MapTile et de dessiner le modèle associé à la position de la tuile. De cette façon, vous réduisez l'utilisation de la mémoire tout en conservant les fonctionnalités de la méthode Tile [,].