LAN-Spiel (Logik)

jannik

Grünschnabel
Hey,

wie einige sicherlich bereits gemerkt haben, bin ich gerade dabei, ein Spiel zu programmieren.

Der Lokale Modus (auf einem PC) ist sogut wie fertig. Jetzt kommt aber der schwere Teil, das Programmieren eines Netzwerk-Features, an dem mein Gehirn etwas zu viel zu grübeln hat,. Deswegen habe ich mal ein neues Thread eröffnet und lass euch mal ein bisschen nachdenken.

Also, in mein Spiel geht es um Schleimspuren, jeder Spieler steuert seinen "Blob" und macht Schleimspuren auf einem Bild. Das sieht ungefähr so aus:
Code:
http://img534.imageshack.us/img534/8418/bgry.png

Wie das momentan abläuft:
1. Richtung erkennen, wo Blob hinwill
2. Blob in die Richtung verschieben, wo er hinwill
3. Schleimspur zeichnen

Nun muss ich ja irgendwie übertragen, wo die gegnerischen Spieler hinfahren (ob nach oben, links, rechts, unten, wahrscheinlich am besten als Integer). Aber ich muss ja jedesmal vom Server die aktuelle Richtung der gegnerischen Blobs holen, bevor man zeichnen usw kann. Und das kann ja auch mal sein, das der eine Client schneller zeichnet als der andere Client. Wie gleiche ich das wieder aus?
Wie würdet ihr das lösen?

Ich hoffe ich habe meine Problem deutlich genug dargestellt, ich wäre wirklich froh, wenn ihr mir in irgendeiner Weise weiterhelfen könntet ;) Schlagt mir einfach mal vor, wie ihr das lösen würdet,

Danke,
Jannik
 
Hi

ist deine Blob-Geschwindigkeit von der Zeichengeschwindigkeit abhängig?
Alos bei jedem neuen Bild wird ... weitergerückt?

Das solltest du ändern. Gib dem Blob eine Geschwindigkeit in Weg pro Zeit, also zB 123 Pixel pro Sekunde
oder (jenachdem wie dein Fenster vergrößerbar etc ist) xx.xx% von der Fensterhöhe/breite...irgendwas in der Art.

Sind alle Spielerblobs gleich schnell?
Kann man auch stehenbleiben oder müssen die Blobs immer in Bewegung sein (und nur die Richtung änderbar)?
Und geht nur gerade nach oben/unten/rechts/links, also keine Schrägen?
Ich nimm einmal ja, nicht stehenbleiben, ja an.

Zur Übertragung: Am Anfang sollte der Server jedem Client mitteilen, wieviel Blobs es gibt, sowie Positionen und Richtung davon. Positionen als 2 int für x/y-Koordinate (zB in Pixel), Richtung als int (zb 1234 für r/l/o/u)
Jeder Client beginnt dann unabhängig von den anderen, alle Blobs zu zeichnen und jeden pro Zeit ein Stück weiter zu rücken.

Vom Server kommt nur dann eine Meldung, wenn ein Blob seine Richtung geändert hat.
Mit Blobnummer und neuer Richtung.
Weil es zwischen den Clients trotz Weg/Zeit-Geschwindigkeit trotzdem noch kleine Abweichungen geben kann, wird bei einem Richtungswechsel auch die aktuelle Position mmitübertragen.
Der Server muss dazu natürlich wie jeder Client mitrechnen, wo die Blobs gerade sind. Nur zeichnen muss er sie nicht.
Dann gilt also immer die Position vom Server. Falls ein Client ein paar Pixel daneben ist, kann er beim Richtungswechsel ja auch gleich die Position korrigieren.

Vom Client zum Server gesendet werden in dem Fall dann die Benutzereingaben.
Wenn du 4 Tasten für Rauf/Runter/Links/Rechts hast, schickst du bei einem Tastendruck eben eine Zahl von 1 bis 4 zum Server, damit der das für sien Mitrechnen weiß und auch an alle Clients weiterübertragen kann.

