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

Übersicht BlitzBasic Beginners-Corner

Gehe zu Seite 1, 2, 3  Weiter

Neue Antwort erstellen

GearTechDE

ehemals 'KillerJo96'

Betreff: TCP: Problem für erstellen von Cubes für jeden Client

BeitragSo, Okt 09, 2011 10:02
Antworten mit Zitat
Benutzer-Profile anzeigen
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]

AppTitle "Teraxia - Game Server"
Graphics 480,320,32,2

Local Frametimer = CreateTimer(60)

Const Client_Joined = 1
Const Client_Left = 2
Const Client_Coords = 3
Const Client_Yaw = 4
Const Client_Msg = 5

Global ServerStream,ClientName$,Message$,Port% = 8000
Global Server = CreateTCPServer(Port%)

If Server <> 0 Then

Color 0,255,0
AppTitle "Teraxia - Game Server | Gestartet!"
Print "Der Server wurde gestartet auf Port: " + Port%
Color 255,255,255

Else

Color 255,0,0
Print "Der Server konnte nicht gestartet werden!"
Color 255,255,255
WaitKey()
End

End If


Repeat

UpdateNetwork()

WaitTimer(Frametimer)
Until KeyHit(1)

Color 255,0,0
AppTitle "Teraxia - Game Server | Wird heruntergefahren..."
Print "Der Server wird heruntergefahren..."
Color 255,255,255
Delay 2000

For C.Client=Each Client

CloseTCPStream(C\Stream)

Next

CloseTCPServer Server
End

End

Function UpdateNetwork()

ServerStream = AcceptTCPStream(Server)

If ServerStream Then

C.Client = New Client
C\Stream = ServerStream

End If

For C.Client = Each Client

If ReadAvail(C\Stream) Then

Select ReadByte(C\Stream)

Case Client_Joined

ClientName$ = ReadString(C\Stream)
WriteByte(C\Stream,Client_Joined)
WriteString(C\Stream,ClientName$)
Color 0,255,0
Print "[Game Server]:>" + ClientName$ + " hat unsere Welt betreten!"

Case Client_Left

ClientName$ = ReadString(C\Stream)
WriteByte(C\Stream,Client_Left)
WriteString(C\Stream,ClientName$)
Color 255,255,0
Print "[Game Server]:>" + ClientName$ + " hat unsere Welt verlassen!"

Case Client_Coords



Case Client_Yaw



Case Client_Msg



End Select

End If

Next

End Function

Type Client

Field Name
Field Stream

End Type


Client:

BlitzBasic: [AUSKLAPPEN]

AppTitle "Teraxia - Ein neues Abenteuer"
Include ".\include\InitClient.bb"
Graphics3D ScreenWidth,ScreenHeight,32,ScreenMode
SetBuffer BackBuffer()

Local FrameTimer = CreateTimer(60)

Global IP$ = "127.0.0.1",Port% = 8000,Name$
Global Stream = OpenTCPStream(IP$,Port%)

If Stream <> 0 Then

Name$ = Input("Dein Name:>")
Cls
Color 0,255,0
WriteByte(Stream,Name$)
Print "Willkommen " + Name$ + ", mit einem beliebigen Tastendruck kommst du in die Welt..."
WaitKey()
Cls

Repeat



RenderWorld()
UpdateWorld()

Flip
Until KeyHit(1)

FlushKeys()
Color 0,255,0
Print "Du verlässt jetzt Teraxia. Wir hoffen es hat dir Spass gemacht und sehen dich bald wieder!"
Color 255,255,255
Print "Bitte drücke jetzt eine beliebige Taste, um zu Windows zurückzukehren..."
WaitKey()
CloseTCPStream Stream
End

Else

Color 255,0,0
Print "Die Game Server von Teraxia sind momentan nicht online. Wir bitten um Verständnis."
Color 255,255,255
Print "Bitte drücke jetzt eine beliebige Taste, um zu Windows zurückzukehren..."
WaitKey()
End

End If

Type Player

Field Name$
Field Mesh
Field X
Field Y
Field Z
Field Yaw

End Type

Function UpdateNetwork()



End Function



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

