![]() |
ping-pong->übermittlung
moin,
zurzeit programmiere ich das alt bekannte ping-pong game im netzwerk. immo arbeite ich am schläger ->bewege ich meinen schläger wird die position auf dem gegn. computer richtig angezeigt, nur die bewegung meines schlägers ist auf dem gegn.PC nicht zeitgleich mit der bewegung auf meinem pc. versteht ihr? also...: schläger(A) bewegt sich nicht so schnell auf pc(B) wie auf pc(A). jedoch ist die entgültige position von schläger(A) auf pc(B) richtig. ich geb euch ma den link zur .exe , dann könnt ihr es selbst aufprobieren und sehen was ich meine ^^ ![]() und hier nochma der code:
Delphi-Quellcode:
unit pingpongq;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdTCPServer, IdIPWatch, IdSocketHandle, DXClass; type TForm1 = class(TForm) IdTCPClient1: TIdTCPClient; IdTCPServer1: TIdTCPServer; Edit1: TEdit; IdIPWatch1: TIdIPWatch; Label1: TLabel; Label2: TLabel; procedure FormCreate(Sender: TObject); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); procedure IdTCPServer1Execute(AThread: TIdPeerThread); procedure Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure IdTCPClient1Connected(Sender: TObject); private LastStep: DWord; procedure Timer(Sender: TObject; var Done: Boolean); { Private declarations } public { Public declarations } end; var Form1: TForm1; y,p2top: Integer; p1_oben, p1_unten, senden_oben, senden_unten: Boolean; Player1, Player2: TImage; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var Binding: TIdSocketHandle;//Für die servereinstellungen begin //grafik: player1 Player1 := TImage.Create(Form1); Player1.Name := 'player1'; Player1.Parent := Form1; Player1.Top := 160; Player1.Left := 10; Player1.Picture.LoadFromFile('player1.bmp'); Player1.Visible := true; //grafik: player2 Player2 := TImage.Create(Form1); Player2.Name := 'player2'; Player2.Parent := Form1; Player2.Top := 160; Player2.Left := Form1.ClientWidth - 20; Player2.Picture.LoadFromFile('player2.bmp'); Player2.Visible := true; //server einstellen: IdTCPServer1.Bindings.Clear; Binding := IdTCPServer1.Bindings.Add; Binding.IP := idIPWatch1.LocalIP; Binding.Port := 9099; IDTCPServer1.Active := true; Application.OnIdle := Timer; DoubleBuffered := True; end; //zum gegn. server verbinden procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_Return then Begin IdTCPClient1.Host := Edit1.Text; IdTCPClient1.Port := 9099; IdTCPClient1.Connect; Edit1.Enabled := false; End; end; //client connected und gibt die posi vom eigenen schläger an procedure TForm1.IdTCPClient1Connected(Sender: TObject); begin IdTCPClient1.WriteLn('160'); end; procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_Space then Begin End; {p1_oben/p1_unten bewegen den eigenen schläger mit hilfe von senden_oben/senden_unten senden wir unsere posi} if Key = VK_UP then Begin p1_oben := true; senden_oben := true; End; if Key = VK_Down then Begin p1_unten := true; senden_unten := true; End; end; //hört mit den obigen aktionen auf procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_UP then Begin p1_oben := false; senden_oben := false; End; if Key = VK_Down then Begin p1_unten := false; senden_unten := false; End; end; {server nimmt gegn. nachricht auf und verarbeitet sie zu der posi vom gegn. schläger} procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var empfangen: String; begin while Form1.IdTCPClient1.Connected do Begin empfangen := AThread.Connection.ReadLn; p2top := StrToInt(empfangen); Player2.Top := p2top; End; end; {application.onIdle event fungiert als timer: entstehung und übermittlung der eigenen bewegung} procedure TForm1.Timer(Sender: TObject; var Done: Boolean); begin Done:=false; If GetTickCount-LastStep > 10 then //in 10ms ein schritt Begin y := 7; if (p1_oben) and (Player1.Top > 11) then Player1.Top := Player1.Top - y; if (p1_unten) and (Player1.Top < 379) then Player1.Top := Player1.Top + y; Label1.Caption := IntToStr(Player1.Top); if IdTCPClient1.Connected then Begin if senden_oben then IdTCPClient1.WriteLn(IntToStr(Player1.Top)); if senden_unten then IdTCPClient1.WriteLn(IntToStr(Player1.Top)); End; Label2.Caption := IntToStr(Player2.Top); LastStep:= GetTickCount; //neue Start Zeit end; end; end. |
Re: ping-pong->übermittlung
Hm, würde jetzt mal spontan auf sowas wie Netzwerk-Overhead tippen...
Erste Idee wäre jetzt ne Synchronisation einzubauen. Also Daten an PC2 schicken, PC2 schickt zurück das die Sachen angekommen sind und dann erst zeichnest Du das ganze auch auf PC1. Allerdings dürfte dabei dann die Bewegung von Schläger 1 auf PC 1 langsamer werden. Grüße Wolf |
Re: ping-pong->übermittlung
stimmt das wäre ne idee...
aber ich habe kein plan wie ich das realisieren soll, haste ne idee? |
Re: ping-pong->übermittlung
Naja, wenn Daten bei PC2 ankommen, abfragen ob es ne Positions-übermittlung ist und wenn ja dann direkt ein "Bekommen" zurück schicken.
Hab aber keine Ahnung ob TIdIPWatch sowas hergibt. Aber letztlich müsstest Du da doch auch abfragen können, ob was rein kommt. Hab mich noch nicht wirklich mit der Technischen Seite befasst. Schönes WE |
Re: ping-pong->übermittlung
ja also ich habe ein bissl rumgearbeitet und habe es jetzt synchron...
aber jetzt sieht das alles so rucklig aus, vorher sah nur der gegn. player so aus. wäre natürlich toll würde alles flüssig laufen... |
Re: ping-pong->übermittlung
das ist der neue code und es ist immernoch nicht synchron:
ich habs versucht die posi des schlägers schon vorher zu senden, aber es geht nicht... das beste wäre es ich benutze nanosekunden, aber wenn ich da 1/10000000 hinschreibe ändert sich nicht wirklich was. meine vermutung -> es geht nicht mit nanosek. ^^ vllt habt ihr noch ne idee
Code:
unit pp_mpq;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdSocketHandle, StdCtrls, IdIPWatch, IdTCPServer, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, ExtCtrls; type TForm1 = class(TForm) IdTCPClient1: TIdTCPClient; IdTCPServer1: TIdTCPServer; IdIPWatch1: TIdIPWatch; Edit1: TEdit; Label1: TLabel; Label2: TLabel; procedure FormCreate(Sender: TObject); procedure Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure IdTCPServer1Execute(AThread: TIdPeerThread); procedure FormClose(Sender: TObject; var Action: TCloseAction); private Zeit_1: DWord; Zeit_2: DWord; procedure Timer(Sender: TObject; var Done: Boolean); { Private declarations } public { Public declarations } end; var Form1: TForm1; Player1, Player2: TImage; p1_oben, p1_unten: Boolean; p2_top: Integer; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var Binding: TIdSocketHandle; begin p1_oben := false; p1_unten := false; p2_top := 160; Application.OnIdle := Timer; DoubleBuffered := True; //server einstellen: IdTCPServer1.Bindings.Clear; Binding := IdTCPServer1.Bindings.Add; Binding.IP := idIPWatch1.LocalIP; Binding.Port := 9099; IDTCPServer1.Active := true; // //grafik: player1 Player1 := TImage.Create(Form1); Player1.Name := 'player1'; Player1.Parent := Form1; Player1.Top := 160; Player1.Left := 10; Player1.Picture.LoadFromFile('player1.bmp'); Player1.Visible := true; //grafik: player2 Player2 := TImage.Create(Form1); Player2.Name := 'player2'; Player2.Parent := Form1; Player2.Top := 160; Player2.Left := Form1.ClientWidth - 20; Player2.Picture.LoadFromFile('player2.bmp'); Player2.Visible := true; end; //zum gegn. server verbinden procedure TForm1.Edit1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_Return then Begin IdTCPClient1.Host := Edit1.Text; IdTCPClient1.Port := 9099; IdTCPClient1.Connect; Edit1.Enabled := false; End; end; //hört mit den obigen aktionen auf procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin {p1_oben/p1_unten bewegen den eigenen schläger mit hilfe von senden_oben/senden_unten senden wir unsere posi} if Key = VK_UP then Begin p1_oben := true; End; if Key = VK_Down then Begin p1_unten := true; End; end; procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); begin while Form1.IdTCPClient1.Connected do Begin p2_top := StrToInt(AThread.Connection.ReadLn); End; end; procedure TForm1.Timer(Sender: TObject; var Done: Boolean); begin Done:=false; If GetTickCount - Zeit_1 > 10 then //in 10ms ein schritt Begin if (p1_oben) and (Player1.Top > 11) then Begin Player1.Top := Player1.Top - 7; p1_oben := false; End; if (p1_unten) and (Player1.Top < 379) then Begin Player1.Top := Player1.Top + 7; p1_unten := false; End; Label1.Caption := IntToStr(Player1.Top); Label2.Caption := IntToStr(Player2.Top); Zeit_1:= GetTickCount; //neue Start Zeit ermitteln End; if GetTickCount - Zeit_2 > 1 then Begin if IdTCPClient1.Connected then IdTCPClient1.Writeln(IntToStr(Player1.Top)); Player2.Top := p2_top; Zeit_2 := GetTickCount; End; end; procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin IdTCPClient1.Disconnect; end; end. |
Re: ping-pong->übermittlung
Da der Timer eine Auflösung von ~20ms hat, erreichst du höchstens eine Framerate von 1000ms/20ms = 50 FPS, was allerdings kein Ruckeln hervorruft :?
Es kann aber sein, dass die Indy "zu langsam" sind, die Daten zu versenden. Evtl. liegt das ja auch an deiner Internetgeschwindigkeit? Oder du sendest einfach zu viele Daten... |
Re: ping-pong->übermittlung
Ich würde darauf Tippen, dass die Indy Komponenten zu langsam sind und du mit Sockets Arbeiten solltest. Ausserdem muss deine Ping auch bei 20 msec liegen wegen dem Timer sonst hängt, dass Spiel immer hinterher. Ich würde "nur" alle 80 msec übertragen lassen. Kommt nun drauf an was für einen Rechner du hast und wie schnell sich der Ball bewegen soll.
|
Re: ping-pong->übermittlung
Zitat:
hmm..aber ich kann nur indy nutzen, weil nur das habe und mich nur damit auskenne. und warum sollte ich zuviele daten senden? ich sende nur eine sache und das ist die posi vom dem player. und nicht nur übers internet ist das so sondern auch über lan, das ist das dumme ja. wenn ich aber auf meinen eigene rechner verbinde dann läuft alles flüßig. naja das könnte auch nen hinweis auf die datengeschwindigkeit sein.. ---bin am verzweifeln--- |
Re: ping-pong->übermittlung
Zitat:
meinste mit sockets die standart dinger von borland? wenn ja -hab ich ja schon erwähnt- habe ich die nicht. oder meinste solche socket-dinger von indy/ für indy????(kenn mich bei indy nun auch nicht soo aus^^) sry für meine ausdrucksweise :) bei zuvielen ms sieht das schrecklich aus, richtig richtig schwerfällig das ganze->das ist auch nicht das wahre |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz