Autor Beitrag
Dude566
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: So 29.03.09 13:37 
Also ich komme momentan einfach nicht weiter:

Mal bewegen sich die Schläger aber dann auch dauerhaft und gehen wieder in die Ursprungsposition zurück, zucken nur ein paar Pixel hin und her.

Habe wirklich nicht mehr viel Zeit bin deshalb offen für, wenn möglich einfache Lösungsvorschläge.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls;

type
  TPong = class(TForm)
    Go: TButton;
    Panel1: TPanel;
    Timer1: TTimer;
    spielerhoch: TTimer;
    spielerrunter: TTimer;
    Spieler: TButton;
    CPU: TButton;
    cpuhoch: TTimer;
    cpurunter: TTimer;
    ball: TTimer;
    procedure GoClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure keys(Sender: TObject; var Key: Word;
      Shift: TShiftState);
    procedure spielerhochTimer(Sender: TObject);
    procedure spielerrunterTimer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Pong: TPong;

implementation

{$R *.DFM}

// Go Button
procedure TPong.GoClick(Sender: TObject);
begin
     Timer1.Enabled := true;
end;

// Aufruf von Tasten Procedure
procedure TPong.Timer1Timer(Sender: TObject);
begin
   Timer1.Enabled := false;
end;

// Tastendrücke auswerten und Bewegungen ausführen
procedure TPong.keys(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
   if (key=VK_UP)  then spielerhoch.Enabled:=true else
   if (key=VK_DOWN) then spielerrunter.Enabled := true;
end;

// Spieler Schläger hoch
procedure TPong.spielerhochTimer(Sender: TObject);
begin
     if Spieler.Top > Panel1.Top then Spieler.Top := Spieler.Top - 2;
     spielerhoch.Enabled := false;
end;

// Spieler Schläger runter
procedure TPong.spielerrunterTimer(Sender: TObject);
begin
     if (Spieler.Top + Spieler.Height) < (Panel1.Top + Panel1.Height)
        then Spieler.Top := Spieler.Top + 2;
     spielerrunter.Enabled := false;
end;

end.


Gruß Dude566

PS: Bitte keine Kommentare, ich solle einen Crashkurs machen, das werde ich auch aber bis zur Präsentation unseres Programms habe ich dafür keine Zeit.

Moderiert von user profile iconNarses: Titel geändert, ist jetzt nicht mehr "eilig".

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.

Für diesen Beitrag haben gedankt: Elias
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 29.03.09 15:02 
Am besten nimmst du einen Timer (der permanent läuft) und prüfst dann mit einer Variable die du außerhalb setzt, ob sich der schläger nach oben oder nach unten bewegen soll. Wenn die Taste losgelassen wird, muss diese Variable auch wieder zurückgesetzt werden.

Pseudocode:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
// key down
  if (key=kup) then
  begin
    up := true;
    down := false;
  end else
  if (key=kdown) then
  begin
    down := true;
    up := false;
  end;
// key up
  if (key=kup) then
    up := false;
//...
// Timer
  if up then
  begin
  //...
  end else
    if down then
//..

für up und down reicht auch eigentlich eine Variable.
ausblenden Delphi-Quelltext
1:
2:
type
  TDirection = (dNone, dUp, dDown);

oder so ähnlich.

mfg
Dude566 Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: So 29.03.09 16:30 
Aber jetzt habe ich schon für die Bewegungen jeweils 2 Timer gemacht, oder soll ich daraus dann einfach Procedures machen die dann ausgeführt werden wenn der eine Timer die Tastenprocedure ausführt, und dort die Bewegungen verwaltet?

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 29.03.09 16:55 
Naja, wenn das oben dein ganzer Code ist, hast du ja jetzt net soooo viel gemacht als dass man das nicht nochmal grundlegend überdenken könnte und so gravierend ist die Änderung nicht. Wie das im Prinzip funktioniert habe ich bereits oben beschrieben und separate Prozeduren brauchst du dafür auch nicht.

mfg


Zuletzt bearbeitet von F34r0fTh3D4rk am So 29.03.09 17:17, insgesamt 3-mal bearbeitet
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: So 29.03.09 16:56 
Du nimmst einen einzigen Timer und prüfst in dem, ob eine Taste gedrückt wird. Pseudocode:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
procedure Timer1;
begin
  if GetAsyncKeyState(VK_UP) <> 0 then 
    geheUmEinsNachOben;

  if GetAsyncKeyState(VK_Down) <> 0 then 
    geheUmEinsNachUnten;
end;


Der Timer hat ein kleines Intervall.

_________________
"Wer Ego-Shooter Killerspiele nennt, muss konsequenterweise jeden Horrorstreifen als Killerfilm bezeichnen." (Zeit.de)
Dude566 Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: So 29.03.09 17:00 
Danke user profile iconGTA-Place, das hilft mir wirklich weiter.

Aber für die Ballbewegung, Kollisionsabfrage und den CPU Spieler brauche ich doch auch jeweils einen Timer oder?

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 29.03.09 17:02 
Nein, man kommt immer mit genau einem Timer aus und sollte das auch tun(*). Man nimmt einfach den kleinsten "gemeinsamen Nenner" sozusagen. Wenn man größere Intervalle braucht, macht man diverse Aktionen eben in jedem x-ten Intervall (z.B. mit nem Zähler und Modulo).

Man kommt auch völlig ohne Timer aus (aber das ist schon ein bissl Off-Topic):
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
while true do
begin
  //...
  sleep(20);
end;

(*)So weit ich weiß (lasse mich gerne eines besseren belehren) sind Timer in Delphi Suche in: Delphi-Forum, Delphi-Library THREADs und müssen folglich synchronsiert werden (Suche bei Google RACE CONDITIONS).


Zuletzt bearbeitet von F34r0fTh3D4rk am So 29.03.09 17:22, insgesamt 4-mal bearbeitet
Dude566 Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: So 29.03.09 17:20 
Ok der Schläger bewegt sich, aber nur nach oben. Wieso? Hab ich ne Abfrage vergessen ob die Taste immer noch gedrückt ist?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
// Bewegung Spieler.
procedure TPong.Timer1Timer(Sender: TObject);
begin
   if GetAsyncKeyState(VK_UP) <> 0 then
      if Spieler.Top > Panel1.Top then Spieler.Top := Spieler.Top - 4
      else
   if GetAsyncKeyState(VK_DOWN) <> 0 then
      if (Spieler.Top + Spieler.Height) < (Panel1.Top + Panel1.Height)
                    then Spieler.Top := Spieler.Top + 2;
end;

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 29.03.09 17:28 
Das sieht soweit ganz richtig aus. Wenn ich das richtig verstanden hab, drückst du "oben" und er bewegt sich nach oben und wenn du nach "unten" drückst passiert nichts?
Wäre schön, den gesamten Quelltext sehen zu können (vielleicht verbergen sich ja noch irgendwo irgendwelche Code-Leichen).
Dunkel
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 682

Mac OS X Snow Leopard
Xcode 3.1
BeitragVerfasst: So 29.03.09 17:29 
user profile iconF34r0fTh3D4rk hat folgendes geschrieben Zum zitierten Posting springen:
(*)So weit ich weiß (lasse mich gerne eines besseren belehren) sind Timer in Delphi Suche in: Delphi-Forum, Delphi-Library THREADs und müssen folglich synchronsiert werden (Suche bei Google RACE CONDITIONS).

Nein, Timer werden von Windows bereitgestellt. Und da Windows nur eine begrenzte Anzahl dieser Timer-Objekte besitzt, sollte man auch sparsam mit diesen umgehen. Für jeden Pups einen eigenen Timer zu verwenden sollte, genau wie globale Variablen und sonstiger Unsinn, welchen man mit Delphi anstellen kann, verboten werden.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
procedure TPong.Timer1Timer(Sender: TObject);
begin
   if GetAsyncKeyState(VK_UP) <> 0 then
     begin      
       if Spieler.Top > Panel1.Top then Spieler.Top := Spieler.Top - 4;
     end
   else
     begin
       if GetAsyncKeyState(VK_DOWN) <> 0 then
         if (Spieler.Top + Spieler.Height) < (Panel1.Top + Panel1.Height)
           then Spieler.Top := Spieler.Top + 2;
     end; 
end;

Du hattest einen Dreher in Deiner Logik. Mit begin-end-Blöcken ist es auch leserlicher, finde ich.

_________________
Ich streite einsam mich mit dieser Oberflächenwelt
Gutes sei ein löblich Brot von dem ich zehre - bis zum Tod [Das Ich - Im Ich]
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 29.03.09 17:46 
Stimmt, hatte das eine if übersehen :D (die Formatierung hatte das gut kaschiert)

@Timer: Da Threads auch vom BS verwaltet werden, sehe ich nicht, warum sich das ausschließen sollte :wink:


Zuletzt bearbeitet von F34r0fTh3D4rk am So 29.03.09 17:48, insgesamt 1-mal bearbeitet
Dude566 Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: So 29.03.09 17:48 
Zur Ballbewegung, ich dachte mir ich Zeichne immer wieder eine Ellipse auf die Form und frage dann die Koordinaten ab ob sie mit einem Schläger kollidiert oder bereits hinter dem Schläger ist.

Aber wie ist das beim Start? Also wo lasse ich sie in welche Richtung starten?

Und bei dem Einfallswinkel gleich Ausfallswinkel muss ich nur beachten das immer eine Richtung dann negativ oder positiv wird.

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 29.03.09 17:49 
Lasse sie doch zufällig entweder nach rechts oder links fliegen.

ausblenden Delphi-Quelltext
1:
2:
3:
if (random(2) = 0) then
  links() else
     rechts();
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: So 29.03.09 19:03 
user profile iconF34r0fTh3D4rk hat folgendes geschrieben Zum zitierten Posting springen:
@Timer: Da Threads auch vom BS verwaltet werden, sehe ich nicht, warum sich das ausschließen sollte :wink:
Wären Timer Threads, müsstest du ja schon bei einem Race Conditions en masse bekommen ;) .

