TCP: Problem für erstellen von Cubes für jeden Client
Übersicht

![]() |
GearTechDEehemals 'KillerJo96'Betreff: TCP: Problem für erstellen von Cubes für jeden Client |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo,
ich bin wie schon in anderen Threads gerade dabei, mehr oder weniger kleine Tests mit TCP zu machen. Ich mache also von Anfang an kleine Projekte, welche ich fertigstelle auch wenns lange dauert wegen meinen Verständnisses. Mein letztes Problem (Mehrere Clients) habe ich jetzt bereits durch Cound-Doku´s Hilfe gut lösen können. Dort habe ich noch einiges abgeändert und das funktioniert jetzt soweit fehlerfrei. Ich habe einen Server und einen Client. Der Server hat folgende Konstanzen. Code: [AUSKLAPPEN] Const Client_Joined = 1 ;Für wenn eine neue Instanz kommt Const Client_Left = 2 ;Für wenn eine Instanz den server verlässt Const Client_Coords = 3 ;Für koordinaten übertragung der später für jeden erstellten würfel pro client Const Client_Yaw = 4 ;für die EntityYaw des Würfels Const Client_Msg = 5 ;erstmal wird das hier nicht gebraucht. Im Server mach ich´s dann so. Code: [AUSKLAPPEN] If ReadAvail(Stream) Then Select ReadByte(Stream) Case Client_Joined Print "Client joined" Case ... Case ... End Select End If Für Client_Joined lasse ich vom Client den Variableninhalt von Name$ übertragen(da steht der name des clients drin). FÜr Client_Left lasse ich auch den Namen übertragen damit der Server weiß, welcher Name jetzt den server verlässt. So... Falls der Server die nachricht Client_Joined erhält, sendet er diese Nachricht per WriteByte(Stream, Client_Joined) an alle Clients weiter, sofern welche da sind ^^. Dann hab ich im Client bei ReadAvail - Client_Joined ne Funktion (CreatePlayer(P_Name$)) In der Funktion steht drin: Code: [AUSKLAPPEN] Function CreatePlayer(P_Name$) p.Player = New Player p\Name = Name$ p\Mesh = CreateCube p\X = 0 p\Y = 0 p\Z = 0 p\Yaw = 0 End Function Jetzt sollte doch eigentlich wenn ein Client joined das an den Server senden, und der wiederum an alle Client das EIN neuer Client dazu gekommen ist, und für diesen EINEN neuen Client bei jedem andren Client ein neuer Würfel erstellt werden. Das funktioniert aber irgendwie nicht.. Was mache ich falsch. Im Sinne habe ich einfach, das man beliebig viele Client mit würfeln erstellen kann wie in einem MMORPG die Player erstellt werden. Ich hoffe ich bin dem Thema in der richtigen Richtung am programmieren oder mache ich hier etwas komplett falsch? Außerdem möchte ich ja den Cube der am Client erstellt wird nachher per W,A,S und D steuern. Das mache ich so: Code: [AUSKLAPPEN] Function KeyControl() For p.Player = Each Player If KeyDown(17) THen MoveEntity p\Mesh,0,0,0.03 If KeyDown(31) ........... usw. next End Function Wenn ich diese Funktion dann in der Hauptschleife ständig neu aufrufe, hab ich so den verdacht das ich ALLE cubes auf einmal bewege wegen "Each Player". Wie kann ich dieses Problem beheben. Ich weiß, ich setze mir große Ziele, aber ich finde je größer das Ziel, desto länger das Projekt und nachher die Lust daran weiter zu arbeiten. Ich hoffe jemand versteht dat hier alles was ich so meine. Ich bin doch eigentlich nicht mehr so weit davon entfernt, dass ich es schaffe für jeden Client einen Cube zu erstellen, dieser Cube bei allen andren Clients auch erstellt wird und die richtigen Koordinaten immer zum richtigen Cube geschickt werden oder?? Falls ich mich hier so etwas von täusche, der möge sich bitte melden. Ich hänge jetzt noch mein derzeitigen Code an: Server: BlitzBasic: [AUSKLAPPEN]
Client: BlitzBasic: [AUSKLAPPEN]
Danke im Voraus. PS: Ich erwarte überhaupt keine fertigen Codes oder ähnliches, einfach nur ein paar Tipps oder Codeschnippsel wie ich das ganze lösen könnte. WER sich die Arbeit jedoch trotzdem machen möchte der kann das gerne tun und ein komplettes Projekt fertigstellen xD Aber ich würd mal behaupten dass ICH das gerade jetz nicht geschrieben haben. |
||
Mit freundlichen Grüßen: GearTechDE |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
du hast noch einen Denkfehler in deinem Server-Script.
Du kommunizierts ja mit mehreren Clients. In der Funktion für ankommende Nachrichten wertest Du die einzelnen Streams, die von den Clients kommen aus. Ist da etwas auf einem Stream, dann verzweigst Du in die verschiedenen Möglichkeiten, welche Art von Nachricht es sein könnte. In diesem Moment bist du nur mit dem einen Stream zu dem einen Client verbunden, von dem diese Nachricht kommt. Ist es die Nachricht Client_Joined, dann genügt es nicht sie an diesen Stream zu weiterzusenden. Von dem kam sie ja eben! Vielmehr musst du jetzt eine neue FOR/EACH-Schleife starten und dort allen Streams eine Meldung machen: BlitzBasic: [AUSKLAPPEN] ..... in den Client muss dann natürlich auch eine Funktion um ankommende Nachrichten anzunehmen: BlitzBasic: [AUSKLAPPEN] Function UpdateNetworkClient() Es genügt im weiteren Verlauf natürlich auf dem Client nicht, nur den Namen neu ankommender Nachrichten auszudrucken. Vielmehr musst du auch dort jetzt einen Mitspieler-TYPE schaffen, der sich Name, Koordinaten, etc von den anderen Teilnehmern merken kann. Im Prinzip pro neues Mitglied eine neuer PLAYER-TYPE. Ebenso kannst Du z.b die Koordinaten-Nachrichten später nicht ohne Mitsenden eines Namens versenden. Bei den Clients müssen diese Daten ja einem best. Mitspieler zugeordnet werden können. |
||
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe |
![]() |
GearTechDEehemals 'KillerJo96' |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hmm, das verstehe ich nicht so ganz.
Ich habe doch im Client einen Type Player mit Name Koordinaten etc. Muss ich da jetzt noch einen Type machen? Ich verliere langsam total den Faden xD... So hab ich das jetzt: Server: BlitzBasic: [AUSKLAPPEN]
Client: BlitzBasic: [AUSKLAPPEN]
|
||
Mit freundlichen Grüßen: GearTechDE |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
soweit sieht der code ganz gut aus...
leider hast du jetzt ja nicht geschrieben, ob die Nachricht von einem neuen Spieler schon bis zu den anderen Clients vordringt... Ja, in jedem Client gibt es einen Player-Type für den eigentlichen Hauptspieler und je einen Player-Type für die teilnehmenden Clients. Einen neuen "Type" musst du dafür nicht machen. Es genügt den Player-Type mehrfach zu verwenden. Man nennt das, was da dazu kommt dann eigentlich ein "Objekt" oder eine "Instanz" BlitzBasic: [AUSKLAPPEN] Type Player "Player" ist ein TYPE. Den gibt es nur einmal im Spiel. Er wird zwischen den Befehlen "TYPE" und "END TYPE" definiert. "p" is ein "Objekt von Type Player". Davon kannst du soviele anlegen wie du willst. Es sind gewissermaßen Individuen (Lebewesen), die so aussehen wie Player Beispiel aus dem realen Leben: BlitzBasic: [AUSKLAPPEN] Type GIRL doch zurück zum Thema.... Schließlich willst Du ja auch auf jedem Rechner die Cubes der anderen Mitspieler anzeigen. Also muss jeder Rechner pro Client ein eigenes Objekt (vom Player-Type) haben. Dort steht dann immer die aktuelle Situation drin, wo sich dieser Mitspieler gerade in seinem Rechner befindet. Den Austausch der Mitteilungen übernimmt der Server. Dort senden die Clients Nachrichten hin. Und der Server verteilt sie weiter an ALLE anderen Clients. So weiß jeder alles von jedem. |
||
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe |
![]() |
count-doku |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo,
ich glaube Midimaster meint, dass du beim Client noch eine unterscheidung zwischen dem eigenen (steuerbar) und den anderen brauchst. Und im Server musst du halt noch in den Client type die Position einfügen. Dann musst du die Positionen jeweils aktualisieren etc. ich glaube aber nicht, dass so ein flüssiges Netzwerkspiel mit BB TCP möglich ist, weil eine Nachricht halt zu langsam ist. Optimal ist bei BB Multiplayerspielen eigentlich TCP für den Login / Chat und wichtige Sachen. UDP halt für Bewegung, Ping sonstwas, was so oft gesendet wird, dass wenn mal ein Paket nicht ankommt trotzdem alles normal weiterläuft lg, count-doku |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
@countdoku
Hilf mir bitte mal, ich habe da gar keine Zeit-Vorstellung! Welche Verzögerungszeiten sind denn zu erwarten bei UPD bzw. TCP? Sagen wir mal ich sende einen String in einem lokalen Netzwerk vom Client zum Server und der versucht so schnell wie es geht durch Zurücksenden zu antworten. Wann etwa habe ich dann die Antwort im Client? |
||
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe |
![]() |
Eingeproggt |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mal ganz grob gesagt braucht TCP so lange wie man es vom Internet-Surfen gewohnt ist. (eine Seite aufzurufen)
UDP geht, wenn grad nix dazwischen kommt so schnell dass man sich als Einsteiger in den Netzwerk-kram darüber keine Gedanken machen muss. Wobei es im LAN natürlich bei beiden flott geht, Probleme entstehen bei TCP dann nur übers Internet. mfG, Christoph. |
||
Gewinner des BCC 18, 33 und 65 sowie MiniBCC 9 |
![]() |
count-doku |
![]() Antworten mit Zitat ![]() |
---|---|---|
Midimaster,
bei einem simplen String lokal: TCP: ~60ms (also 30 hin, 30 zurück) UDP: ~23ms (also 11 hin, 12 zurück) Übers Internet steigen die Werte bei TCP ziemlich schnell, bei UDP kaum. D.h. solange er sein Spiel nur für LANs schreibt geht alles gut. (Ausser vllt. dass sein Programm für die Sendezeit angehalten wird) lg, count-doku |
||
![]() |
GearTechDEehemals 'KillerJo96' |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hmm, okey...
Das ich den Type mehrmals verwenden kann hab ich mir schon gedacht wegen z.B. p.Player oder ps.Player .. man kann ja verschiedene so zu sagen Variablen dafür nehmen. Nur leider schaff ich´s immer noch nich, für jeden Client der joined nen Cube zu erstellen. Ich raff nicht wieso, ich finde den Fehler einfach nicht. ![]() ![]() Aber mir ist noch dazwischen gekommen: Wenn ich doch vom Client jetzt ne nachricht schreibe, kommt die dann nur beim Server oder auch bei allen andren Clients an, weil das ja sonst schwachsinn wäre, die sachen alle an nen server zu senden und der dann alle zurück an die andren clients obwohl sie´s schon bekomn haben. Das wäre ja dann alles doppelt gemoppelt. Das versteh ich noch nich so ganz. |
||
Mit freundlichen Grüßen: GearTechDE |
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Clienten bekommen ihre Infos vom Server - darum gibt es auch Probleme mit deinen würfeln: Du musst dem Clienten schon eine Nachricht schicken, das die anderen Clienten grad Würfel erstellt haben.
Woher sollten die sonst davon wissen? |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
GearTechDEehemals 'KillerJo96' |
![]() Antworten mit Zitat ![]() |
---|---|---|
Zitat: Woher sollten die sonst davon wissen?
Keine Ahnung ^^ @Topic So.. ich mach den Netzwerk Kram jetzt nochmal von Vorne, was ja bis jetzt nich wirklich viel ist, damit ich da nochmal ein wenig Licht in die Sache bringe. Beachten muss ich jetzt folgendes: Ich mach das hier mal vor: Server: BlitzBasic: [AUSKLAPPEN]
So beim Server!! Und so beim Client BlitzBasic: [AUSKLAPPEN]
Wenn ich jetzt den Server + 2 Clients hintereinander starte, sollten doch bei dem ersten Client 2 Cubes da sein. Sind sie aber nicht. Warum nicht? Was fehlt hier denn noch?? |
||
Mit freundlichen Grüßen: GearTechDE |
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
In der Konstellation schickst du dem einen clienten doch nur sich selbst wieder zu: for![]() ![]() Und dann nicht vergessen, das die würfel am Nullpunkt ineinander stehen. |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
GearTechDEehemals 'KillerJo96' |
![]() Antworten mit Zitat ![]() |
---|---|---|
Also sieht der Server jetzt so aus:
BlitzBasic: [AUSKLAPPEN]
Und beim Client in der Funktion ändere ich den X wert von standart auf Rand(0,10) so dürfte es der würfel nich immer an der selben stelle stehn. SO richtig? |
||
Mit freundlichen Grüßen: GearTechDE |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wieso verwendest Du nicht die Variablennamen so wie ich es in meinem Beispiel von heute morgen gezeigt habe?
die äußere FOR/NEXT läuft mit dem Objekt c.Client die innere FOR/NEXT mit den Objekt Andere.Client Zwei verschiedene Aufgaben erhalten zwei verschiedene lokale Objektvariablen In dem Moment eines Erst-Datenempfang von einem bestimmten Clienten erstellt du doch erstmals das Objekt C.CLient. Kommunikation mit diesem Clienten könnte nun über den dazugehörenden Stream c\Stream ablaufen. Aber eben nur Kommunikation mit diesem Clienten! Die Kommunikation mit den anderen (vorher bereits gemeldeten) Clienten muss über ein anderes Objekt und über den dazugehörenden anderen Strream ablaufen. Wir nennen ihn einfach mal Andere.Client bzw. Andere\Stream. Du musst dir das so vorstellen: Jedes Mal, wenn du ein neues Objekt erstellst, wandert es in eine Liste. Hast du z.b. 5 Objekte erstellt, weil sich bereits 5 Clienten gemeldet haben, dann sind in dieser Liste alle 5 Objekte. Und jetzt wird's kompliziert: Die einzelnen Elemente dieser Liste kannst Du nun in einer FOR/NEXT-Schleife unter völlig beliebigen Namen ansprechen. Das ist so bei Objektlisten. Deshalb verwenden wir mal den Namen Andere Server: BlitzBasic: [AUSKLAPPEN] If ReadAvail(C\Client) Then Kommt nun eine solche Nachricht bei einem der anderen Clienten an, so kannst Du zwar die CreatePlayer()-Funktion zum Erstellen eines Objektes und des Cubes verwenden. Die Koordinaten dürfen aber nicht RAND() gesetzt werden, sondern sollten eigentlich als weitere Nachricht vom Neu-Clienten zunächst an den Server, und von dort an alle anderen Clienten gesendet werden. Schließlich soll ja der Würfel eines Teilnehmers bei allen anderen Teilnehmern auch an der richtigen Stelle stehen. |
||
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe |
![]() |
GearTechDEehemals 'KillerJo96' |
![]() Antworten mit Zitat ![]() |
---|---|---|
Okey, danke Midimaster, ich hatte vorher irgendwie das Problem mit einem MAV bei der ersten For-Next Schleife. Warum? Keine Ahnung aber jetzt funktioniert es denk ich mal. Jetzt ist dort, wenn ich einen Client starte, ein Würfel. Den Würfel erstelle ich ja mit nem Type: IN diesem Fall p.Player = New Player.
Muss ich jetzt für mich noch einen andren Objekt erstellen? z.B. so: MyP.Player = New Player ??? Aber dann wären doch immer 2 Cubes pro Client da.. Das ist doch irgendwie falsch. |
||
Mit freundlichen Grüßen: GearTechDE |
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
tja, jetzt musst du entweder erreichen, dass der Sever eine Nachricht von dir nicht auch an Dich sendet, oder du musst erreichen, dass der Client merkt, dass eine Nachricht, die er erhält eigentlich von ihm war.
Ich würde das erste machen: BlitzBasic: [AUSKLAPPEN] If ReadAvail(C\Client) Then |
||
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe |
![]() |
GearTechDEehemals 'KillerJo96' |
![]() Antworten mit Zitat ![]() |
---|---|---|
Und das:
BlitzBasic: [AUSKLAPPEN]
... verhindert, dass er es an den selben Client sendet? Man das ist wirklich kompliziert. Wow, also das funktioniert so weit. Also das will ich doch gleich mal in meine Script Datenbank schreiben ![]() Hmm. Also jetzt erstelle ich für den Type ein andres Objekt, welches ich dann selber steure. Ich denke für die ersten 2 Minuten werde ich noch klar kommen. Ich melde mich dann gleich wieder ^^. Vielen Dank für die wirklich ausgezeichnete Hilfe Midimaster. Du bist so jemand, dem ich bestimmt irgendwie z.B. als Lehrer gut zuhören könnte. Bei dir verstehe ich meinstens auf Anhieb, wie´s geht ![]() okey, ich melde mich dann wieder. @OffTopic, Was wenn ich im selben Thread noch ne Frage gestellt habe, und diese nachher übersehen wird? Darf ich dann einen neuen Thread aufmachen? |
||
Mit freundlichen Grüßen: GearTechDE |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Du darfst soviele Threads aufmachen, wie du magst *g*
Nunja, es kommt drauf an. Dieses Forum wird nunmal für spezifische fragen genutzt, die ich auch Spezifisch beantwortet werden. Hast du nun eine neue frage, solltest du einen neuen Thread aufmachen. Allerdings nicht für jede Milchkanne, meist hilft auch ein wenig nachdenken ![]() Versetz dich einfach mal in die Lage eines anderen Nutzers: Dieser sucht nun nach einem Stichwort und findet einen anderen Thread, wo sein stichwort vorkommt. Dieser Thread enthält 5 unterschiedliche Fragen, welche alle beantwortet werden. Ich hätte keine lust, da groß rumzusuchen, da sich die Ursprungs frage / fragen aus dem ersten Post deutlich von meiner gesuchten unterscheiden. Ich würde in diesem Fall annehmen, dass das Stichwort nur kurz angerissen und nicht beantwortet wurde. Nicht grade förderlich fürs schnelle hilfe finden ![]() Wenn deine Frage sich allerdings direkt auf die vorhergegangene Bezieht (ausweitung des Problems und seiner Lösung), so solltest du sei im Selben Thread posten. Wenns dann doch mal übersehen wird, kannst du nach absprache zb auch vorhergegangene Helfer direkt per PN kontaktieren, hier beißt niemand. (aber ehrlich gesagt habe ich grade nicht die Forum's Regeln vor Augen *duck* - da stehen sicher auch diverse regelungen drin! *hust*) |
||
![]() |
GearTechDEehemals 'KillerJo96' |
![]() Antworten mit Zitat ![]() |
---|---|---|
@PhilipK Okay, danke.
@Topic Wie gesagt, ich melde mich. Also, ich habe jetzt so weiter gemacht, dass ich beim Start des Clients ein neues Objekt meines Types erstelle. Den kann ich mit meiner erstellen Funktion KeyControl() auch schön bewegen. Jetzt lasse ich jedes Mal wenn W,A,S oder D gedrückt wird den ClientNamen$ + Koordinaten + Yaw Winkel an den Server senden. Mein einziges Problem ist jetzt, und das hatte ich schon immer und war auch immer meine Frage, wie ich jetzt die richtigen Koordinaten an die richtigen Cubes kriege. Ich habe mir gerade mal ein paar Gedanken gemacht aber ich habe leider echt keinen Plan wie ich des machen soll. Edit: Ich habe im Client bei Client_Coords den Namen$ + jede Koordinate mit ReadFloat(Stream) ausgelesen. Danach rufe ich die Funktion ManagePlayer(P_Name$) auf und möchte das dort die Position + Yaw Winkel der Cubes ausgerichtet wird. EIgentlich bräuchte ich doch einfach das Type Objekt rauszusuchen, welches den Namen ... hat und dann die Position an dieses Objekt geht. Das geht aber irgendwie anders oder? Man kann ja nicht: For p.Player = PLAYERNAME Ich habe echt kp wie´s weitergeht Hoffe mir hilft jetzt zum X-ten Mal wieder jemand. Danke im Voraus |
||
Mit freundlichen Grüßen: GearTechDE |
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Thema Types:
Man kann Objekte direkt miteinander vergleichen: BlitzBasic: [AUSKLAPPEN] Type TTest Threads erstellen vs. Fragen sammeln: So viel wie nötig, so wenig wie möglich. Bei einem Themengebiet macht es schon Sinn, alle fragen (bzw. folge-fragen) an einem Ort zu haben. Und Steuerung: Du hast den Clientnamen - darüber kannst du den richtigen Clienten und damit den richtigen Würfel finden. Eigentlich sollte der Server ja den Clienten sagen, wo sie sich (tatsächlich) befinden, damit das überall gleich aussieht. Edit: Killerjo96 hat Folgendes geschrieben: Man kann ja nicht: For p.Player = PLAYERNAME
Naja, darum wäre ein Array+ID für den Direktzugriff schneller, aber erst mal kannst du es auch so machen: BlitzBasic: [AUSKLAPPEN] Function FindTest.TTest(w$) Ist bei den paar Clients die du hast sicher schnell genug. |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
- Zuletzt bearbeitet von Xeres am Mo, Okt 10, 2011 15:22, insgesamt einmal bearbeitet
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group