Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Button1 undefinierter Bezeichner


Dude566 - Fr 27.03.09 17:42
Titel: Button1 undefinierter Bezeichner
Also, wir müssen als Hausaufgabe Pong programmieren, was für mich ja schonmal ein Problem darstellt.

Von der Theorie her kein Problem, aber die Verwendung der Komponenten wie Timer etc untereinander wirft so manches Problem auf.

Ich bin jetzt bald fertig mit den Nerven.

Habe jetzt ein wenig geschrieben und da tritt folger Fehler auf:
Button1 undefinierter Bezeichner


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:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    PaintBox1: TPaintBox;
    tasten: TTimer;
    Button1: TButton;
    Button2: TButton;
    Play: TButton;
    procedure tastenTimer(Sender: TObject);
    procedure PlayClick(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
  procedure spielerhoch;
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

// Schläger hoch
procedure spielerhoch;
begin
   if Button1.Top > 1 then Button1.Top :=  Button1.Top-2;
   if Button1.Top > 1 then Button1.Top :=  Button1.Top-2;
   if Button1.Top > 1 then Button1.Top :=  Button1.Top-2;
   if Button1.Top > 1 then Button1.Top :=  Button1.Top-2;
   if Button1.Top > 1 then Button1.Top :=  Button1.Top-2;
   if Button1.Top > 1 then Button1.Top :=  Button1.Top-2;
end;

// Schläger runter
procedure spielerrunter;
begin
   if Button1.Top + 89 < 299 then Button1.Top := Button1.Top+2;
   if Button1.Top + 89 < 299 then Button1.Top := Button1.Top+2;
   if Button1.Top + 89 < 299 then Button1.Top := Button1.Top+2;
   if Button1.Top + 89 < 299 then Button1.Top := Button1.Top+2;
   if Button1.Top + 89 < 299 then Button1.Top := Button1.Top+2;
   if Button1.Top + 89 < 299 then Button1.Top := Button1.Top+2;
end;

// Tastendrücke prüfen
procedure TForm1.tastenTimer(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
     If (Key = VK_UP) Then procedure spielerhoch;
     If (Key = VK_DOWN) Then procedure spielerrunter;
end;

// Spielstart
procedure TForm1.PlayClick(Sender: TObject);
begin
     Timer.tasten.Enabled := true;
end;
end.


Was soll das?

Könnt ihr mir vielleicht Tipps geben wie ich das Projekt angehen soll, ich hatte jetzt schon mehrere Anläufe. Was ich z.B. brauche und beachten muss.

Gruß Dude566


jaenicke - Fr 27.03.09 17:45

Du deklarierst oben spielerhoch als Methode von Form1, unten aber nicht.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
  procedure spielerhoch;
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

// Schläger hoch
procedure TForm1.spielerhoch;


Dude566 - Fr 27.03.09 17:52

Ok Problem behoben, wie sieht es mit Vorschlägen zur Umsetzung des Programmes aus?


jaenicke - Fr 27.03.09 17:59

Naja, abgesehen von den wiederholten Zeilen (was soll der Unsinn?) ist das so ja nicht kompilierbar. Du hast eine Mischung von OnKeyDown und OnTimer (tastenTimer), das kann ja nicht gehen.

Und das ist ja auch syntaktisch falsch:

Delphi-Quelltext
1:
If (Key = VK_UP) Then procedure spielerhoch;                    


Dude566 - Fr 27.03.09 18:08

Ja kann sein, bin heute total durcheinander einfach viel zu viel um die Ohren.

Ich werde mich morgen nochmal in aller Ruhe hinsetzen und von vorne anfangen, trotzdem würde ich mich über Vorschläge zum Aufbau und Theorie des Programmes freuen.


jaenicke - Fr 27.03.09 18:19

Es gibt keine Kombination aus Timer und OnKey-Ereignissen. Für Spiele ist eine Lösung z.B. mit GetKeyState / GetAsyncKeyState möglich. Sonst hast du nämlich nach dem ersten Druck der Taste auch eine Verzögerung bis die nächsten Ereignisse vom Festhalten anfangen zu ticken (bei OnKeyXXX).


Dude566 - Sa 28.03.09 12:47

Ich könnte es doch so machen:

Beim Spielbegin startet ein Timer der die Procedure aufruft die, die Tastendrücke prüft und dann jeweils der passenden Bewegungsprocedure zuweist.

Oder andere Vorschläge?


jaenicke - Sa 28.03.09 12:57

user profile iconDude566 hat folgendes geschrieben Zum zitierten Posting springen:
Beim Spielbegin startet ein Timer der die Procedure aufruft die, die Tastendrücke prüft und dann jeweils der passenden Bewegungsprocedure zuweist.
Sag ich ja, GetKeyState / GetAsyncKeyState sind ja diese Routinen, die prüfen, ob Tasten gedrückt sind.


Dude566 - Sa 28.03.09 13:00

Ja ich habe bei der Verwendung Bedenken, weil wir eigentlich nur mit unseren bisherigen Mitteln (Lernstoff) das Programm schreiben sollen.

Gibts einen anderen ähnlich guten Weg, oder ist es wirklich die einzige gute Lösung?


jaenicke - Sa 28.03.09 13:05

Dann nimm nur OnKeyDown, musst aber die Taste kurz festhalten bis das Ereignis mehrfach auftritt. (Wie wenn du einen Buchstaben festhälst eben.) Dann brauchst du keinen Timer. Für die Tastenunterscheidung bietet sich case an.


Dude566 - Sa 28.03.09 13:09

user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Dann nimm nur OnKeyDown, musst aber die Taste kurz festhalten bis das Ereignis mehrfach auftritt.


Es soll aber keine Verzögerungen geben, ich setze mich gleich mal dahinter und schaue ob es klappt.


jaenicke - Sa 28.03.09 13:10

Beim ersten Druck der Taste gibt es auch keine, aber wenn du die festhalten willst, wie eigentlich in Spielen üblich ist, ist es ohne die oben genannten Methoden nicht schön lösbar.


Kha - Sa 28.03.09 13:14

Mit Timer, aber ohne GetKeyState, geht es so:


jaenicke - Sa 28.03.09 13:15

Das meinte ich, aber besonders schön finde ich die Lösung wie gesagt nicht. ;-)


Kha - Sa 28.03.09 13:17

Och, ist halt eine Emulation von GetKeyState. Immer noch besser als den Ball wegen der Tastenverzögerung nicht zu treffen :zwinker: .


Dude566 - Sa 28.03.09 17:15

Noch ein dummer Fehler, aber ich bin mir fast sicher das es nicht an mir liegt. :zwinker:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
type
  TPong = class(TForm)
    procedure Timer1Timer(Sender: TObject);
    procedure keys(Sender: TObject; var Key: Word;
      Shift: TShiftState);

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


Verstehe das mit dem Key noch nicht so ganz, welche Parameter muss ich jetzt noch eintragen, denn laut Delphi fehlen sie.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
procedure spielerhochTimer(Sender: TObject);

procedure TPong.spielerhochTimer(Sender: TObject);
begin
     if Button2.Top > Panel1.Top then Button2.Top - 2;
end;


Hier wird wieder wegen einem undefiniertem Bezeichner gemeckert: Button2


jaenicke - Sa 28.03.09 17:28

Du kannst keys nicht so aufrufen. Das musst du als Ereignis benutzen, wenn eine Taste gedrückt wird. Das ist also deine Reaktion auf das Ereignis OnKeyDown. Für einen Timer musst du GetKeyState benutzen oder es machen wie user profile iconKha sagte.


Dude566 - Sa 28.03.09 17:32

Und was ist mit dem undefinierten Bezeichner, ich habe meiner Meinung nach alles angegeben, du hast mich ja schon einmal auf einen Fehler bezüglich eines Buttons hingewiesen.


jaenicke - Sa 28.03.09 17:38

Wenn Button2 in TPong existiert, sollte das eigentlich klappen. :nixweiss:
Wie sieht denn die Deklaration oben komplett aus?


Dude566 - Sa 28.03.09 17:47

Ok war mein Fehler, ich hatte den Button zwischendurch umbenannt ohne es in der Procedure zu ändern. :autsch:

Jetzt aber der nächste Fehler in der gleichen Zeile:

Delphi-Quelltext
1:
2:
3:
4:
procedure TPong.spielerhochTimer(Sender: TObject);
begin
     if Spieler.Top > Panel1.Top then Spieler.Top - 2;
end;


[Fehler] Unit1.pas(63): Anweisung erforderlich, aber Ausdruck vom Typ 'Integer' gefunden


JayEff - Sa 28.03.09 17:50

Lies dir mal den Delphi Crashkurs [http://www.christian-stelzmann.de/artikel/crashkurs.htm] von Christian S. durch. Dir fehlen ja fast alle Grundlagen :shock:
Eine Zuweisung geht so: Variable := Wert; nicht so: Variable - 2


Mike19 - Sa 28.03.09 17:57

Hallo, was will Dir der Compiler sagen ?

Zitat:
[Fehler] Unit1.pas(63): Anweisung erforderlich, aber Ausdruck vom Typ 'Integer' gefunden


Du kann nicht nicht schreiben ".... then Button2.Top -2"


Richtig ist

"...then Butto2.top:=Button2.Top-2;"

Micha


Dude566 - Sa 28.03.09 17:57

Ich dachte das kann man bei Positionsangaben wie z.B. bei Buttons direkt so machen.


jaenicke - Sa 28.03.09 18:08

Es ist ja keine Anweisung, also was soll der Compiler damit machen? Woher soll der Compiler wissen, dass das Ergebnis der Differenz wieder zurückgeschrieben werden soll? ;-)


Dude566 - So 29.03.09 14:27

Hier gehts weiter:

http://www.delphiforum.de/topic_Pong+Eilig_91289.html


Regan - So 29.03.09 16:50

user profile iconDude566 hat folgendes geschrieben Zum zitierten Posting springen:
Hier gehts weiter:

http://www.delphiforum.de/topic_Pong+Eilig_91289.html

Tschuldigung fürs OffTopic, aber: :rofl: . Schreibst du jetzt hier ein Buch?


Dude566 - Mo 30.03.09 18:10

Wieso Buch schreiben, was is denn das für ein lahmer Witz?

http://www.delphiforum.de/viewtopic.php?t=91289


Christian S. - Mo 30.03.09 20:10

user profile iconDude566 hat folgendes geschrieben Zum zitierten Posting springen:
Hier gehts weiter:
Dann mache ich hier zu.

Bitte mache in anderen Threads (auch wenn es Deine sind) nicht mehr Werbung für andere von Deinen Threads.