_________________
>λ=
F34r0fTh3D4rk
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 5285
Erhaltene Danke: 29

Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
BeitragVerfasst: So 29.03.09 19:04 
Nicht zwangsläufig. Gerade bei einem Game spielt sich dann ja eigentlich alles im Timer ab. Race Conditions müssen auch nicht immer zu einem (sichtbaren) Fehler führen. Aber es scheint wirklich so zu sein, dass Timer im Hauptthread laufen. Dann kann ich ja beruhigt schlafen ;)
Dude566 Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: Mo 30.03.09 15:52 
Ich habe mich jetzt für eine Ellipse mit TShape entschieden, die sich dann in eine zufällige Richtung bewegen soll.
Soll ich das am besten mit 2 Randomzahlen machen, und dann jenachdem ob 1 oder 2 in die jeweilige Richtung gehen?
Aber das kann ich ja nicht mit in den Timer das müsste dann doch bei GoButton immer oder?

2.
Wie frage ich denn dann ab, wenn der Ball jeweils den Button trifft, Spieler wird an rechter Seite getroffen und CPU Spieler an der linken Seite des Buttons getroffen.
Wenn getroffen wird dann soll der Ball wieder in die andere Richtung wechseln, aber immer noch mit gleicher Steigung, wegen Einfallswinkel = Ausfallswinkel.

