À propos de
Ce sont en fait deux questions en une. Tout d'abord, je cherche un moyen de stocker efficacement de grandes quantités de données de tuiles. L'autre aspect concerne l'interrogation de l'ensemble de données et l'affichage des vignettes. Permettez-moi de vous donner quelques informations en premier.
Nous créons un jeu de magnat multijoueur basé sur un navigateur utilisant la bibliothèque CraftyJS pour le rendre sur Canvas. En arrière-plan de l'interface graphique, nous exécutons Yii Framework sur PHP et tout cela se connecte à un générateur de carte aléatoire Python et à un moteur de jeu.
Voici à quoi ressemble le premier rendu de carte approximatif: http://i.imgur.com/khAXtl.png
Stockage des données cartographiques
Le monde du jeu est généré aléatoirement à chaque démarrage du jeu. La taille est de 100x100 tuiles hexagonales pour chaque joueur. Cela signifie que pour une partie à trois joueurs, 90 000 tuiles sont créées. Actuellement, je viens de créer un tableau JavaScript à partir duquel je rends la carte.
Cela fonctionne bien pour le rendu, mais pour tout type d'interaction avec la carte, nous devons stocker quel joueur possède la tuile, quel type de structure est construit par-dessus, quel est son prix actuel, etc. Au début, au moins pour le prototype, nous voulions utiliser MySQL, mais après quelques tests, ce n'est pas exactement aussi rapide que je le souhaiterais. Peut-être qu'un magasin d'objets comme MongoDB serait mieux adapté pour stocker des données de tuiles au lieu d'une table SQL. Ou peut-être autre chose?
Affichage de la carte
Un autre problème que je vois se déplace sur la carte. Actuellement, je crée des entités Crafty pour chaque tuile même si elle n'est pas dans la fenêtre. Ceci est lent, car même si Crafty ne rend que ceux de la fenêtre, il stocke et peut-être itère toutes les tuiles de chaque événement de rendu. Ce que j'ai actuellement est une carte générée dessinée qui est très lente à charger et bégaie lorsque vous vous déplacez, maintenant j'aimerais la rendre jouable.
Ma première idée a été de charger le sous-ensemble de tuiles affiché dans la fenêtre. Mais lorsqu'un joueur déplace la fenêtre dans une zone vide, je dois interroger le serveur et attendre la réponse, ce n'est qu'alors que la carte peut être rendue. Ce serait bien dans une application native, mais c'est lent dans un jeu Web.
Le moyen d'obtenir des performances fluides à partir de la carte pourrait être de précharger un sous-ensemble plus important de tuiles dans un tableau javascript et de l'utiliser comme cache. Le joueur aurait quelques écrans "mis en cache" et quand il déplacerait la fenêtre, je chargerais plus de tuiles dans le "cache" JS.
Suis-je dirigé dans la bonne direction? J'aimerais obtenir plus d'informations de la part de quelqu'un qui a fait quelque chose de similaire. Je suis nouveau dans le développement de jeux, mais j'ai parcouru de nombreuses sources au cours des dernières semaines.
la source
Réponses:
Gameplay
Tout d'abord, je voudrais vous demander, avez-vous réellement besoin de 10000 tuiles par joueur? Bien que je ne sache pas quel type de jeu vous créez, il est généralement vrai que les grandes cartes font de longs jeux. La plus grande carte de Civilization 5 est 10240 tuiles, et cela ne fonctionne que parce que vous n'avez pas besoin de jouer sur plus d'une fraction de celle-ci.
Base de données
Vous ne devez pas essayer d'exécuter un jeu comme celui-ci à partir d'une base de données, vous devez conserver les données dans la mémoire de l'application. Vous pouvez utiliser une base de données pour sauvegarder le jeu. Pour une sauvegarde complète, enregistrez une sérialisation des données du jeu, puis vous pouvez l'incrémenter en enregistrant les commandes données, puis réexécutez-les si la sauvegarde doit être utilisée.
Stockage JavaScript
En ce qui concerne le client, je dirais que vous feriez mieux de garder la carte entière chargée, au moins si vous vous en tenez aux gazillions, tout avoir dans une belle arborescence d'objets pourrait être un peu trop, donc vous devriez probablement garder les données dans un format codé "semi-binaire". Les chaînes fonctionnent parfaitement pour ce genre de choses, alternativement, vous pouvez stocker en toute sécurité des entiers non signés jusqu'à 53 bits dans un flottant de 64 bits, beaucoup de ceux dans un tableau et je pense que vous verrez une empreinte mémoire assez modeste.
Visualisation JavaScript
Bien que je ne dise pas que vous ne devez pas nécessairement utiliser le canevas, vous n'en avez en fait pas besoin pour des choses comme celle-ci. Définissez le tout comme un groupe d'éléments img et modifiez la propriété src pour afficher différentes parties de la carte.
Conseil de pro Au fait, il est parfois plus facile de partager la graine utilisée pour la générer que de partager la carte entière.
la source
MySQL n'est pas lent. Vous effectuez probablement des requêtes naïves ou avez des index sous-optimaux. Les approches NoSQL comme MongoDB peuvent être plus rapides, peut-être pas. Votre modèle d'accès et votre choix de requête sont ce qui compte vraiment ici. Il est possible de donner des conseils sur la façon d'améliorer les performances, mais pas sans voir ce que vous faites déjà.
Oui bien sûr. Il n'y a pas grand-chose à ajouter ici - le client demande des tuiles au serveur, il vous suffit donc de vous assurer que celles que vous demandez couvrent une zone plus grande que l'écran.
Addenda:
Si vous êtes compétent avec Python, je vous conseillerais d'abandonner l'intermédiaire PHP. Si vous exécutez votre jeu en tant que processus Python, vous pouvez conserver vos données de tuiles en mémoire beaucoup plus facilement et réduire considérablement les accès MySQL. Il est également utile que Python soit un langage beaucoup plus sain que PHP.
la source