| Autor |
Beitrag |
Dude566
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: 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.
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 public end;
var Pong: TPong;
implementation
{$R *.DFM}
procedure TPong.GoClick(Sender: TObject); begin Timer1.Enabled := true; end;
procedure TPong.Timer1Timer(Sender: TObject); begin Timer1.Enabled := false; end;
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;
procedure TPong.spielerhochTimer(Sender: TObject); begin if Spieler.Top > Panel1.Top then Spieler.Top := Spieler.Top - 2; spielerhoch.Enabled := false; end;
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 Narses: 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
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: 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:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| if (key=kup) then begin up := true; down := false; end else if (key=kdown) then begin down := true; up := false; end; if (key=kup) then up := false; if up then begin end else if down then |
für up und down reicht auch eigentlich eine Variable.
Delphi-Quelltext 1: 2:
| type TDirection = (dNone, dUp, dDown); |
oder so ähnlich.
mfg
|
|
Dude566 
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: 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
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: 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
      

Beiträge: 5248
Erhaltene Danke: 2
WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
|
Verfasst: So 29.03.09 16:56
Du nimmst einen einzigen Timer und prüfst in dem, ob eine Taste gedrückt wird. Pseudocode:
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 
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: So 29.03.09 17:00
Danke GTA-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
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: 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):
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 THREADs und müssen folglich synchronsiert werden ( RACE CONDITIONS).
Zuletzt bearbeitet von F34r0fTh3D4rk am So 29.03.09 17:22, insgesamt 4-mal bearbeitet
|
|
Dude566 
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: 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?
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| 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
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: 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
      
Beiträge: 682
Mac OS X Snow Leopard
Xcode 3.1
|
Verfasst: So 29.03.09 17:29
_________________ 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
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: So 29.03.09 17:46
Stimmt, hatte das eine if übersehen  (die Formatierung hatte das gut kaschiert)
@Timer: Da Threads auch vom BS verwaltet werden, sehe ich nicht, warum sich das ausschließen sollte 
Zuletzt bearbeitet von F34r0fTh3D4rk am So 29.03.09 17:48, insgesamt 1-mal bearbeitet
|
|
Dude566 
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: 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
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: So 29.03.09 17:49
Lasse sie doch zufällig entweder nach rechts oder links fliegen.
Delphi-Quelltext 1: 2: 3:
| if (random(2) = 0) then links() else rechts(); |
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: So 29.03.09 19:03
|
|
F34r0fTh3D4rk
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: 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 
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: 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?
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 public end;
var Pong: TPong;
implementation
{$R *.DFM}
procedure TPong.GoClick(Sender: TObject); begin kugel.Top := 136; kugel.Left:= 144; Timer1.Enabled := true;
end;
procedure TPong.Timer1Timer(Sender: TObject); begin 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
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: 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:
Delphi-Quelltext
| 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:
Delphi-Quelltext
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.
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 
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: 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
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: 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:
Delphi-Quelltext 1: 2:
| Ball.Left := Ball.Left + sx; Ball.Top := Ball.Top + sy; |
|
|
Dude566 
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: 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.
|
|