Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - eigene Prozedur erstellen, die ein Shape bewegt.


BoerseMan79 - Sa 03.11.12 00:42
Titel: eigene Prozedur erstellen, die ein Shape bewegt.
Hallo,
ich bin neu hier und hoffe, dass ich hier mit Delphi viel Spaß haben werde.

Ich arbeite zurzeit an einen Projekt. Ich muss eine Ampelsteuerung/Verkehrssystem programmieren/simulieren. Aber das ist hier nicht das Thema. Projekt ist grade gestartet und ich fange langsam erst an es zu Entwickeln. Meine Kenntnisse mit Delphi sind sehr gering. Ich kenne mich allerding mit den Grundlagen von C/C++ aus. Also Begriffe wie Funktionen, Schleifen, Klassen und so weiter sind mir ein Begriff. Und da Pascal Parallelen mit C und C++ hat, denke ich dass ich Delphi schnell begreifen werde.

Zuerst möchte ich ein Shape (Auto) bewegen. Wie ein Timer ein Shape bewegt weiß ich bereits. Ich will eine Prozedur "move" dazu bringen ein Shape zu bewegen und der Timer oder anderes Objekt (Button) soll diese Prozedur ausführen. Leider funktioniert das nicht so einfach:


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

interface

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

type
  TForm1 = class(TForm)
    Shape1: TShape;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
    //TProcedure = procedure;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  move;
end;
procedure TForm1.move;
  begin
    Shape1.left:=Shape1.left+1;
  end;
end.


da fehlt was! Aber was? Oder geht es ganz anders?


WasWeißDennIch - Sa 03.11.12 00:59

Du rufst eine Methode des Formulars auf, die nicht deklariert wurde. Schreib doch mal in den private Abschnitt:

Delphi-Quelltext
1:
procedure move;                    

Dann sollte sich etwas tun.


BoerseMan79 - Sa 03.11.12 02:53

Also folgendes:
Ich bringe die Prozedur allgemein zum Laufen und zwar wenn die Prozedur nur einfache Funktionen aufruft:


Delphi-Quelltext
1:
2:
3:
4:
procedure sagwas;
begin
  ShowMessage('Hi');
end;


Voraussetzung ist, die Prozedur muss vor der anderen Prozeduren sein, die diese Proz. aufrufen, oder ich muss die Prozedur vorher "anmelden", so wie in C/C++

Aber wenn meine Proz. auf Objekte aus TForm1 zugreifen will, dann gibts eine Fehlermeldung:

Zitat:
Undefinierter Bezeichner: 'Shape1'


und das ist mein Programm:


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

interface

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

type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Shape1: TShape;
    RadioButton1: TRadioButton;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
procedure move;
begin
  Shape1.left:=Shape1.left+1;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
   move;
end;

end.


Mathematiker - Sa 03.11.12 07:06

Hallo und :welcome: ,
Du kanst im Normalfall nur auf Shape1 mit einer Methode zugreifen, die auch zur gleichen Klasse gehört, d.h.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
type
  TForm1 = class(TForm)
    Timer1: TTimer;
    Shape1: TShape;
    RadioButton1: TRadioButton;
    procedure Timer1Timer(Sender: TObject);
  private
    procedure move;    //hier eintragen
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;
...
procedure Tform1.move;
begin
  Shape1.left:=Shape1.left+1;
end;

Das ist der Hinweis von WasWeißDennIch, nur etwas ausführlicher.

Alternativ ginge auch (ohne procedure move unter private)

Delphi-Quelltext
1:
2:
3:
4:
procedure move;
begin
  Form1.Shape1.left:=Form1.Shape1.left+1;
end;

Das finde ich persönlich aber sehr, sehr hässlich.
Natürlich kannst Du auch gleich das Bewegen von Shape1 in die Timer-Prozedur schreiben.

Beste Grüße
Mathematiker


BoerseMan79 - Sa 03.11.12 13:01

user profile iconMathematiker hat folgendes geschrieben Zum zitierten Posting springen:
...
Das finde ich persönlich aber sehr, sehr hässlich.
Natürlich kannst Du auch gleich das Bewegen von Shape1 in die Timer-Prozedur schreiben.
...


ja ich weiß, es ging ja erstmals ums Prinzip. Später sollen in meinem Verkehrssystem 45 Autos durch zwei Kreuzungen fahren. Die Autos sollen dann auf Stau, Rote Ampel reagieren und Richtungen auf Wunsch an einer Kreuzung auswählen. Und dann werden die Prozeduren in Timern immense groß.

Und aus optischen gründen wollte ich das mit Zwischenprozeduren verbessern.


WasWeißDennIch - Sa 03.11.12 13:09

Dagegen ist auch nichts zu sagen, aber es gibt einen Unterschied zwischen Routinen und Methoden. Methoden gehören zu einer Klasse, "normale" Routinen nicht.

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
type
  TDings = class
  public
    procedure DoSomething; // <-- Methodendeklaration
  end;

procedure TDings.DoSomething; // <-- Implementation der Methode
begin
  //Code
end;

procedure DoSomething; // <-- "normale" Routine, an keine Klasse gebunden
begin
  //Code
end;


BoerseMan79 - Sa 03.11.12 21:48

danke! Es hat geklappt! :zustimm:
Ich werde am Projekt weiter arbeiten und wenn ich fragen hab: I'll be back!