Seite 2 von 7

Verfasst: 12.02.2007 21:20
von Pandorra
jo, das wird das schwierigere werden.
Aber für Animationen meiner Figuren (bsp. Hausbau etc.) werde ich alles Variablen benutzen die jeder einprogrammiert hat( für den Anfang(darum auch langsmmer)).

Code: Alles auswählen


ReceiveNetworkData(ClientID, Buffer, 30)
Spieler22BauHaus = Val(PeekS(Buffer)) 

ReceiveNetworkData(ClientID, Buffer, 30)
SpielerBauHausx = Val(PeekS(Buffer)) 

ReceiveNetworkData(ClientID, Buffer, 30)
SpielerBauHausy = Val(PeekS(Buffer)) 

If Spieler22BauHaus
DisplaySprite(0, SpielerBausHausx, SpielerBauHausy)
EndIf
So ungefähr werde ich das wohl machen bis ich mehr wissen über Programmieren besitze.( Es wird wohl sehr aufwendig)
Wenn ich etwas falsch mache korrigiert mich, bin ja dazu da um zu lernen :)

Danke PMV

Verfasst: 12.02.2007 22:08
von PMV
Naja, eine gute Netzwerk-Funktion ist wirklich ziemlich schwer und
aufwendig. Und eine "einfache" Möglichkeit gibt es eigentlich nicht. Daher
haben vorallem Hobby-Projekte keinen Mehrspielermodus über LAN/
Internet :wink: Dafür gibt es dem Spiel natürlich noch mal einen
besonderen reitz, da spielen mit anderen natürlich meistens viel mehr
Spaß machen als alleine spielen zu müssen.

Also das oben wird nicht klappen. Um mit den Netzwerkbefehlen arbeiten
zu können, muss man sich schon etwas mit Pointern (Zeiger) und der
Speicherverwaltung auseinander setzten. Die PB-Befehle machen es
sicher etwas einfacher, da man auch komplete Strings senden und
empfangen kann ...

Also ReceiveNetworkData( , , 30) wird bis zu 30 Byte einlesen. Wenn du
nun mit SendNetworkData() beide Werte sendest, auch wenn du
nacheinander sendest wirst du das Problem trotzdem haben, wird
ReceiveNetworkData beide Werte hintereinander in den Speicher
schreiben. Ein Float hat 4 Byte, also darfst du auch nur 4 Byte auslesen.
Es gibt für jeden Datentyp ein extra Peek() ... so das du überhaupt kein
Val() brauchst.

Senden brauchst auch keinen ganzen String, ich denke du sendest so:

Code: Alles auswählen

SendNetworkData(ClientID, @Spieler22BauHaus, 4)
SendNetworkData(ClientID, @Spieler22BauHausx, 4)
SendNetworkData(ClientID, @Spieler22BauHausy, 4)
empfangen könntest du so:

Code: Alles auswählen

ReceiveNetworkData(ClientID, Buffer, 4) 
Spieler22BauHaus = PeekL(Buffer) ;ist doch ne Long-Variable, oder?

ReceiveNetworkData(ClientID, Buffer, 4) 
SpielerBauHausx = PeekF(Buffer) 

ReceiveNetworkData(ClientID, Buffer, 4) 
SpielerBauHausy = PeekF(Buffer)
MFG PMV

Verfasst: 13.02.2007 07:18
von Scarabol
Ich sende immer in kompletten Strings mit | oder so dazwischen, dann empfange ich auf Clientseite den String mit receivenetworkdata und speicher in mit peeks() wieder in einen String da brauch ich keine Längenangabe oder sowas, aber mir ist aufgefallen das man den Speicher nach jedem Empfang mit Pokes("") leeren sollte gibt sonst komische Werte, den empfangenen String kannst du dann mit Stringfield wieder in seine einzelnen Werte zerlegen.

Verfasst: 13.02.2007 13:32
von PMV
Das ist auch eine möglichkeit, aber das birgt auch gefahren.
Wenn du zum Beispiel "String1|String2|" sendest und kurz darauf noch,
"String5|", kann im Speicher durchaus mal "String1|String2|String5|"
stehen, je nach dem. Es kann aber auch passieren, das "String1|Str" im
Speicher steht, z.b. wenn deine Leitung recht stark beansprucht wird.
Auch ein "Stri" ist denkbar. All diese Möglichkeiten musst du in deinem
Code berücksichtigen.

