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 public procedure spielerhoch; end;
var Form1: TForm1;
implementation
{$R *.DFM}
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;
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;
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;
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; end;
var Form1: TForm1;
implementation
{$R *.DFM}
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
Dude566 hat folgendes geschrieben : |
| 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
jaenicke hat folgendes geschrieben : |
| 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:
- Im OnKeyDown den Key-Parameter in einem Feld der Form (von mir aus auch ne globale Variable ;) ) merken
- Im OnTimer dieses Feld auswerten und die entsprechende Prozedur aufrufen
- Im OnKeyUp das Feld leeren
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);
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
Kha 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
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? ;-)
Regan - So 29.03.09 16:50
Tschuldigung fürs OffTopic, aber: :rofl: . Schreibst du jetzt hier ein Buch?
Christian S. - Mo 30.03.09 20:10
Dude566 hat folgendes geschrieben : |
| 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.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!