Gruß
 
Dankeschön, das hilft schonmal etwas. :)

ist deine Blob-Geschwindigkeit von der Zeichengeschwindigkeit abhängig?
Alos bei jedem neuen Bild wird ... weitergerückt?

Wie meinst du das? Ich versuche es zu erklären (Beispiel: Richtung nach unten):
1. Speichere aktuelle Uhrzeit in millesekunden
2. Ich bewege den Blob redblob (ist ein Imagepanel) nach unten auf dem Spielfeld (Ebenfalls ein Panel mit einem schwarzen Image als Hintergrund)
2. Danach zeichne ich ein Rechteck auf das Hintergrundbild des Spielfelds, als Schleimspur.
3. Thread.sleep(vordefinierte zeit, die über geschwindigkeit der blobs bestimmt minus der verbrauchten Zeit für letztere Schritte, gemessen an der gespeicherten Zeit vom ersten Punkt);
4. Loop zu punkt eins

Sind alle Spielerblobs gleich schnell?
Kann man auch stehenbleiben oder müssen die Blobs immer in Bewegung sein (und nur die Richtung änderbar)?
Und geht nur gerade nach oben/unten/rechts/links, also keine Schrägen?
Ich nimm einmal ja, nicht stehenbleiben, ja an.

Sie sind nicht immer gleichschnell, es spawnt alle zehn Sekunden ein Item, welches auch Fähigkeiten wie einfrieren und eigenen Blob schneller machen beinhält.
Nein es kann nicht stehen geblieben werden.
Man kann nur runter, hoch, rechts, links.

---

Meine Bedenken liegen klar bei der Veränderung der Richtung bzw ja auch die Veränderung der Geschwindigkeit. Und dass alle Clients nicht gleichschnell zeichnen/die Blobs bewegen evtl.. Klar kann man die Blobs bei nem Richtungswechsel anders positionieren, aber die bis dahin gemachten Schleimspuren sind ja auch ein Problem, die sind dann ja etwas verpositioniert und das Schleimspur-Bild verändert sich von Client zu Client.

Aber wie kann man das denn lösen, das ist echt schwer, ich wäre echt dankbar, wenn da irgendjemand überhaupt was findet.

Und achja, auch wenn jemand eine Lösung hat, ich weiß nicht, ob ich das auch programmiererisch umgesetzt kriege.

Ich habe noch bis zum 18.03. Zeit, ansonsten muss ich es wohl bei einem Lokalen Modus belassen, wäre zu schade :(

Edit:\\
Ich weiß nicht, wie man integer sendet und der Client sie von anderen Integern auseinanderhält, deswegen lasse ich euch erstmal gucken ;) (P.S.: Ich habe noch kein Thread.Sleep() in der Game Methode, einfach dazudenken)
 
Zuletzt bearbeitet:
1. Speichere aktuelle Uhrzeit in millesekunden
2. Ich bewege den Blob redblob (ist ein Imagepanel) nach unten auf dem Spielfeld (Ebenfalls ein Panel mit einem schwarzen Image als Hintergrund)
2. Danach zeichne ich ein Rechteck auf das Hintergrundbild des Spielfelds, als Schleimspur.
3. Thread.sleep(vordefinierte zeit, die über geschwindigkeit der blobs bestimmt minus der verbrauchten Zeit für letztere Schritte, gemessen an der gespeicherten Zeit vom ersten Punkt);
4. Loop zu punkt eins
Zum Punkt 3: Den solltest du eventuell ändern.
Du bekommst zwar einen Millisekundenwert, der aber alles andere als Millisekundengenauigkeit hat.
Abweichungen von 50 ms sind keine Seltenheit.
Auf deinem Rechner fällt das vielleicht nicht auf, wenn du aber verschiedene Rechner und vor allem verschiedene Betriebssysteme mitspielen lässt, kanns durcheinander kommen.
Ist aber vorläufig nicht zwingend notwendig, das zu ändern. Solange man auch auf anderen Rechnern als Mensch keine Verzögerungen und unregelmäßige Bildraten bemerkt....

