UDP austausch

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

 

MisterKnister

Betreff: UDP austausch

BeitragSo, Dez 27, 2009 21:59
Antworten mit Zitat
Benutzer-Profile anzeigen
halli halli,

seit einigen tagen arbeite ich an einem egoshooter, den man bisher aber nur auf einem PC spielen kann und weil der 2. spieler die kamera immer mit der tastatur steuern muss, was ziemlich schrierig ist und ich zu faul bin, um eine KI zu machen Razz habe ich mich entschieden, einfach eine netzwerkunterstützung einzubauen

dazu habe ich die folgenden codes geschrieben (nur als beispiel für ein netzwerk)

server

Code: [AUSKLAPPEN]
 
Repeat
  Flip:WaitTimer tmr:Cls
  If KeyDown(205) Then x1 = x1+1
  If KeyDown(203) Then x1 = x1-1
  If KeyDown(208) Then y1 = y1+1
  If KeyDown(200) Then y1 = y1-1





   IP_rd = RecvUDPMsg(udp_getkeys)
   clientkeyhit1 = ReadByte(udp_getkeys)
   clientkeyhit2 = ReadByte(udp_getkeys)
   clientkeyhit3 = ReadByte(udp_getkeys)
   clientkeyhit4 = ReadByte(udp_getkeys)
   If clientkeyhit1 Then x2 = x2+1
   If clientkeyhit2 Then x2 = x2-1
   If clientkeyhit3 Then y2 = y2+1
   If clientkeyhit4 Then y2 = y2-1




  sendcounter = sendcounter-1
  If sendcounter = 0 Then
   WriteLine(udp_sendinfos, x1)
   WriteLine(udp_sendinfos, y1)
   WriteLine(udp_sendinfos, x2)
   WriteLine(udp_sendinfos, y2)
   SendUDPMsg udp_sendinfos, andereip, dest_port
   sendcounter = 5
  EndIf





  Color 255, 0, 0:Rect x1, y1, 10, 10
  Color 0, 255, 0:Rect x2, y2, 10, 10
  If KeyHit(1) Then End
 Forever




client
Code: [AUSKLAPPEN]

 Repeat
  Flip:WaitTimer tmr:Cls

  If KeyDown(205) Then
   WriteByte(udp_sendkeys, 1)
;   x2 = x2+1
  Else
   WriteByte(udp_sendkeys, 0)
  EndIf
  If KeyDown(203) Then
   WriteByte(udp_sendkeys, 1)
;   x2 = x2-1
  Else
   WriteByte(udp_sendkeys, 0)
  EndIf
  If KeyDown(208) Then
   WriteByte(udp_sendkeys, 1)
;   y2 = y2+1
  Else
   WriteByte(udp_sendkeys, 0)
  EndIf
  If KeyDown(200) Then
   WriteByte(udp_sendkeys, 1)
;   y2 = y2-1
  Else
   WriteByte(udp_sendkeys, 0)
  EndIf
  SendUDPMsg udp_sendkeys, andereip, dest_port




  sendcounter = sendcounter-1
  If sendcounter = 0 Then
   IP_rd = RecvUDPMsg(udp_getinfos)
   x1 = ReadLine(udp_getinfos)
   y1 = ReadLine(udp_getinfos)
   x2 = ReadLine(udp_getinfos)
   y2 = ReadLine(udp_getinfos)
   sendcounter = 5
  EndIf

  Color 255, 0, 0:Rect x1, y1, 10, 10
  Color 0, 255, 0:Rect x2, y2, 10, 10

  If KeyHit(1) Then End
 Forever





wie ihr seht sendet der client nur die tastendrücke, die dann vom server aufgenommen und verwertet werden, was auch bis auf eine kleine verzögerung ganz gut funktioniert.
das habe ich so gemacht, weil ich mir dachte, dass das spiel dann auch auf allen rewchnern parallel läuft

da ich aber noch gar keine erfahrung mit netzwerken habe frage ich hier um rat vielleicht gibt es ja auch bessere möglichkeiten für sowas...

Nicdel

