Autor Beitrag
mangaka
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42

windows xp sp2
Delphi 2005 personal
BeitragVerfasst: Di 12.09.06 12:50 
moin leute,
ich denke ihr habt schon viele threads mit solch einem titel gelesen, aber in keinem von dem habe ich was gefunden was mir weiterhelfen konnte.
ich kenne mich mit der netzwerkprogrammierung schon ein bisschen aus, habe schon ein paar chat-programme mit indy geschrieben und ein filesend-programm mit der netzwerkkomponente von delphi.
jetzt zum eigentlich problem. ich möchte ein echtzeit lan-spiel programmieren. zum einstieg dachte ich mir, dass ping-pong nicht schlecht wäre. habe schon einzelspieler halbwegs in c++ mit der sdl-libary erstellt.
mein problem besteht darin, dass ich nicht weiss wie ich mehrere informationen in einem kleinstmöglichsten datenpaket an den server schicke. man könnte auf die idee kommen ein record zu senden, jedoch soll diese lösung eine sehr schlechte sein.
das nächste problem ist, dass ich nicht weiss, wie oft ich solch ein datenpaket abschicken soll.
---
etwas theoretisches:
damit mein schläger nicht auf meinem rechner laggt, sende ich in bestimmten zeitintervallen den server meine posi(mit einem zeitstempel). der server sieht sich das nun an und überprüft , ob eine kollision stattgefunden hat. falls ja, schickt er dem client eine nachricht, dass er sich auf die position zurückbewegen soll, an dem er die nachricht abgeschickt hat(deswegen der zeitstempel). gibt es keine belehrung vom server, bewegt der schläger sich weiter.
---
also das mit der theorie könnte klappen, wenn ich oft genug ein datenpaket sende, aber ich weiss nun wirklich nicht wie oft das geschehen soll. ich will ja nicht den server zu bomben.

das wären meine ersten fragen, ich hoffe wirklich, dass ihr mir weiterhelfen könnt.
an diesem problem sitze ich nämlich schon ein paar wochen.



mfg
mangaka

ps:
sry für den langen text :)
DarkLord05
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 449

WinXP Pro SP2
Opera; Delphi 3 Pro; Delphi 2005, Turbo Delphi, dev-c++, Eclipse, MS Visual Studio .NET 2003, MS Visual C++
BeitragVerfasst: Di 12.09.06 18:23 
Also spontan würd mir einfallen "einfach" den Winkel zu nehmen indem die Kugel bewegt wird, also nur 1x abschicken wenn die Kugel auftrifft.
Als bsp.:
ausblenden Quelltext
1:
2:
3:
4:
5:
|         #|
|#     +   | 
|          |
|          |
|          |

Die Kugel wurde in einem winkel von 45° "abgestoßen" von dem "feld" des Spielers. Man könnte ja noch die Position von der Kugel mitschicken, wäre jedenfalls besser um das anzuzeigen

Dann wird der Rest interpoliert, also bei den Clients berechnet anstatt auf dem Server. So sendest du nicht viele Packete.

Is mir so spontan eingefallen, viell. hast ja was dagegen und teilst deine meinung bzw dein wissen, weil du viell. weißt warum das schlecht is :)
mangaka Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42

windows xp sp2
Delphi 2005 personal
BeitragVerfasst: Di 12.09.06 21:00 
danke,
aber mein problem beschäftigt sich nicht mit dem ball, dennoch ne gute idee(denn mit dem ball habe ich mich noch nicht beschäftigt)
um was es mir immo geht sind die beiden schläger.

wenn ich die kollision(der rest, so wie du meinst) auf den clients berechnen würde, dann könnte es passieren, dass beide verschiedene ansichten von der kollision haben. evtl meint der eine "da ist eine kollision" und der andere "du spinnst doch". deshalb möchte ich das lieber mit hilfe des servers handeln.

danke nochmals ;)
DarkLord05
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 449