Sie sind nicht immer gleichschnell, es spawnt alle zehn Sekunden ein Item, welches auch Fähigkeiten wie einfrieren und eigenen Blob schneller machen beinhält.
Nein es kann nicht stehen geblieben werden.
Man kann nur runter, hoch, rechts, links.
Der Server muss alles übernehmen (wo und wann Items auftauchen etc).
Es soll ja bei jedem Spieler gleich sein.

Vom Client brauchst du nach wie vor nur die Tasten senden.
zB Jeweils ein Byte mit den Werten 1 2 3 4 für r o l u.

Umgekehrt ist der Client (außer der Tastaturverwaltung) eigentlich nur noch zum Anzeigen gut.
Der Rest kann vom Server vorgegeben werden.

Die "Befehle", die der Server verschickt, könnten zB immer mit einer Nummer anfangen, welcher Befehl das ist.
Da du wohl niht mehr als 255 Anweisungen haben wirst, dürfte auch hier ein Byte reichen.
Je nach Befehlsart kommen dann eventuell noch weitere Werte mit...

Beispiel, wie ich das festlegen würde:
1: Es gibt ein neues Blob mit Nummer <int> auf Position x <int> und y <int> mit der Geschwindigkeit <int> und Richtung <int>.
2: Das Blob Nummer <int> verschwindet wieder (Wenn ein Spieler aussteigt)
3: Blob Nummer <int> hat ab jetzt die Geschwindigkeit <int>. Aktuell ist es auf Position xy <int><int>
4: Blob Nummer <int> wechselt die Richtung nach <int>. Aktuell ist es auf Position xy <int><int>
5: Ein Item (es bekommt die Nummer <int>) vom Typ <int> ist auf xy<int><int> aufgetaucht. (Typ für Verschnellern, Einfrieren etc)
6: Das Item Nummer <int> soll wieder weg

Irgendwas in der Art halt.
Die gesamte Logik, wann was passiert, übernimmt der Server.
Der Client kann nur Befehle empfangen, sich irgendwelche Blobs/Items mit ihren Nummern merken (bis er sie wieder vergessen soll) und zeichnen.

Meine Bedenken liegen klar bei der Veränderung der Richtung bzw ja auch die Veränderung der Geschwindigkeit. Und dass alle Clients nicht gleichschnell zeichnen/die Blobs bewegen evtl.. Klar kann man die Blobs bei nem Richtungswechsel anders positionieren, aber die bis dahin gemachten Schleimspuren sind ja auch ein Problem, die sind dann ja etwas verpositioniert und das Schleimspur-Bild verändert sich von Client zu Client.

Wenn die Schleimspur ein paar Pixel zu weit ist und das Blob beim Abbiegen wieder "zurückspringt", kannst du ja diese Pixel in die alte Richtung nocheinmal zeichnen - aber nicht mit Schleim, sondern mit dem Hintergrund "übermalen".

Edit:\\
Hier ist mein Projekt:
Code:
http://www.multiupload.com/NW6SZ3GBTY
Ich weiß nicht, wie man integer sendet und der Client sie von anderen Integern auseinanderhält, deswegen lasse ich euch erstmal gucken ;) (P.S.: Ich habe noch kein Thread.Sleep() in der Game Methode, einfach dazudenken)

Du kannst das auch als Zip-Datei hier reinstellen.

Gruß
 
Zum Punkt 3: Den solltest du eventuell ändern.
Du bekommst zwar einen Millisekundenwert, der aber alles andere als Millisekundengenauigkeit hat.
Abweichungen von 50 ms sind keine Seltenheit.
Auf deinem Rechner fällt das vielleicht nicht auf, wenn du aber verschiedene Rechner und vor allem verschiedene Betriebssysteme mitspielen lässt, kanns durcheinander kommen.
Ist aber vorläufig nicht zwingend notwendig, das zu ändern. Solange man auch auf anderen Rechnern als Mensch keine Verzögerungen und unregelmäßige Bildraten bemerkt....