BeitragSo, Dez 27, 2009 22:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich würde nicht die Tastendrücke senden, sondern einfach die neuen Koordinaten. Das ist viel einfacher.
Desktop: Intel Pentium 4 2650 Mhz, 2 GB RAM, ATI Radeon HD 3850 512 MB, Windows XP
Notebook: Intel Core i7 720 QM 1.6 Ghz, 4 GB DDR3 RAM, nVidia 230M GT, Windows 7

TimBo

BeitragSo, Dez 27, 2009 22:08
Antworten mit Zitat
Benutzer-Profile anzeigen
also du arbeitest mit UDP da ist es (nicht wie bei TCP) Masse = Klasse

mein Vorschlag:
Sende alle 10 msc. deine Positionen (die Koordinaten deines Spielers) als Integer.
Der Server muss diese natürlich auslesen und weitersenden.


Dann wären die Verzögerungen schonmal gebannt.

Um mehr Ordnung zu schaffen gibst du jedem Paket eine ID. Dann gibst du den Koordinaten die ID 1 die rotationen die 2 usw.

dann sieht das z.b. so aus
Code: [AUSKLAPPEN]
WriteByte UDPStream, 1
WriteByte UDPStream, x (als integer)
writebyte udpStream, y (als integer)

auslesen tust du das dann so
Code: [AUSKLAPPEN]
while recvudpmsg(stream)
  select readbyte(udpstream)
    case 1
      x = ReadInt(Stream)
      y = ReadInt(Stream)

    case 2
      ;es wurde die rotation verschickt
   
    case 3
      ;es wurde i was anderes geschickt
  end select

wend


so solltest du den Empfang und den Versand schön unter einem Hut bekommen.

Edit:
Zitat:
Ich würde nicht die Tastendrücke senden, sondern einfach die neuen Koordinaten. Das ist viel einfacher.

lieber andauernd deine Position senden , als nur die NEUEN Kordinaten.
Denn gerade bei UDP können Pakete verloren gehen und da ist es viel sinnvoller die Koordinaten kontinuierlich zu senden ;D
mfg Tim Borowski // CPU: Ryzen 2700x GPU: Nvidia RTX 2070 OC (Gigabyte) Ram: 16GB DDR4 @ 3000MHz OS: Windows 10
Stolzer Gewinner des BCC 25 & BCC 31
hat einen ersten Preis in der 1. Runde beim BWInf 2010/2011 & 2011/12 mit BlitzBasic erreicht.
 

MisterKnister

BeitragSo, Dez 27, 2009 22:34
Antworten mit Zitat
Benutzer-Profile anzeigen
ok das hab ich verstanden, dann mach ich das also so, dass ich immer eine zahl am anfang mitsende und wenn zb spieler 2 maustaste 1 drückt also schießt dann schreibe ich

Code: [AUSKLAPPEN]

WriteByte UDPStream, 3


von welchem spieler das kommt sieht der ja aufgrund der ip oder?
aber im moment ist sowieso nur ein 2 spieler spiel geplant Very Happy


aber was meint ihr mit koordinaten und positionen? weil für mich ist das dasselbe und der muss das ja auch alles wieder zurückschicken, da das ja auf allen rechnern parallel laufen soll und wenn dann mal nichts ankommt dann ist der ja auf allen rechnern die position 0 und das wäre ja schon ein großer bug...
deswegen das mit den tastendrücken


ich habe mir das nämlich so vorgestellt, dass ALLE daten zum server gesendet werden, da werden die dann aktualisiert und alles wird berechnet und dann werden die daten wieder an alle spieler geschickt
dh. die computer von den teilnehmern tun eig nichts anderes, als die figuren an die richtigen positionen zu setzten und die lebenspunkte oder so darzustellen
 

BIG BUG

BeitragMo, Dez 28, 2009 3:09
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn keine Nachricht ankommt dann wird auch nicht neu positioniert, Dein Fall mit der Position 0 tritt also nicht auf.

Einfach die gedrückten Tasten zu übertragen ist nicht ausreichend, da durch die Verzögerung bei der Übertragung das Spiel sehr schnell unsynchron wird, also die Positionen der Spieler auf jedem Computer anders sind.
Deswegen muss auch die XYZ-Position sowie die Sichtrichtung jedes Spielers übertragen werden. Die gedrückten Tasten und ggf. die Bewegungsrichtung und -geschwindingkeit solltest Du außerdem übertragen, damit die Bewegungen bei allen flüssig sind.