3. Dann brauche ich noch eine Abfrage ob der Ball den oberen oder unteren Rand berührt und dort dann auch wieder in die richtige Richtung lenken.

Das passt doch nicht alles in einen Timer oder?
Wie soll ich das machen, also die Abfragen?

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls;

type
  TPong = class(TForm)
    Go: TButton;
    Timer1: TTimer;
    ball: TTimer;
    Panel1: TPanel;
    Spieler: TButton;
    CPU: TButton;
    kugel: TShape;
    procedure GoClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Pong: TPong;

implementation

{$R *.DFM}

// Go Button
procedure TPong.GoClick(Sender: TObject);
begin
     kugel.Top := 136;
     kugel.Left:= 144;
     Timer1.Enabled := true;

end;

// Bewegung Spieler.
procedure TPong.Timer1Timer(Sender: TObject);
begin
// Bewegungen des Spielers
if GetAsyncKeyState(VK_UP) <> 0 then
     begin
       if Spieler.Top > 8 then Spieler.Top := Spieler.Top - 2 ;
     end
   else
     begin
       if GetAsyncKeyState(VK_DOWN) <> 0 then
         if (Spieler.Top + Spieler.Height) < 316
           then Spieler.Top := Spieler.Top + 2;
     end;
end;

end.

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Mo 30.03.09 16:21 
Zitat:
Soll ich das am besten mit 2 Randomzahlen machen, und dann jenachdem ob 1 oder 2 in die jeweilige Richtung gehen?


