Browsergame: 2 Fragen <> Zeitverzögert und Koordinatensystem

Du kannst doch berechnen wo sicher der Nutzer nach t Sekunden befindet und dann updaten, wenn ein anderer Spieler ihn "sieht".

Aber ich kann ihn ja erst updaten, wenn ein User ihn sieht. Dazu muss der User ihn aber erstmal sehen. -> Klingt ein bisschen komisch :D - aber mein Problem ist ja genau das, wann sieht ein User denn den anderen User?

------

Das mit den zwischen Schritten in der DB hatte ich mir auch überlegt. Allerdings wird das bei über tausend Spielern und dann daraus resultierenden über 100.000 zwischenschritten auch nicht sinvoller - oder?
paD
 
Moin,

Das mit den zwischen Schritten in der DB hatte ich mir auch überlegt. Allerdings wird das bei über tausend Spielern und dann daraus resultierenden über 100.000 zwischenschritten auch nicht sinvoller - oder?
paD

Das dürfte weitaus sinnvoller sein, als es Live zu Berechnen.

Bei einer Live-Berechnung müsstest du erstmal für alle User ausrechnen, wo sie sind...dürfte auf Dauer kaum machbar sein.

Wenn du die gleich anfangs die Route speicherst, benötigst du später nur 1 Query, um festzustellen, wer sich grad in der Nähe befindet.

Das speichern sollte auch nicht so problematisch sein. Wenn du 1000 User hast, rennen ja zum einen nicht alle gleichzeitig los, und wenn sie unterwegs sind, ist ja erstmal für eine Weile nichts zu Speichern.
 
Moment mal, du willst ja auch während der Bewegung wissen, zu welcher Zeit, wer, wo in der Nähe ist?

Geht da ja vermutlich um Schiffe überfallen oder so?

Du könntest mal so überlegen: Du unterteilst den Raster noch einmal in so ca. 20x20 große Raster. Berechnet wer überhaupt bei der momentanen Bewegung diesen Raster kreuzen könnte, und berechnest nur für die.

Ich werde mir da noch was überlegen wenn ich Zeit habe, und mich dann noch einmal melden, da gibt es sicher eine brauchbare Lösung.

lg Darian
 
Ja, die Zwischenschritte sind dann wohl wahrscheinlich einfacher. Allerdings auch nicht so sauber.
Vorallem soll der User sich bewegen können, wie er will.. Das wird also eine riesige Zwischen-Schritt-Tabelle. Und wenn er dabei 700 Felder durchquert sind das 700 Einträge (längste weg aktuell auf meiner Karte (diese wächst aber auch noch weiter.. ;))).

Wenn ich jetzt sage alle X-Prozent vom weg speichert er einen Zwischenschritt, ist er zwischen den Schritten auch wieder "Unsichtbar"..


Allerdings bei 1000 Schiffen jedes mal alle Einträge zu durchrechnen, ob die gerade in der nähe sind wird den Server auch nicht gerade entlasten.. -.-

Vllt. sollte ich ganz von dem Aktuellen DB-Aufbau weg und das noch anders lösen?

paD
 
Eine andere Möglichkeit ist ein Cronjob, der allerdings nur minütlich ausgeführt werden kann. Der Cronjob könnte dann alle Minute die Position ermitteln und wegschreiben. Stattdessen kann natürlich auch ein Dämon eingesetzt werden. Nachteil beider Lösungen ist jedoch das asynchrone Verhalten.

Die Lösung der Zwischenschritte hat diesen Nachteil nicht. Zumal du hier Einträge der Vergangenheit löschen und die Daten somit schlank halten kannst. Mit gescheiten Indexen sind selbst große Datenmengen absolut kein Problem - selbst wenn 10.000 User gleichzeitig 700 Felder gehen, sind das nur 7.000.000 Einträge. Die Wahrscheinlichkeit, dass diese Situation eintritt ist so groß wie ein Lottogewinn.

Grüße
 
Also die Zwischenschrittlösung scheint mir mitlerweile dann wohl die beste.
Sehe ich das dann also so richtig:

Beim ändern des Zieles (beim Losfahren..) Speichere ich die Zwischenschritte in der Datenbank quasi:
SchiffID, px, py, zeit

Jetzt habe ich aber das Problem, wie speichere ich am besten die Zeit?
Oder wie lese ich diese am besten aus, wenn ich nach dem "WHERE zeit = time()" suche, müsste ich jede Sekunde speichern, was ja nicht sinvoll ist.

Könnte ich hier vllt. mit einem "BETWEEN" arbeiten? Aber dann wirds ja auch ein bisschen ungenau (was angesichts der anderen Lösungen wohl noch akzeptabel wäre ;))

Oder fällt mir einfach nicht ein, wie es besser gelöst wäre?

paD
 
Zunächst solltest du dich für ein Intervall entscheiden, welches du zum Berechnen der einzelnen Zwischenschritte verwenden möchtest. Angenommen es sind 10 Sekunden, dann würde ich beim Wegschreiben den ersten Schritt auf ein Vielfaches von 10 Sekunden genau aufgerundet weg schreiben (0, 10, 20, 30, 40, 50). die Nachfolgenden Schritte passen dann.

Beim Auslesen würde ich umgekehrt aber ebenfalls auf ein Vielfaches von 10 Sekunden abrunden (bei 5 => 0, bei 38 => 30, etc.).

Der Vorteil ist eine sehr triviale Abfrage auf die Datenbank auf eine genaue Sekunde. Die Datenbank muss da nicht groß rum wuseln. Zudem bringt die Datenbank eine Menge gescheiter Feld-Typen mit. Klar kannst du das auch gern mit einer INT Spalte lösen, aber ein TIMESTAMP ist da sicher eher angebracht. Auf diese Spalte solltest du im Übrigens unbedingt einen Index setzen ;).

Grüße BN
 
Also sieht das hier gar nicht so verkehrt aus? :)
Code:
CREATE TABLE IF NOT EXISTS `user_schiffe_wege` (
  `schiffid` int(10) unsigned NOT NULL,
  `zeit` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `px` int(10) unsigned NOT NULL,
  `py` int(10) unsigned NOT NULL,
  KEY `schiffid` (`schiffid`),
  KEY `zeit` (`zeit`),
  KEY `px` (`px`),
  KEY `py` (`py`)
);
 
default CURRENT_TIMESTAMP könntest du noch entfernen ;) Zudem wird sicher ein zusammengesetzter Index aus px, py und zeit sinnvoller sein als auf jedes Feld einzeln einen Index zu setzen. MySQL kann bei Abfragen lediglich einen einzigen Index einer Tabelle nutzen. Da du mit angrenzender Wahrscheinlichkeit in Abfragen auf diese Tabelle die Positionen und die Zeit abfragen wirst, ist ein zusammengesetzter Index auf diese Felder nur die logische Folge.

Grüße BN
 
joa, dieses CURRENT_TIMESTAMP wollte ich auch raus nehmen, allerdings gab mir phpMyAdmin immer nen Fehler aus, da habsch gelassen :)

Den Index hatte ich auch auf einen Index zusammengestaucht ;) - Hatte wohl die alte Tabelle im Zwischenspeicher :)

Vielen Dank jedenfalls für deine Hilfe - Thread hat sich somit erledigt :)

paD
 
Zurück