Diese Informationen dann einfach z.B. alle 100 ms an die anderen Computer senden...
B3D-Exporter für Cinema4D!(V1.4)
MD2-Exporter für Cinema4D!(final)

TimBo

BeitragMo, Dez 28, 2009 12:05
Antworten mit Zitat
Benutzer-Profile anzeigen
bei UDP können Pakete die du sendest verloren gehen.
Und wenn z.b. 3 mal nach vorne verloren geht , dann ist das einfach nur doof.

Dann denkt der Server der Spieler würde stehen, dabei bewegt er sich beim Client.

Also immer schön den Server mit deinen Positionen vollnerven. Wink

------

Wegen des Spielermanagemants:
speicher auf dem Server alle Spieler als Types, welche die IP den Port und sonstige Dinge wie x, y, (z), sichtrichtung etc. speichern.

Wenn du nun eine 1 empfängst suchst du erstmal in den Types, welcher Spieler dir da die 1 geschickt hat. (einfach die IPs und die Ports vergleichen wenn beide übereinstimmen, dann hast du den Gamer gefunden). Dann kannst du ja die neue Koordinaten in den Typ reinspeichern.

Am Ende der Mainschleife oder nach einem bestimmten Zeitintervall von 2-5 mscs :
kannst du dann allen Types (Gamern) die Position und rotation von allen Gamern sendnen.
Aber Gamer 2 solltest du nicht die koordinaten von gamer 2 schicken. Smile

Ich hoffe du hast das halbwegs verstanden.
mfg Tim Borowski // CPU: Ryzen 2700x GPU: Nvidia RTX 2070 OC (Gigabyte) Ram: 16GB DDR4 @ 3000MHz OS: Windows 10
Stolzer Gewinner des BCC 25 & BCC 31
hat einen ersten Preis in der 1. Runde beim BWInf 2010/2011 & 2011/12 mit BlitzBasic erreicht.
 

MisterKnister

BeitragMo, Dez 28, 2009 22:26
Antworten mit Zitat
Benutzer-Profile anzeigen
also ersteinmal danke für all die antworten,

ich denke, das hab ich verstanden und das mit der synchronisation ist mir jetzt auch klar Very Happy
das mit den spielern als types und mit der ip in ein field hatte ich eh vor, brauchte ich aber noch nicht, da ich ersteinmal nur 2 spieler hereinlassen wollte ^^
was ich aber nicht verstanden hatte war, wann man sowas sendet (BIG BUG schrieb, nach 100 ms, TimBo nach 10) wobei ich mir da aber denke, probieren geht über studieren Very Happy und, was der unterschied zwichen koordinaten und positonen ist Razz aber ich denke, damit war nur gemeint, dass der server die daten bekommt und nicht mehr an den spieler leitet, von dem er sie bekommen hat ?! und dann sollte ja auch alles synchron laufen

dann werd ch mal sehen, wie ich das in die tat umsetze aber ich denke, jetzt krieg ich das hin

danke noch mal an alle, die geantwortet haben Very Happy

TimBo

BeitragMo, Dez 28, 2009 22:31
Antworten mit Zitat
Benutzer-Profile anzeigen
es gibt keinen Unterschied zwischen Position und Koordinaten Wink

aber im Prinzip hast du es ja schon verstanden ^^

und auch bei den 10 oder 100msc geht es , wie du schon gesagt hast , nur nach Gefühl.
Wenn du der Meinung bist, es läuft schon bei 100 msc. flüssig ,dann belässt du es bei den 100. Kannst aber natürlich auch runtergehen.

Worauf es ankommt ist , dass du es immer sendest , in Pakete einteilst und dem Gamer (einem Type) zuordnest Very Happy

Viel Glück noch weiterhin
TimBo
mfg Tim Borowski // CPU: Ryzen 2700x GPU: Nvidia RTX 2070 OC (Gigabyte) Ram: 16GB DDR4 @ 3000MHz OS: Windows 10
Stolzer Gewinner des BCC 25 & BCC 31
hat einen ersten Preis in der 1. Runde beim BWInf 2010/2011 & 2011/12 mit BlitzBasic erreicht.

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group