ReceiveNetworkData() gibt die Anzahl empfangender Bytes zurück. Diese
information sollte ausgewertet werden. Dadurch weist du, wie viel Bytes
in deinem Speicher wirklich die Information haben, die du willst. Mit

Code: Alles auswählen

String.s + PeekS(*Buffer, empfangende Bytes)
kannst du so z.b. jedes Ergebnis sauber in einen String schreiben, ohne
das etwas verloren geht. Du müsstest den Speicher auch nicht immer
wieder leeren. Diesen String kann man dann nach dem Trennzeichen
(z.b. "|") durchsuchen und dann den Inhalt parsen. StringField() wäre da
interessant.

MFG PMV

Verfasst: 13.02.2007 18:53
von Pandorra
nochmal danke PMV.
Aber ich hab nun sehr wahrscheinlich das letzte Problem mit dem versenden und einlesen von Strings über Netzwerk.
Gut der PC liest sie nun aus dem Buffer ein. Aber das Haus wird trotzdem nicht gebaut (Habe die Kordinaten Global gemacht). Irgendwie will er die nicht einlesen

Verfasst: 13.02.2007 19:02
von PMV
Also du kannst den inhalt der Variablen ja mit

Code: Alles auswählen

Debug Variable
dir anzeigen lassen. Das könntest du am besten mal mit allen Variablen
machen, um zu schauen, ob die auch wirklich korekt erhalten wurden :wink:

Lässt sich das Problem so nicht finden ... kann ich ohne Code auch nicht
weiter helfen :wink:

MFG PMV

Verfasst: 13.02.2007 19:07
von Pandorra
also du meinst wenn ich das so mache müsste er die Variable auch gleich schon ersetzen? Also wenn ich ein Hausbau hab ich ja in Global Kordinaten eingespeichert diese müsste sich dann ändern wenn sich Figuren bewegen und das klappt nicht. Werd mir mal das im Debug anzeigen lassen.


Edit:

Server

Code: Alles auswählen

Global Spieler1x.f, Spieler1z.f
Spieler1x = 300
Spieler1y = 300


Global Spieler2x.f, Spieler2z.f
Spieler2x = 600
Spieler2y = 600

    If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
EndIf

Port = 6832
Buffer = AllocateMemory(10000)