WinXP Pro SP2
Opera; Delphi 3 Pro; Delphi 2005, Turbo Delphi, dev-c++, Eclipse, MS Visual Studio .NET 2003, MS Visual C++
BeitragVerfasst: Di 12.09.06 21:38 
ahh, logisch, stimmt, daran hab ich gar net gedacht, die schläger werden gar net "mitübertragen". Mhhh... kein wunder das du da solange denkst wie du das machst nicht alles sofort bzw wann zu übertragen...mmmhh...
alle X-Sec einfach die position mit übertragen viell. Also nur alle 1000 ms oder 1500 ms, müsste man testen ob das gut geht und der Server bzw das Netzwerk nicht so zugebombt wird. Spontan fällt mir sonst nix ein, viell. hab ich ja nachher nen Geistesblitz^^
mangaka Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42

windows xp sp2
Delphi 2005 personal
BeitragVerfasst: Di 12.09.06 22:46 
hehe, zumindest verstehst nun woran ich die ganze zeit sitze.
das problem nun bei einem zeitintervall von zb. 1500ms könnte sein, dass die "belehrung" vom server(wie in der theorie erwähnt) zu spät kommt und ich aufeinmal zurückgesetzt werde, obwohl ich nicht weiss warum.(verständlich?)

aber man könnte ja dem server schon öfter was schicken, jedoch müssten dafür die pakete sehr klein sein, damit die verbindung nun nicht so überlastet wird. und das mit den paketen war ja auch ne frage von mir^^


guten abend noch ;)
DarkLord05
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 449

WinXP Pro SP2
Opera; Delphi 3 Pro; Delphi 2005, Turbo Delphi, dev-c++, Eclipse, MS Visual Studio .NET 2003, MS Visual C++
BeitragVerfasst: Mi 13.09.06 18:47 
Was hälst du davon nur den gegnerschläger zu übertragen? Der wird dann bei einem nur durch den server aktualisiert. So hast du den vorteil das der Spieler machen kann was er will, er sieht bei sich vom Schläger immer das 100%ige Original. Da man so am besten spielen kann.
mangaka Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42

windows xp sp2
Delphi 2005 personal
BeitragVerfasst: Do 14.09.06 09:57 
ja also...
nach der theorie wollte ich auch nur den gegnerischen schläger übertragen. mein schläger wird nur vom server aktuallisiert, wenn eine kollision stattgefunden hat.
DarkLord05
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 449

WinXP Pro SP2
Opera; Delphi 3 Pro; Delphi 2005, Turbo Delphi, dev-c++, Eclipse, MS Visual Studio .NET 2003, MS Visual C++
BeitragVerfasst: Do 14.09.06 17:15 
^^ dann siehts so aus als ob der andre schummelt, wenn sein schläger plötzlich oben ist wo der ball ist und sein Schläger vorher unten war*g*
Ich würd da wirklich mit 1000 -> 1200 ms arbeiten und da die daten übetragen. Aber an sich kannst ja mal ne Procedur bzw Funktion schreiben die die Daten überträgt, dann rufst das "einfach" bei kollision auf und mit nem Timer nach ner bestimmten Zeit um zu gucken was so besser wäre oder ob man das mit dem Timer komplett vergessen kann (was ich aber nicht glaube ;))
mangaka Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42

windows xp sp2
Delphi 2005 personal
BeitragVerfasst: Do 14.09.06 17:49 
ein timer muss sowießo dabei sein, aber nicht solch einen standart-timer von delphi, sondern einen selbst erstellten.
und ich glaube du hast noch nicht verstanden, wie ich das mit dem gegnerischen spieler meine. hier mein beispiel:

pc[a]
-ich bin pc[a] und schicke in einem bestimmten zeitintervall meine posi an den server.
das datenpaket übersehe ich mit einem zeitstempel. nachdem ich die nachricht abgeschickt habe, merke ich mir meine
position an dem zeitpunkt.
-kriege ich keine antwort vom server, ist die welt wunderbar und ich mache weiter wie bisher.
bekomme ich jedoch ne nachricht vom server, sehe ich mir den zeitstempel an und korrigiere meine position.
=>(siehe pc[b] fürs empfangen des gegnerischen players)

[server]
-ich bin der server. ich weiss wie die map aussieht und wo bei welcher posi eine kollision stattfindet.
-wow ich kriege eine nachricht von pc[a]. mal sehen ob er gegen die wand läuft. hmmm... das tut er nicht, gut, dann mal ab mit der posi an pc[b].

