SendReliableMessage - Echtzeit Übertragung mit hohen Anforderungen

  • 11 Antworten
  • Neuester Beitrag
Diskutiere SendReliableMessage - Echtzeit Übertragung mit hohen Anforderungen im Android App Entwicklung im Bereich Betriebssysteme & Apps.
ui_3k1

ui_3k1

Gesperrt
Guten Morgen, seit ein paar Tagen beschäftigt mich folgende Frage:
Wie lassen sich Daten in (annähernd) Echtzeit übertragen und das dann auch noch sicher.
Folgendes Problem:
Ich habe bei meinem kleinen Spiel die Datenübertragung zwischen den Spielern so gestaltet, dass alle Positionsänderungen unreliable übertragen werden, sprich keine Prüfung stattfindet. Bei Schüssen und Treffern bekommt der andere Mitspieler eine Nachricht, die quittiert werden muss. So weit so gut. Wird also ein Schuss nicht quittiert (bzw eine Quittung erfolgt via "-1") weiß der Absender, dass etwas nicht stimmt und kann reagieren. In meinem Fall setze ich dann bei dem, wo der Fehler entstanden ist eine variable aktiv, die dann einmalig einen Schuss erzeugt.
Das funktioniert in ersten Testläufen schon ziemlich gut. Allerdings will ich jetzt mein Spiel dahingehend erweitern, dass auch Schüsse in einem variablen Winkel abgeben werden können und somit würde ein einfaches Signal zum Abschuss nicht mehr in Frage kommen, da ja weitere Informationen nötig sind um den Schuss auf dem anderen Gerät korrekt darstellen zu können. Ich habe schon die Google Doku halbwegs auswendig im Kopf - aber was diese Sachen angeht ist man doch ziemlich auf sich alleine gestellt. Bin mir auch darüber bewusst dass meine Frage wahrscheinlich schon eher speziell ist, aber gleichzeitig sehe ich genug multiplayer wo das alles funktioniert (allerdings sind die technisch wohl auch anders zu betrachten, da nicht p2p).

Ach so und wie weiß ich wie viele Daten ich sende? Bis dato umfasst mein Byte Array 8 ints (also 8x32bit) und bis zu 1400byte sind wohl möglich, erscheint mir aber als etwas viel.. So wären ja noch 97,8% frei
Welche Möglichkeiten gibt es noch die Daten zu übertragen?
 
Zuletzt bearbeitet:
StefMa

StefMa

Experte
Mit was überträgst du denn derzeit die Daten?!
Ich denke für sowas wäre die App Engine ideal...Aber nur meine erste Vermutung ;)

Gruß
 
ui_3k1

ui_3k1

Gesperrt
Derzeit nutze ich die libs rund um Google Play. Die dort angebotene Implementierung schreibt man halt auf sein Programm so um dass es passt. Kannst mal nach "SendReliableMessage" oder "SendUnreliableMessage" in der Doku schauen, so an sich ist es schon super erklärt. (hätte auch einen link für dich, bin gerade aber mobil on).
Ich poste später mal meinen Code.

Okay, werde ich gleich mal nachschlagen - bis dato habe ich immer nur von der app engine gehört (bei mir ist das Wort "engine" immer mit "ich klick mich ans ziel" konnotiert)
 
ui_3k1

ui_3k1

Gesperrt
Hallo,
das Problem hat sich praktisch von alleine erledigt :D Ich habe mir wohl zu große Gedanken über moegliche Ungenauigkeiten gemacht...
Die Schussrichtung steuere ich nun ueber die Sprites. Diese werden hinsichtlich ihrer Rotation vom Spieler über die Neigung des Geräts gesteuert - SensorEventListener.
Dementsprechend habe ich auch nur zwei weitere Variablen, die das andere Gerät erkennen muss, nämlich einen Rotationswert je Spieler.

So weit so gut. Als nächstes kommt die "Map" dran. Hier schwebt mir ein Zufallsgenerator vor, der die Maps erschafft.
Allerdings habe ich dann ja wieder genau das Problem, dass das andere Gerät die gleiche Map braucht. Hmm...
 
Linux4ever

Linux4ever

Fortgeschrittenes Mitglied
Zu den Maps: Mit einem zufälligen Seed, den der Partner dann auch bekommt? Der Map-Algorithmus muss halt immer die gleiche Map für den gleichen Seed zurückliefern.
 
ui_3k1

ui_3k1

Gesperrt
Jo so habe ich mir das auch gedacht. Habe mir schon eine recht einfache Lösung überlegt.
1. die beiden SpielerIDs in einen Hash umwandlen
2. den größeren Hash mit dem kleineren subtrahieren (dieses Ergebnis ist auf beiden Geräten gleich und bei jeder neuen Raumerstellung neu)
3. mit der Differenz lade ich dann eine bestimmte Karte. (man kann ja erst mal 10 Karten anbieten und dann einfach nur die letzte Ziffer der Differenz in die "Auswahl" einfließen lassen)

Da ich Schritte 1 & 2 sowieso schon mache (um die Spieler eindeutig zuordnen zu können) ist diese neue "Funktionalität" wahrscheinlich in wenigen Minuten implementiert.