BeitragSo, Okt 09, 2011 10:56
Antworten mit Zitat
Benutzer-Profile anzeigen
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]
.....
For C.Client = Each Client
If ReadAvail(C\Stream) Then
Select ReadByte(C\Stream)
Case Client_Joined
ClientName$ = ReadString(C\Stream)
For Andere.Client = Each Client
WriteByte(Andere\Stream,Client_Joined)
WriteString(Andere\Stream,ClientName$)
Next
Color 0,255,0
Print "[Game Server]:>" + ClientName$ + " hat unsere Welt betreten!"
.....


in den Client muss dann natürlich auch eine Funktion um ankommende Nachrichten anzunehmen:

BlitzBasic: [AUSKLAPPEN]
Function UpdateNetworkClient()
If ReadAvail(Stream) Then
Select ReadByte(Stream)
Case Client_Joined
ClientName$ = ReadString(C\Stream)
MitSpieler = New Player
MitSpieler\Name=ClientName
Color 0,255,0
Print "[Game client]:>" + ClientName$ + " hat unsere Welt betreten!"
.....



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

GearTechDE

ehemals 'KillerJo96'

BeitragSo, Okt 09, 2011 11:11
Antworten mit Zitat
Benutzer-Profile anzeigen
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]

AppTitle "Teraxia - Game Server"
Graphics 800,320,32,2

Local Frametimer = CreateTimer(60)

Const Client_Joined = 1
Const Client_Left = 2
Const Client_Coords = 3
Const Client_Yaw = 4
Const Client_Msg = 5

Global ServerStream,ClientName$,ClientIP$,Message$,Port% = 8000
Global Server = CreateTCPServer(Port%)

If Server <> 0 Then

Color 0,255,0
AppTitle "Teraxia - Game Server | Gestartet!"
Print "Der Server wurde gestartet auf Port: " + Port%
Color 255,255,255

Else

Color 255,0,0
Print "Der Server konnte nicht gestartet werden!"
Color 255,255,255
WaitKey()
End

End If


Repeat

UpdateNetwork()

WaitTimer(Frametimer)
Until KeyHit(1)

Color 255,0,0
AppTitle "Teraxia - Game Server | Wird heruntergefahren..."
Print "Der Server wird heruntergefahren..."
Color 255,255,255
Delay 2000

For C.Client=Each Client

CloseTCPStream(C\Stream)

Next

CloseTCPServer Server
End

End

Function UpdateNetwork()

ServerStream = AcceptTCPStream(Server)

If ServerStream Then

C.Client = New Client
C\Stream = ServerStream

End If

For C.Client = Each Client

If ReadAvail(C\Stream) Then

Select ReadByte(C\Stream)

Case Client_Joined

For Andere.Client = Each Client
WriteByte(Andere\Stream,Client_Joined)
WriteString(Andere\Stream,ClientName$)
Next
Color 0,255,0
Print "[Game Server]:>" + ClientName$ + " hat unsere Welt betreten!"

Case Client_Left



Case Client_Coords



Case Client_Yaw



Case Client_Msg



End Select

End If

Next

End Function

Type Client

Field Name
Field Stream

End Type


Client:
BlitzBasic: [AUSKLAPPEN]

AppTitle "Teraxia - Ein neues Abenteuer"
Include ".\include\InitClient.bb"
Graphics3D ScreenWidth,ScreenHeight,32,ScreenMode
SetBuffer BackBuffer()

Local FrameTimer = CreateTimer(60)

Const Client_Joined = 1
Const Client_Left = 2
Const Client_Coords = 3
Const Client_Yaw = 4
Const Client_Msg = 5

Global ClientName$
Global IP$ = "127.0.0.1",Port% = 8000,Name$
Global Stream = OpenTCPStream(IP$,Port%)

Global MyUnDottedIP = TCPStreamIP(Stream)
Global MyDottedIP$ = DottedIP$(MyUnDottedIP)

Global MainCam = CreateCamera()
PositionEntity MainCam,0,3,-5

If Stream <> 0 Then

Name$ = Input("Dein Name:>")
Cls
Color 0,255,0
WriteByte(Stream,Client_Joined)
WriteString(Stream,Name$)
WriteString(Stream,MyDottedIP$)
Print "Willkommen " + Name$ + ", mit einem beliebigen Tastendruck kommst du in die Welt..."
WaitKey()
Cls
Include ".\include\gameworld.bb"
CreatePlayer(Name$)

