J'ai un jeu qui génère une carte de niveau aléatoire au début du niveau. Je veux implémenter un moyen d'enregistrer et de charger le niveau.
Je pensais que peut-être XML serait une bonne option pour enregistrer toutes les variables, alors il serait facile pour moi de créer quelque chose qui puisse analyser ce XML et générer exactement le même niveau.
Mais XML est probablement exagéré pour mes besoins. Je me souviens à l'époque avec l'ancienne console Sega qui n'avait pas la capacité de sauvegarder votre jeu (je pense que le jeu Worms l'a fait aussi), qu'ils vous donneraient un tas de personnages que vous pourriez écrire. Si vous insériez cette chaîne plus tard, elle chargera le niveau exact.
Une "chaîne de niveau" serait-elle une bonne option? Serait-ce une sorte de conversion "base60"? Comment pourrais-je implémenter cela?
Quel que soit le format que vous utilisez pour vos sauvegardes, pour l'amour de Dieu, entrez un numéro de version. Vous pourrez avoir des chargements rétrocompatibles en vous ramifiant sur le numéro de version, ou vous pourrez reconnaître en toute sécurité les sauvegardes qui sont trop anciennes charger.
Vous le regretterez si vous ne le faites pas.
la source
JSON est bon, mais YAML est meilleur. :) http://www.yaml.org/ et http://code.google.com/p/yaml-cpp/ pour l'une des implémentations les plus agréables à utiliser.
YAML est un sur-ensemble de JSON qui ajoute la prise en charge de quelques fonctionnalités intéressantes, notamment:
la source
Si vous souhaitez sérialiser toutes les données du jeu, je recommanderais JSON comme format de fichier, c'est pourquoi il est plus facile d'utiliser le XML et le support est très bon dans de nombreuses langues.
J'ai utilisé cette bibliothèque pour C ++ et cela fonctionne très bien.
http://jsoncpp.sourceforge.net/
la source
XML est un bon choix si vous n'êtes pas limité par sa taille et qu'il est pris en charge nativement (par exemple en .NET et Flash) mais si vous voulez un format mince, vous pouvez créer votre propre format et analyseur assez facilement. J'utilise normalement 1 caractère par exemple. virgule pour séparer chaque objet. Pour décoder la chaîne, effectuez une scission sur virgule. Maintenant, chaque objet a besoin de propriétés différentes, alors séparez-les avec un caractère différent, par exemple un point-virgule, et utilisez un autre caractère pour séparer les noms de propriété des valeurs de propriété, par exemple. Côlon. Tout peut donc être décodé facilement sans regex simplement en utilisant string.split. Voici un exemple:
vous pouvez économiser encore plus d'espace en gardant les noms de propriété à 1 caractère, par exemple h pour la santé. Par exemple.
Comparer à l'alternative JSON:
De plus, si vous souhaitez réduire la taille de vos numéros, vous pouvez les encoder en utilisant l'ensemble complet de caractères UTF16 imprimables. Ce fil m'a inspiré à poser une question sur Stack Overflow sur la quantité de données que vous pourriez emballer dans un caractère à l'écran . La réponse semble être quelque part au-dessus de 40000 valeurs pour un entier, si cela ne vous dérange pas d'avoir des pièces de brail, de kanji et d'échecs: ♔♕♖♗♘♙♚♛♜♝♞♟
Pour obtenir une réduction de taille supplémentaire, vous pouvez utiliser l'ordre de lecture / écriture pour déterminer quelle valeur est laquelle, de sorte que les deux premiers caractères représentent l'id, les deux suivants sont la position x, les deux suivants l'y, puis l'angle, puis la santé , etc. Donc:
pourrait stocker toutes les mêmes informations que les autres exemples.
Les grilles de tuiles peuvent être stockées comme une simple chaîne, chaque caractère représentant un type de tuile différent, par exemple:
où je pourrais dire la lave, 9 signifie l'herbe, etc.
la source
Si vous codez en .Net, XML est très facile à utiliser, car vous pouvez sérialiser / désérialiser votre classe de niveau en / hors de XML avec seulement quelques lignes, puis tout cela dans une classe bien gérée.
TheMap serait une variable de type Map dans laquelle toutes vos données sont chargées.
En supposant que vous avez une classe Map déjà construite, cela enregistrerait votre carte en XML:
Cela chargerait ensuite ce XML dans votre classe de carte, pour être à nouveau utilisé dans le code.
À partir de ce moment, votre fichier XML est maintenant chargé dans votre classe pour une utilisation facile.
En ce qui concerne votre problème "Level String", ce qui a été dit auparavant fonctionnerait très bien, vous pouvez simplement utiliser le numéro de graine comme "Level String".
Sinon, vous pouvez simplement pré-générer autant de cartes différentes que vous le souhaitez, et les avoir toutes enregistrées avec une "chaîne de niveau", puis l'utiliser pour afficher la carte appropriée.
la source
J'utiliserais un appareil simple
struct
ou similaire (selon votre langue) pour stocker tous les états du jeu dans un endroit central. Si vous voulez la protection des setters / getters, vous pouvez envelopper la structure dans aclass
.Si vous vous sentez à la hauteur, utilisez des champs de bits ou faites vous-même la manipulation de bits à l'aide d'opérateurs au niveau du bit.
Sachez que dans certaines langues, les règles de remplissage et d'emballage des structures peuvent être un peu compliquées - mais cela peut aussi ne pas avoir beaucoup d'importance pour votre cas si vous avez un ou deux octets de remplissage.
Vous pouvez également être en mesure d'utiliser un
#pragma
(tel que#pragma pack(1)
) ou un__attribute__
pour emballer étroitement la structure, éliminant ainsi le rembourrage. Cela peut ou non fonctionner selon votre compilateur et votre architecture cible.Notez que l'utilisation de champs de bits et de pragmas ou d'attributs de pack peut réduire la portabilité. À travers les architectures matérielles, l'endianité du champ struct (ordre des octets) peut également changer. Donc, vous voudrez peut-être éviter cela si vous essayez la portabilité.
(Par exemple, Pac-Man, cette structure peut contenir naïvement un identifiant de carte ou une graine de carte, une position Pac-Man x et y, quatre positions fantômes x et y et un grand champ de bits pour la présence ou l'absence de 32 à 64 pastilles, quel que soit le maximum.)
Une fois que vous avez votre structure, passez-la à quelque chose comme une fonction xxencode :
L'écriture de cette fonction est un peu sujette aux erreurs; vous devez décaler et combiner les octets si nécessaire pour obtenir par exemple 6 bits à la fois, puis traduire en un caractère approprié. J'essaierais personnellement de traquer le code de quelqu'un d'autre, à moins que je ne le fasse pour le "plaisir" (et je voudrais probablement une suite de tests pour cela).
Ne sous-estimez jamais le pouvoir de la vieille école
struct
aux bons endroits. Nous l'avons utilisé une tonne pour les jeux GBA et DS ici.la source
XML est bon pour les documents à structure arbitraire (les éléments peuvent apparaître à différents niveaux de l'arborescence) ou pour l'incorporation de format étranger (comme mettre svg dans une page xhtml). Si vous n'avez pas ces exigences, c'est un format vraiment inefficace, et quelque chose de plus simple comme csv ou json est préférable.
la source