Allerdings bin ich immer noch etwas unzufrieden mit der grafischen Darstellung.
Bei größeren Unterschieden (Größe und Auflösung) der beiden Displays kommt es auf dem Gerät mit der höheren Auflösung zu Grafikfehlern. Da das kleine Gerät alles kleiner darstellt lässt es relativ gesehen auch eine größere Nähe zu Hindernissen (Blöcke, andere Sprites usw) zu.
Somit refresht dann das Gerät mit dem kleineren Display das größere mit Positionsdaten, die das Gerät mit dem größeren Display nicht anzeigen kann (es kommt zu einem "Flattern" - sieht ein bisschen aus wie ein Echo, wobei es definitiv nicht von der Übertragung als solche kommt, der reine Payload zwischen den Geräten ist regelrecht perfekt - nur die "Entgegennahme" und die "Darstellung" ist fehlerhaft). Bei Schüssen ist es ebenfalls bemerkbar.

Ich denke es führt fast kein Weg um openGL herum.
 
Zuletzt bearbeitet:
DagobertDokate

DagobertDokate

Experte
1. die beiden SpielerIDs in einen Hash umwandlen
2. den größeren Hash mit dem kleineren subtrahieren (dieses Ergebnis ist auf beiden Geräten gleich und bei jeder neuen Raumerstellung neu)
3. mit der Differenz lade ich dann eine bestimmte Karte. (man kann ja erst mal 10 Karten anbieten und dann einfach nur die letzte Ziffer der Differenz in die "Auswahl" einfließen lassen)
DOOOOOOOOOOOOOOOOOOOOF :p

Wenn ich jetzt gegen meine Freundin spielen würde, würden wir immer auf der gleichen Karte antreten :p

Nicht so doll :ohmy:

lg.
 
ui_3k1

ui_3k1

Gesperrt
DagobertDokate schrieb:
DOOOOOOOOOOOOOOOOOOOOF :p

Wenn ich jetzt gegen meine Freundin spielen würde, würden wir immer auf der gleichen Karte antreten :p

Nicht so doll :ohmy:

lg.
Nope, da bist du ganz grundlegend falsch informiert. Aber schön, dass du genau liest... Ich hab doch geschrieben:

"2. den größeren Hash mit dem kleineren subtrahieren (dieses Ergebnis ist auf beiden Geräten gleich und bei jeder neuen Raumerstellung neu)"

Mit der SpielerID ist nicht die statische Google PlusID gemeint - sondern ein variabler "alphanumerischer Tag", der bei JEDER Raumerstellung neu generiert wird.

Hehe, man muesste schon mit dem Kammersack gepudert sein, wenn man so viele Variablen anlegt und Vergleiche fährt, um dann im Nachhinein zu merken, dass etwas "unstimmig" ist, da hast du recht. :thumbsup:
Aber die Sache ist schon durchdacht. :flapper:

OpenGL ist ein Hammer :scared: seit Tagen lese ich jetzt nach, um mir Infos zu beschaffen, welche Funktionen sich ändern, bzw. wo sich das Spiel (hinsichtlich der Loop, Game-States, Kollisionsabfragen etc) generell ändert und habe zwar einen Überblick über die Methoden - aber noch nicht im Geringsten über das "WIE man ein Spiel vom Canvas auf OpenGL umstellt"...
Wenn jemand etwas weiß, bitte sagen :rolleyes2:
 
DagobertDokate

DagobertDokate

Experte
Mit der SpielerID ist nicht die statische Google PlusID gemeint
Ahhhh wenn die ID natürlich keine ID ist macht das dann Sinn :D

lg.
 
ui_3k1

ui_3k1

Gesperrt
So kann man das auch wieder nicht sagen, bei Google laeuft die Bezeichnung unter dem Namen "participantID", aber ich weiß was du meinst, dieser Name ist reichlich schlecht gewählt. Sinnvoller wäre wahrscheinlich "temporärer Spieleridentifikator" o.ä... ich habe am Anfang auch erst mal einige fehlerhafte Connections aufgebaut, da ich davon ausging es handle sich dabei um eine fixe Größe.. Trotzdem bin ich insgesamt von den PlayServices mehr als ueberzeugt, lässt sich sehr sinnvoll integrieren und vor allem problemlos testen, kein Vergleich zu den in app billings.

Der ursprüngliche Beitrag von 17:20 Uhr wurde um 17:23 Uhr ergänzt:

Wobei.. wenn man annimmt dass participant der Teilnehmer in einer Runde ist, dann macht die Namesgebung doch schon Sinn :)
 
DagobertDokate

DagobertDokate

Experte
Dann kannst es mir ja demnächst bei bringen :D Da wollte ich mal nach der BA im Oktober rein gucken^^

lg.
 
ui_3k1

ui_3k1

Gesperrt
Jo, mache ich gerne.

Ein paar allgemeine Tipps:
Gut überlegen, was welches Gerät an Informationen vom anderen Gerät braucht und wie mehrere Geräte mit der gleichen Logik (beide haben ja die gleiche App) zu eindeutigen Zuständen kommen.
Das klingt erstmal ganz logisch und auch nicht besonders schwierig, aber trotzdem habe ich mir ziemlich oft "arrggg wasn Brainfuck" gedacht.
Gerade wenn es darum geht die Steuerung zu splitten, sollte man erst eine (möglichst) vollständige Lösung skizzieren und dann anfangen zu coden. Hatte ein paar mal einen Gedanken nicht 100%tig zu ende gedacht und musste dann umstrukturieren.