pc[b]
-yeah ich kriege futter vom server. jetzt kann ich den gegnerischen player platzieren.
-dieser gegnerische player bewegt sich nun die ganze zeit in die richtung, die der server mir gesagt hat.
gibt es ein update, informiert mich der server davon und ich korrigiere den gegnerischen schläger.


also wenn jetzt der pc[a] gegen eine wand läuft, sagt ihm der server das und er lässt die position bei pc[b] korrigieren.
ich hoffe wirklich, dass du mir folgen konntest. ich weiss sonst nicht wie ich das noch weiter erläutern könnte ;)

mfg
mangaka
DarkLord05
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 449

WinXP Pro SP2
Opera; Delphi 3 Pro; Delphi 2005, Turbo Delphi, dev-c++, Eclipse, MS Visual Studio .NET 2003, MS Visual C++
BeitragVerfasst: Do 14.09.06 18:11 
Glaube ich habs begriffen^^ wenns so läuft dann is das ja wunderbar :)
mangaka Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42

windows xp sp2
Delphi 2005 personal
BeitragVerfasst: Do 14.09.06 18:29 
j0ar und damit das läuft müssen die zeitintervall so klein wie möglich sein und das datenpaket deshalb sehr klein mit genug informationen über die posi und so.

und das ist halt mein problem. ich weiss nicht wie ich die datenpaketen möglichst klein mache.
DarkLord05
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 449

WinXP Pro SP2
Opera; Delphi 3 Pro; Delphi 2005, Turbo Delphi, dev-c++, Eclipse, MS Visual Studio .NET 2003, MS Visual C++
BeitragVerfasst: Do 14.09.06 18:58 
nim einfach nur die wichtigsten infos, also da die x position eh immer gleich ist (vom schläger) braucsht du nur die px anzahl von y zu übertragen, oder die positionsanzahl. Mehr nicht, und wenn du nur "500" überträgst dann ist es eben stelle 500. Mehr nicht, das wars^^
mangaka Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42

windows xp sp2
Delphi 2005 personal
BeitragVerfasst: Fr 15.09.06 23:12 
ich brauch mindestens 2 informationen. wie du schon gesagt hast die x-position und dann noch welcher player davon betroffen ist. also ob ich meinen schläger updaten muss oder der gegner bei mir im fenster.
loetmann
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


Delphi 3
BeitragVerfasst: Fr 15.09.06 23:30 
Hallo,

währe es nicht besser nur Daten zu übertragen wenn sich der Pongchcläger wirklich bewegt wird? so im OnMouseMove/SchlägerDraw? Denn ist es immer noch "Echtzeit" aber mit weniger Daten.

Ich würde es so machen
[Server] berechnet Ball und sendet Zielposition an C1 und C2
[Client1]berechnet Ball von letzter Pos zu neuer Pos, hat Schläger bewegt sende Daten zum S
[Client2]berechnet Ball von letzter Pos zu neuer Pos, macht nichts keine Daten
[Server] berechnet Ball und sendet Zielposition an C1 und C2
[Client2]berechnet Ball von letzter Pos zu neuer Pos, hat Schläger bewegt sende Daten zum S
[Server] berechnet Ball, errechnet Kollision und sendet Zielposition an C1 und C2


der Server müßte dann doch in nem Timer oder so laufen, könnte aber weniger Intervalle brauchen wenn der Ball nicht in Spielernähe ist. -> weniger Last.

ein Gruß
mangaka Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42

windows xp sp2
Delphi 2005 personal
BeitragVerfasst: Sa 16.09.06 00:45 
wie ich das sehen, müsste der ball nach deinem beispiel laggen. also es würde so aussehen als ruckle es.
außerdem, was machst du, wenn der spieler über einen längern zeitraum den schläger bewegt?

--
nagut man könnte auch beides im client einbauen. einen timer, der was losschickt, wenn der schläger in den letzten ms sich bewegt hat und nichts losschickt, wenn er nichts getan hat. das wäre wohl die beste lösung für den client.
dennoch gehts mir hier primär um die größe des datenpakets. ich habe irgendwo mal gelesen, dass man binärcode übertragen soll. weiss einer von euch dazu was?