Repeat

UpdateNetwork()

If KeyDown(32) Then TurnEntity MainCam,0,-1.5,0
If KeyDown(30) Then TurnEntity MainCam,0,1.5,0


RenderWorld()
UpdateWorld()

Flip
WaitTimer(FrameTimer)
Until KeyHit(1)

FlushKeys()
Color 0,255,0
Print "Du verlässt jetzt Teraxia. Wir hoffen es hat dir Spass gemacht und sehen dich bald wieder!"
Color 255,255,255
Print "Bitte drücke jetzt eine beliebige Taste, um zu Windows zurückzukehren..."
WaitKey()
WriteByte(Stream,Client_Left)
WriteString(Stream,Name$)
WriteString(Stream,MyDottedIP$)
CloseTCPStream Stream
End

Else

Color 255,0,0
Print "Die Game Server von Teraxia sind momentan nicht online. Wir bitten um Verständnis."
Color 255,255,255
Print "Bitte drücke jetzt eine beliebige Taste, um zu Windows zurückzukehren..."
WaitKey()
End

End If

Type Player

Field Name$
Field Mesh
Field X
Field Y
Field Z
Field Yaw

End Type

Function UpdateNetwork()

If ReadAvail(Stream) Then

Select ReadByte(Stream)

Case Client_Joined

ClientName$ = ReadString(Stream)
MitSpieler.Player = New Player
MitSpieler\Name = ClientName$
Color 0,255,0
Print "[Game client]:>" + ClientName$ + " hat unsere Welt betreten!"

Case Client_Left



Case Client_Coords



Case Client_Yaw



Case Client_Msg



End Select

End If

End Function

Function CreatePlayer(P_Name$)

p.Player = New Player
p\Name$ = P_Name$
p\Mesh = CreateCube()
p\X = Rand(0,10)
p\Y = 0
p\Z = 0
p\Yaw = 0

End Function

Function ManagePlayer(P_Name$)



End Function
Mit freundlichen Grüßen: GearTechDE

Midimaster

BeitragSo, Okt 09, 2011 12:08
Antworten mit Zitat
Benutzer-Profile anzeigen
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
Field x,y...
End Type
...
p.Player = New 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
Field Alter , Aussehen , Haarfarbe, Ex
End Type

' deine letzte Freundin:
Alte.Girl= New Girl
Alte.Name= Gabi
Alte\Alter=21
Alte\Ex=1

'deine aktuelle:
Neue.Girl= New Girl
Neue.Name=Susi
Neue\Alter=17
Neue\Ex=0
....

For Freundinnen.Mädchen = Each Girl
If Freundinnen\Ex=0
"Ich gehe mit " + Freundinnen\Name
EndIf
Next


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

BeitragSo, Okt 09, 2011 12:11
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Okt 09, 2011 12:25
Antworten mit Zitat
Benutzer-Profile anzeigen
@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

BeitragSo, Okt 09, 2011 12:44
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Okt 09, 2011 13:04
Antworten mit Zitat
Benutzer-Profile anzeigen
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

GearTechDE

ehemals 'KillerJo96'

BeitragSo, Okt 09, 2011 16:19
Antworten mit Zitat
Benutzer-Profile anzeigen
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. Evil or Very Mad Question

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

Xeres

Moderator

BeitragSo, Okt 09, 2011 16:23
Antworten mit Zitat
Benutzer-Profile anzeigen
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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

GearTechDE

ehemals 'KillerJo96'

BeitragSo, Okt 09, 2011 16:38
Antworten mit Zitat
Benutzer-Profile anzeigen
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]

If ReadAvail(C\Client) Then

Select ReadByte(C\Client)

Case Client_Joined

ClientName$ = ReadString(C\Client) ;Name auslesen.
WriteByte(C\Client,Client_Joined)
WriteString(C\Client,ClientName$)

End Select

End If


So beim Server!!

Und so beim Client

BlitzBasic: [AUSKLAPPEN]