Leider weiß ich nicht, wie man das anders lösen könnte :(
Hast du eine Alternative dazu?

Die "Befehle", die der Server verschickt, könnten zB immer mit einer Nummer anfangen, welcher Befehl das ist.
Da du wohl niht mehr als 255 Anweisungen haben wirst, dürfte auch hier ein Byte reichen.
Je nach Befehlsart kommen dann eventuell noch weitere Werte mit...

Hättest du ein Code Beispiel bzw könntest mir schnell eines machen? Also wie man z.B. dem Client, den man nun durch "client. accept()" nun hat, ein paar Daten schickt. Und wie man dieses mit dem Client-PC nun liest?

Also zum Beispiel:

Blob wandert absofort nach unten geschickt.
Befehl: 01 (Für "ändere Richtung")
Richtung: 1 (Für "unten")

Setze Blobposition nach x=753, y=578...
Befehl: 02 (Für "Position ändern"
Blobnummer: 1 (Für "rot")
X-Position: 753
Y-Position: 578

Wie setze ich das um im Code? Sendet der Server das nach und nach dann? Oder wie macht man das? Ein Code-Beispiel für das wäre echt super :)
 
Schon mal über nen Tick nachgedacht. War bei mir letztens ne bessere Methode als über ne normale Zeiteinheit zugehen.

Damit haben unterschiedliche Betriebssysteme kein Problem und das Spiel läuft wesentlich synchroner und genauer.
 
ist eig. wie ne zeitregelung bloß das zu einem tick immer eine methode ausgeführt wird.

man baut in jeden client einen tick thread ein

der ruft alle, was weiß ich vllt 20 ms. einen methoden aufruf durch, der sich vom server nen "status" holt
Der status gibt das spielfeld wieder.

Die aktionen werden jedoch immer sofort an den server geschickt. als in nem keylistener zum bleistift

der tick wird vom server aus gestartet. hab das mal für nen viergewinntspiel gemacht. da war das ganz gut.
 
Ich werde mir das mal überlegen. Aber ist mir noch nicht ganz klar bisher.
Naja ist auch egal erstmal, ich schau es mir an, sobald die Client-Server Sache überhaupt läuft, wenn auch richtig async erstmal.

Ich habe mir folgendes überlegt:

Client:
Eine Methode zum empfangen von allen Befehlen, erstmal die Richtungen der Blobs wären ganz gut als Anfang. Und eine dann noch zum Senden der Pfeiltasten eine weiter Funktion/Methode.

Server:
Eine zum empfangen der Pfeiltasten und eine zum Senden der Befehle (Blobnummer & Blobrichtungen zum Beispiel).

Könnte mir einer sagen, wie ich meinen Clients 2 Integer (bzw Byte wäre ja auch ausreichend für den Befehl) Werte sende und wie man diese empfängt dann? :) Wäre echt gut :)

Danke im Vorraus ;)
 
Zuletzt bearbeitet:
Könnte mir einer sagen, wie ich meinen Clients 2 Integer (bzw Byte wäre ja auch ausreichend für den Befehl) Werte sende und wie man diese empfängt dann? :) Wäre echt gut :)

Kennst du dich mit der Übertragung generell nicht aus oder suchst du einen Weg, ein int statt dem Bytearray zu verarbeiten?

Für zweites: Thomas Darimonts erster Beitrag (insgesamt fünfter Beitrag im Thread) hier:
http://www.tutorials.de/java/228129-konvertierung-von-integer-byte-array.html

Für erstes: Klasse Serversocket mit Bind und Accept, und die Klasse Socket mit Connect, GetInputStream und GetOutputStream.
etc etc...

Gruß
 

Neue Beiträge

Zurück