ps:
vergesst diesen schei*** ball. der macht immo alles noch komplizierter. hauptaugenmekr auf die schläger richten, zumindest sollen die nicht laggen ;)
loetmann
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


Delphi 3
BeitragVerfasst: Sa 16.09.06 09:43 
Guten morgen,

da sollte nichts ruckeln, wenn der C die neue Koordinate (Ball oder Schläger bekommt) macht er eine Animation von Punkt A nach B. Damit hängt er vielleicht ein paar ms der Realität hinterher aber sollte so gehen. (mit OpenGL geht das fix)

Die kleinstmögliche Dateneinheit:
-Du brauchst den ID des Clienten
-Seine Aktion

Das könntes Du in 2-3 Bytes packen.

-reaktion vom Server
das währen etwas mehr, Ball, andere Clienten
Das währen den mehrere 2-3 Bytes-Pakete (pro client und Ball)

WEnn es nur 2 C sind könnte braucht man für die ID 2 Bit (00=Ball, 01=C1, 10=C2, 11=frei/anderes)

jetzt bleiben noch 6 Bit übrig:
die könnte man für Kommandos benutzen
und im nächsten Byte/s sendest Du die Kommandowerte.
ausblenden Quelltext
1:
2:
3:
4:
5:
Komando  Wert    = Aktion
000000   00000000 00000000 [Ball][koordinate x,y]
010000   00000000  [C1][koordinate y]
010001             [C1][spiel beenden]
100001             [C2][spiel beenden]

Wenn ein Byte pro Wert zu wenig ist muß halt mehr hin... oder komprimieren

Ein Gruß
mangaka Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42

windows xp sp2
Delphi 2005 personal
BeitragVerfasst: Sa 16.09.06 10:07 
moin moin,
genau sowas ähnliches habe ich mir vorgestellt. aber wie mache ich eine variable aus 4bytes?
ein array? ändert sich bei einem array nicht die größe?
und noch was. die größte zahl die ein byte einnehmen kann ist doch 255 oder?
ausblenden Delphi-Quelltext
1:
2:
3:
4:
=>1byte = 8bits
11 11 11 11 = 2^7 + 2^6 + 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0
            = 128 + 64  + 32  + 16  +  8  +  4  +  2  + 1
            = 255



jetzt noch ne frage so am rand:
wo ist der unterschied zwischen dem senden in einem stream und dem normalen sende()-befehl.
loetmann
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


Delphi 3
BeitragVerfasst: Sa 16.09.06 10:18 
Ja,

ein Byte(8Bit) =max. 255. Für größere Werte nimmst Du dann mehrere Bytes das kannst Du ja mit den Kommandos (->Protokoll) festlegen.

Bei einem Stream versendest Du mehrere Bytes hintereinander mit Send einen String (im Prinzip auch mehrere Bytes hintereinander), glaub ich.

Streams müßten theoretisch schneller sein, jedenfals bei Datei-I/O ließt man mit nem Stream schneller als mit read.

Ein Gruß
mangaka Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 42

windows xp sp2
Delphi 2005 personal
BeitragVerfasst: Sa 16.09.06 10:22 
soll ich dann einen stream zum server öffnen und dann die pakete einzelnt losschicken?
oder gibts ne möglichkeit die pakete gebündelt zu senden?
loetmann
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


Delphi 3
BeitragVerfasst: Sa 16.09.06 10:35 
Du solltest _immer_ mit dem Server verbunden sein (solange das Spiel läuft). Das geht am schnellsten da die Zeit fürs connecten nur einmal aufkommt. Da wird es egal sein ob Stream oder send. Ich würde send bevorzugen, so kann man evtl. besser auf die Kommandos vom S reagieren.

Guck Dir doch mal die Chat-Beispiele an, die sollten ja auch in "Realtime" laufen.

Das größere Problem wird aber eher die Verbindung als die Datenpaketgröße sein (gerade wenn es übers Web laufen soll). Wichtig ist da die geringe response-time (schreibt man das so?).

Ein Gruß