;Client wird gestartet
WriteByte(Stream,Client_Joined)
WriteString(Stream,Name$) ;Hier wird dann für den gerade neu erstellten Client, die nachrich an den server geschrieben
...

If ReadAvail(Stream) Then

Select ReadByte(Stream)

Case Client_Joined

ClientName$ = ReadString(Stream)
CreatePlayer(ClientName$)

End Select

End If

...

Function CreatePlayer(P_Name$)

p.Player = New Player ;p.Player sind jetzt immer die andren Clients nicht ich selber.
p\Name = P_Name$
p\Mesh = CreateCube()
p\X = 0
p\Y = 0
p\Z = 0
p\Yaw = 0

End Function


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

Xeres

Moderator

BeitragSo, Okt 09, 2011 16:49
Antworten mit Zitat
Benutzer-Profile anzeigen
In der Konstellation schickst du dem einen clienten doch nur sich selbst wieder zu: for...each benutzen und allen clienten die Join-Nachricht schicken.
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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

GearTechDE

ehemals 'KillerJo96'

BeitragSo, Okt 09, 2011 17:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Also sieht der Server jetzt so aus:

BlitzBasic: [AUSKLAPPEN]

If ReadAvail(C\Client) Then

Select ReadByte(C\Client)

Case Client_Joined

ClientName$ = ReadString(C\Client) ;Name auslesen.
For C.Client = Each Client

WriteByte(C\Client,Client_Joined)
WriteString(C\Client,ClientName$)

Next

End Select

End If


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

BeitragMo, Okt 10, 2011 1:36
Antworten mit Zitat
Benutzer-Profile anzeigen
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
Select ReadByte(C\Client)
Case Client_Joined
ClientName$ = ReadString(C\Client) ;Name auslesen.
For Andere.Client = Each Client
WriteByte(Andere\Client , Client_Joined)
WriteString(Andere\Client , ClientName$)
Next
End Select
End If


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

GearTechDE

ehemals 'KillerJo96'

BeitragMo, Okt 10, 2011 14:02
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Okt 10, 2011 14:16
Antworten mit Zitat
Benutzer-Profile anzeigen
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
Select ReadByte(C\Client)
Case Client_Joined
ClientName$ = ReadString(C\Client) ;Name auslesen.
For Andere.Client = Each Client
If Andere\Client <> C\Client
WriteByte(Andere\Client , Client_Joined)
WriteString(Andere\Client , ClientName$)
EndIf
Next
End Select
End If
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe

GearTechDE

ehemals 'KillerJo96'

BeitragMo, Okt 10, 2011 14:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Und das:

BlitzBasic: [AUSKLAPPEN]

If Andere\Client <> C\Client
WriteByte(Andere\Client , Client_Joined)
WriteString(Andere\Client , ClientName$)
EndIf


... 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 Wink

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 Idea

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

BeitragMo, Okt 10, 2011 14:43
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Smile

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 Smile *nur meine 2 Cent!*

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*)

GearTechDE

ehemals 'KillerJo96'

BeitragMo, Okt 10, 2011 15:00
Antworten mit Zitat
Benutzer-Profile anzeigen
@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

Xeres

Moderator

BeitragMo, Okt 10, 2011 15:14
Antworten mit Zitat
Benutzer-Profile anzeigen
Thema Types:
Man kann Objekte direkt miteinander vergleichen:
BlitzBasic: [AUSKLAPPEN]
Type TTest
Field wert$
End Type

Function Create.TTest(w$)
Local t.TTest = New TTest
t\wert = w
Return t
End Function

Local A.TTest = Create("A")
Local B.TTest = Create("B")
Local C.TTest = Create("C")

Local T.TTest

;** Alle Objekte vom Typ TTest:
For T = Each TTest
Print(T\wert)
Next
Print("- - -")

;** Ein Spezielles Objekt:
Print("T = B")
For T = Each TTest
If T = B Then Print(T\wert)
Next
Print("- - -")

;** Alles außer einem bestimmten Objekt:
Print("T <> B")
For T = Each TTest
If T <> B Then Print(T\wert)
Next

WaitKey()


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$)
Local T.TTest
For T = Each TTest
If T\wert = w Then Return T
Next
End Function

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
T
HERE 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

Gehe zu Seite 1, 2, 3  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group