Das hat FearOfTheDark schon geschrieben.

Zitat:
Wenn getroffen wird dann soll der Ball wieder in die andere Richtung wechseln, aber immer noch mit gleicher Steigung, wegen Einfallswinkel = Ausfallswinkel.


Also ich sehe da zwei Möglichkeiten: entweder Winkel und Speed definieren, oder aber sx und sy. sx wäre dann das, um wie viel der Ball nach rechts "geht", sy nach unten. Und dann schreibst du einfach beim Andocken am Schläger:

ausblenden Delphi-Quelltext
1:
sx := -sx;  // sx wird negiert					


Zitat:
3. Dann brauche ich noch eine Abfrage ob der Ball den oberen oder unteren Rand berührt und dort dann auch wieder in die richtige Richtung lenken.


ganz einfach so:

ausblenden Delphi-Quelltext
1:
sy := -sy;  // sy wird negiert					


Es wäre aber wirklich einfacher, du würdest Die DPR, PAS und DFM Dateien hochladen, in der Delphi-IDE lässt sich vieles leichter erkennen, als im Forum. :wink:

PS: Ja, das passt alles in einen Timer. Du fragst einfach ab, ob die X-Koordinate des Balls hinter Spieler2 oder vor Spieler1 ist (also nicht "oder", sondern natürlich getrennt).
Dude566 Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: Mo 30.03.09 16:25 
Nein ich meinte wie ich dann wenn ich all das machen will den Bewegungsvorgang machen kann.

Also hier mal das ganze Projekt im Anhang.

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.


Zuletzt bearbeitet von Dude566 am Di 31.03.09 16:18, insgesamt 1-mal bearbeitet
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Mo 30.03.09 16:31 
Ich bin mir nicht sicher, ob ich dich richtig verstehe. Meinst du, dass sich der Ball bewegt? Das ginge dann mit:

ausblenden Delphi-Quelltext
1:
2:
Ball.Left := Ball.Left + sx;
Ball.Top  := Ball.Top  + sy;
Dude566 Threadstarter
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: Mo 30.03.09 16:42 
Ja klar, der Ball muss sich ja bewegen, sonst ist es kein Pong.

de.wikipedia.org/wiki/Pong

Edit:
Ich kann den Spieler auch ohne vorher den Button gedrückt zu haben über die Pfeiltasten steuern. Das sollte aber eigentlich nicht so sein.

Und wenn ich den Button drücke hängt sich alles auf. ^^

_________________
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
Dieses Thema ist gesperrt, Du kannst keine Beiträge editieren oder beantworten.

Das Thema wurde von einem Team-Mitglied geschlossen. Wenn du mit der Schließung des Themas nicht einverstanden bist, kontaktiere bitte das Team.