If CreateNetworkServer(0, Port, #PB_Network_TCP)

    
Repeat

    Server = NetworkServerEvent()
  
    If Server
    
      ClientID = EventClient()
      
  
      Select Server
        
        Case 2
        ReceiveNetworkData(ClientID, Buffer, 4)
        Spieler2x = PeekF(Buffer)
        
        
        ReceiveNetworkData(ClientID, Buffer, 4)
        Spieler2z = PeekF(Buffer) 
        
        Case 4
       StartDrawing(ScreenOutput())
       DrawText(100,100,Profil + "has closed the conection ", RGB(154, 223, 116), RGB(0, 0, 0))
       StopDrawing()
       Delay (1000)
       Exit = 1


      EndSelect
    
    SendNetworkData(ClientID, @Spieler1x, 4)
        
        
    SendNetworkData(ClientID, @Spieler1z, 4)
        
        
    SendNetworkData(ClientID, @Spieler2x, 4)
        
        
    SendNetworkData(ClientID, @Spieler2z, 4)
    
    EndIf 

Das müsste alles sein was du brauchst für den Server.

Code: Alles auswählen

Global Spieler1x.f, Spieler1z.f
Spieler1x = 300
Spieler1y = 300


Global Spieler2x.f, Spieler2z.f
Spieler2x = 600
Spieler2y = 600

   If InitNetwork() = 0
  MessageRequester("Error", "Can't initialize the network !", 0)
  End
  EndIf


Port = 6832
Buffer = AllocateMemory(10000)

ConnectionID = OpenNetworkConnection("192.168.178.44", Port)
Client = NetworkClientEvent(ConnectionID) 

Repeat 




  If Client

  SendNetworkData(ConnectionID, @Spieler2x, 4)
  
 
  SendNetworkData(ConnectionID, @Spieler2z ,4)

    Select Client

      Case 2
      ReceiveNetworkData(ConnectionID, Buffer, 4)
      Spieler1x = PeekF(Buffer)

      Case 2
      ReceiveNetworkData(ConnectionID, Buffer, 4)
      Spieler1z = PeekF(Buffer) 
  
      Case 2
      ReceiveNetworkData(ConnectionID, Buffer, 4)
      Spieler2x = PeekF(Buffer) 

      Case 2
      ReceiveNetworkData(ConnectionID, Buffer, 4)
      Spieler2z = PeekF(Buffer)
     
    EndSelect 
  EndIf   
Den rest kann man sich ja denken.
Wenn ihrden Rest auch noch braucht schick ich ihn.

Verfasst: 14.02.2007 21:26
von Pandorra
ich hab noch eine Frage(siehe oben)
schonmal thx fürs beantworten im vorraus

Verfasst: 14.02.2007 22:54
von PMV
das sieht schon mal nicht übel aus ... aber da gibs noch Probleme:
1. Select Case

Code: Alles auswählen

Select Variable
  Case 1 
    Debug "Variable = 1"
  Case 2
    Debug "Variable = 2"
  Case 2
    Debug "dieser Text wird nie mals angezeigt"
EndSelect
Problem verstanden? :wink:

2. Wenn du bei jedem Schleifendurchlauf 4 Byte einließt, aber 16 Byte
sendest, was bedeutet das? Genau, dein Programm kommt in verzug
und hat irgend wann viel zu viel Daten ... das funktioniert nicht. Du musst
dir was überlegen, wie es besser geht. Als Tipp wäre da eine Schleife ;-)
Es ist vielleicht auch nicht nötig, das ganze bei jedem Durchlauf zu
senden, sondern vielleicht alle 50ms ... müssteste mal testen :D

3. Problem, Nur weil du in 4 Byte packeten sendest, musst du nicht
zwangsweise immer 4 Byte erhalten ... du musst den Rückgabewert von
ReceiveNetworkData() überprüfen. Der Rückgabewert ist die wirkliche
Anzahl der empfangenden Bytes. Du musst, wie schon mal geschrieben,
wenn auch nicht direkt an dich gerichtet, diesen Wert nutzen.

MFG PMV

Verfasst: 14.02.2007 23:06
von ZeHa
Das hat jetzt zwar nur indirekt mit dem Thema zu tun, aber das hier ist echt eine sehr schlechte Art, mit den Variablen herumzuhantieren:

Code: Alles auswählen

Spieler2x = 600 
Spieler2y = 600
Wenn Du für jeden Spieler eigene Variablen machst, hast Du irgendwann das totale Chaos. Bau Dir lieber eine Struktur, die kannst Du immer wieder erweitern, und das gilt dann sofort für alle Spieler. Auch der Code reduziert sich, denn so mußt Du ja alles, was Du z.B. mit Spieler1x anstellst, auch mit Spieler2x machen (und es gibt ja sicherlich auch sowas wie z.B. Spieler1energie, Spieler1leben, Spieler1geld und noch viel mehr).

Und da Du ja an einem Netzwerk-Spiel arbeitest, kann es sein, daß Du auf einmal auf die Idee kommst, statt 2 Spielern 4 oder 8 oder noch mehr Spieler zuzulassen. Dann darfst Du erstens alle Variablen zusätzlich anlegen und zweitens an allen Code-Stellen, wo Du drauf zugreifst, Zeilen etliche male kopieren. Wenn Du das allerdings über eine Struktur löst, kannst Du mit minimalstem Aufwand einen neuen Spieler in Dein Spiel einfügen.

Und übers Netzwerk läßt sich sowas auch viel leichter verschicken - einfach den Buffer übers Netz jagen und es hat sich. Ansonsten mußt Du ja jede Variable einzeln senden und dementsprechend wieder empfangen!