Über
Dies sind eigentlich zwei Fragen in einer. Zunächst suche ich nach einer Möglichkeit, große Mengen an Kacheldaten effizient zu speichern. Der andere Aspekt betrifft das Abfragen des Datensatzes und das Anzeigen von Kacheln. Lassen Sie mich zunächst einige Hintergrundinformationen geben.
Wir erstellen ein browserbasiertes Multiplayer-Tycoon-Spiel, das die CraftyJS-Bibliothek verwendet, um es auf Canvas zu rendern. Im Hintergrund der GUI führen wir Yii Framework auf PHP aus und alles verbindet sich mit einem Python Random Map Generator und einer Game Engine.
So sieht das erste grobe Karten-Rendering aus: http://i.imgur.com/khAXtl.png
Speichern der Kartendaten
Die Spielwelt wird bei jedem Spielstart zufällig generiert. Die Größe beträgt 100x100 sechseckige Plättchen für jeden Spieler. Das bedeutet, dass für ein Spiel mit drei Spielern 90.000 Kacheln erstellt werden. Derzeit erstelle ich nur ein JavaScript-Array, aus dem ich die Karte rendere.
Dies funktioniert gut für das Rendern, aber für jede Art von Interaktion mit der Karte müssen wir speichern, welcher Spieler die Kachel besitzt, welche Art von Struktur darauf aufgebaut ist, wie hoch der aktuelle Preis ist und so weiter. Zumindest für den Prototyp wollten wir zunächst MySQL verwenden, aber nach einigen Tests ist es nicht genau so schnell, wie ich es gerne hätte. Möglicherweise ist ein Objektspeicher wie MongoDB besser zum Speichern von Kacheldaten anstelle einer SQL-Tabelle geeignet. Oder vielleicht noch etwas?
Karte anzeigen
Ein weiteres Problem, das ich sehe, ist das Bewegen auf der Karte. Derzeit erstelle ich Crafty-Objekte für jede Kachel, auch wenn sie sich nicht im Ansichtsfenster befindet. Dies ist langsam, da Crafty zwar nur die im Ansichtsfenster rendert, jedoch alle Kacheln jedes Renderereignisses speichert und möglicherweise durchläuft. Was ich derzeit habe, ist eine gezeichnete generierte Karte, die sehr langsam geladen wird und stottert, wenn Sie sich bewegen. Jetzt möchte ich sie spielbar machen.
Meine erste Idee war, die angezeigte Teilmenge der Kacheln zu laden, die sich im Ansichtsfenster befinden. Wenn ein Spieler das Ansichtsfenster in einen leeren Bereich verschiebt, muss er den Server abfragen und auf die Antwort warten. Erst dann kann die Karte gerendert werden. Dies wäre in einer nativen Anwendung in Ordnung, in einem Web-Spiel jedoch verzögert.
Die Möglichkeit, eine reibungslose Leistung der Karte zu erzielen, besteht darin, eine größere Teilmenge von Kacheln in ein Javascript-Array vorzuladen und als Cache zu verwenden. Der Spieler würde ein paar Bildschirme "zwischengespeichert" haben und wenn er das Ansichtsfenster verschiebt, würde ich mehr Kacheln in den JS "Cache" laden.
Bin ich auf dem richtigen Weg? Ich würde gerne mehr Informationen von jemandem bekommen, der etwas Ähnliches getan hat. Ich bin neu in der Spieleentwicklung, habe aber in den letzten Wochen viele Quellen durchgesehen.
quelle
Antworten:
Gameplay
Zunächst möchte ich Sie fragen, ob Sie tatsächlich 10000 Plättchen pro Spieler benötigen. Obwohl ich nicht weiß, welche Art von Spiel Sie machen, ist es im Allgemeinen wahr, dass große Karten lange Spiele machen. Die größte Karte in Civilization 5 besteht aus 10240 Plättchen, und das funktioniert nur, weil Sie nicht mehr als einen Bruchteil davon spielen müssen.
Datenbank
Sie sollten nicht versuchen, ein Spiel wie dieses aus einer Datenbank heraus auszuführen. Sie müssen die Daten im Anwendungsspeicher behalten. Sie können eine Datenbank verwenden, um das Spiel zu sichern. Speichern Sie für eine vollständige Sicherung eine Serialisierung der Spieldaten. Anschließend können Sie diese erhöhen, indem Sie die erteilten Befehle speichern und diese erneut ausführen, wenn die Sicherung verwendet werden muss.
JavaScript-Speicher
Was den Client betrifft, würde ich sagen, dass Sie die gesamte Karte besser geladen lassen sollten, zumindest wenn Sie sich an die Millionen Kacheln halten, die alles in einem schönen Objektbaum haben, könnte dies etwas zu viel sein, daher sollten Sie die Daten wahrscheinlich behalten in einem "semi-binären" codierten Format. Strings eignen sich hervorragend für diese Art von Dingen. Alternativ können Sie vorzeichenlose Ganzzahlen bis zu 53 Bit sicher in einem 64-Bit-Float speichern, viele davon in einem Array und ich denke, Sie werden einen ziemlich bescheidenen Speicherbedarf sehen.
JavaScript-Visualisierung
Obwohl ich nicht sagen möchte, dass Sie Canvas nicht unbedingt verwenden sollten, benötigen Sie es für solche Dinge eigentlich nicht. Richten Sie alles als eine Reihe von img-Elementen ein und ändern Sie die src-Eigenschaft, um verschiedene Teile der Karte anzuzeigen.
Pro-Tipp
Übrigens ist es manchmal einfacher, den für die Generierung verwendeten Startwert freizugeben, als die gesamte Karte freizugeben.
quelle
MySQL ist nicht langsam. Höchstwahrscheinlich führen Sie naive Abfragen durch oder haben nicht optimale Indizes. NoSQL-Ansätze wie MongoDB sind möglicherweise schneller, möglicherweise auch nicht. Hier kommt es wirklich auf Ihr Zugriffsmuster und die Wahl der Abfrage an. Es ist möglich, Ratschläge zur Verbesserung der Leistung zu geben, aber nicht ohne zu sehen, was Sie bereits tun.
Ja, sicher. Hier gibt es nicht viel hinzuzufügen - der Client fordert vom Server Kacheln an, sodass Sie nur sicherstellen müssen, dass die Kacheln, die Sie anfordern, einen Bereich abdecken, der größer als der Bildschirm ist.
Nachtrag:
Wenn Sie mit Python vertraut sind, würde ich Ihnen raten, den PHP-Mittelsmann loszuwerden. Wenn Sie Ihr Spiel als Python-Prozess ausführen, können Sie Ihre Kacheldaten viel einfacher im Speicher behalten und die MySQL-Zugriffe erheblich reduzieren. Es hilft, dass Python auch eine viel vernünftigere Sprache als PHP ist.
quelle