AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Zugriff auf Komponenten in einer anderen Unit

Ein Thema von daniel-volk · begonnen am 16. Jun 2004 · letzter Beitrag vom 17. Jun 2004
Antwort Antwort
daniel-volk

Registriert seit: 16. Jul 2003
170 Beiträge
 
Delphi 6 Enterprise
 
#1

Zugriff auf Komponenten in einer anderen Unit

  Alt 16. Jun 2004, 17:27
Hi Leute,

ich hoffe ich hab hier für mein Problem die richtige Kategorie erwischt und mir auch eine einigermaßen passende Überschrift einfallen lassen.

Jedenfalls geht es darum, dass ich ein Billard-ähnliches Prog schreiben will. Allerdings ist das von Billard noch etwas entfernt. Ich möchte vielmehr auf einem Billardtisch (ein Image) ein paar Kugel rumspringen lassen. Die Kugelmenge soll beliebig wählbar sein und die Kugeln sollen sowohl von den Wänden als auch voneinander abprallen.
Ich habe es schon so weit, dass die Kugeln von den Wänden reflektiert werden und ich auch beliebig viele Kugeln erstellen kann.
Das habe ich so gelöst, dass ich in einer weiteren Unit "Kugeln" einen Typ TBall erstellt habe, der Prozeduren zum bewegen, darstellen, createn usw besitzt. Es sind auch Variablen enthalten, die die Position der Kugel etc beinhalten.

In der Haupt-Unit ist die neue Unit eingebunden. Außerdem befindet sich dort ein dynamisches Array vom Typ TBall.
So weit so gut. Das geht auch alles sehr schön. Das einzige Problem ist jetzt, dass jede Kugel die Möglichkeit haben muss, auf das besagte Array zuzugreifen, um zu erfahren, welche Kugeln noch existieren. Außerdem muss sie auf die anderen Kugeln zugreifen können, um dann deren Variablen auszulesen.
Denn um eine Kollision festzustellen, muss ich von den anderen Kugeln die Koordinaten abfragen.
Ich habe da keine wirkliche Lösung parat. Vor allem, weil ich es sauber programmieren möchte. Ich möchte die Kugel-Unit auch problemlos noch in andere Projekte integrieren können, um damit vielleicht noch ein richtiges Billard zu proggen oder so - oder ich erstelle einen Bildschirmschoner.

Jedenfalls wäre es schön, wenn ihr mir helfen könntet.

MfG,
McDV.
  Mit Zitat antworten Zitat
Benutzerbild von alcaeus
alcaeus

Registriert seit: 11. Aug 2003
Ort: München
6.537 Beiträge
 
#2

Re: Zugriff auf Komponenten in einer anderen Unit

  Alt 16. Jun 2004, 18:10
Prozeduren, Funktionen und Variablen, die auch außerhalb einer Unit zur Verfügung stehen sollten, musst du im Interface-Teil deklarieren:

Delphi-Quellcode:
unit Test;

interface

funtion TestFunc: Integer;

var
  i: Integer;

implementation

var
  j: Integer;

function TestFunc: Integer;
begin
//
end;

function TestFunc2: Single;
begin
//
end;

end.
Also, die Funktion TestFunc und die Variable i sind auch außerhalb der Unit bearbeit- und verwendbar, TestFunc2 und j nicht.
Wenn du das ganze aber wirklich sauber lösen willst, dann mach das objektorientiert.

Greetz
alcaeus
Andreas B.
Die Mutter der Dummen ist immer schwanger.
Ein Portal für Informatik-Studenten: www.infler.de
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#3

Re: Zugriff auf Komponenten in einer anderen Unit

  Alt 16. Jun 2004, 18:22
Du brauchst mindestens 2 Klassen: TBall und TTisch.
TBall repräsentiert alle Eigenschaften eines Balles (x, y, Speed, Richtung, Farbe)
TTisch enthält eine ObjektListe oder dyn. Array mit allen TBall-Objekten auf dem Tisch.
Zusätzlich Länge und Breite des Tischs.
Ausserdem gibt es die Methoden
TTisch.MoveBalls(timeinterval:integer);
TTisch.CollisionBande(ball:TBall);
TTisch.CollisionBalls(ball1, ball2:TBall);
TTisch.PaintBackground(canvas:TCanvas);
TTisch.PaintBalls(canvas:TCanvas);
Property TTisch.BallCount;
Diese beiden Klassen werden beide in die Unit Billard reingepackt.
Andreas
  Mit Zitat antworten Zitat
daniel-volk

Registriert seit: 16. Jul 2003
170 Beiträge
 
Delphi 6 Enterprise
 
#4

Re: Zugriff auf Komponenten in einer anderen Unit

  Alt 16. Jun 2004, 18:50
Hi.

Ganz genau! Ich möchte es auch objektorientiert machen. Das ist ja ein Schulprojekt. Nur eben, dass die anderen Schüler es nicht so komplex machen. Aber objektorientiert soll es ja schon sein.
Und genau dafür suche ich eine Lösung. Wie gesagt: Ich möchte nicht auf irgendeine function oder so zugreifen, sondern lediglich auf eine Variable und eine Komponente (ist ja oben genauer beschrieben).

Die Unterunit ist ja nur in die Haupt-Unit eingebunden, aber nicht umgekehrt. Das wäre ja auch wieder unsauber.
Und die Unterunit enthält die Typendeklaration der Kugeln. Und ich brauche eine Möglichkeit, um aus dieser Typendeklaration heraus (also den Prozeduren der Unterunit) auf die anderen Komponenten vom Typ TKugel zuzugreifen.
Die gesamten Kugeln werden dabei in einem Array der Hauptunit verarbeitet. Also einem solchen Array:

  Kugeln : array of TKugel; Ich kann euch auch mal gerade den gesamten Quellcode vorlegen. Vielleicht hilft das ja weiter:
Wundert euch aber bitte nicht über die komische Nomenklatur. Das ist recht albern, aber unser Lehrer möchte das so haben .

Delphi-Quellcode:
unit mBaelle; //Dieses ist die Haupt-Unit.

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ExtCtrls, StdCtrls, mBall; //mBall ist die zweite Unit, die die Typendeklaration für den Ball enthält

type
  TFrmBaelle = class(TForm)
    ImTisch: TImage;
    BtnMove: TButton;
    TiBallMotor: TTimer;
    procedure BtnMoveClick(Sender: TObject);
    procedure TiBallMotorTimer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    Baelle : array of TBall; //das besagte Array
    { Public-Deklarationen }
  end;

var
  FrmBaelle: TFrmBaelle;

implementation

{$R *.DFM}


procedure TFrmBaelle.BtnMoveClick(Sender: TObject); //Schaltet den Timer ein und aus, ist also jetzt unwichtig
begin
  TiBallMotor.Enabled := not(TiBallMotor.Enabled);
end;

procedure TFrmBaelle.TiBallMotorTimer(Sender: TObject); //Hinter diesem "Motor" verbirgt sich nur der Timer, der die Prozeduren zum bewegen der Bälle aufruft
begin
  Baelle[0].Bewegen; //Ich weiß, dass das unschön ist. Aber es ist ja auch nur zum testen. Da kommt später eine vernünftige Schleife hin.
  Baelle[1].Bewegen;
end;

procedure TFrmBaelle.FormCreate(Sender: TObject);
begin
  ImTisch.Top := 10;
  ImTisch.Left := 10;
  ImTisch.Height := Screen.Height-10-100;
  ImTisch.Width := Screen.Width - 20;
  ImTisch.Canvas.Rectangle(0,0,Imtisch.Width,ImTisch.Height);
  Setlength(Baelle,2); //Auch das hier ist nur ein Test
  Baelle[0] := TBall.Create(200,160,30,10,ImTisch,RGB(00,33,99));
  Baelle[1] := TBall.Create(230,240,10,300,ImTisch,RGB(90,50,150));
end;

end.
Und die zweite Unit:

Delphi-Quellcode:
unit mBall;

interface

uses
  classes, ExtCtrls, graphics, Math;
type
  TBall = class(TObject) //Das ist der neue Objekttyp.
  protected
    xM,yM, Radius, Richtung : integer; //Mittelpunktskoordinaten des Balls
    kColor : TColor; //Variablem müssen vermutlich als public deklariert werden
    kTisch: TImage; //Der Billardtisch
    xmotion, ymotion : extended;
    procedure Darstellen;
    procedure Reflektion(Gegenwinkel : integer); //berechnet die Reflektion eines Balles
    procedure Zusammenstoesse_pruefen;
  public
    constructor Create(pX,pY,pRadius,pRichtung:integer; pTisch:TImage; Farbe : TColor);
    destructor Destroy; override;
    procedure Bewegen;
  end;

implementation


procedure TBall.Zusammenstoesse_pruefen;
begin

end;

constructor TBall.Create(pX,pY,pRadius,pRichtung:integer; pTisch:TImage; Farbe : TColor);
begin
  inherited Create;
  xM := px; yM := pY; Radius := pRadius; Richtung := pRichtung;
  kColor := Farbe;
  kTisch := pTisch;
  Darstellen
end;

destructor TBall.Destroy;
begin
  inherited Destroy
end;

procedure TBall.Darstellen;
begin
  with kTisch.Canvas do
  begin
    Pen.Mode := pmNotXOr;
    Pen.Color := clWhite;
    Brush.Color := kColor;
    Ellipse(xM-Radius,yM-Radius,xM+Radius,yM+Radius)
  end
end;

procedure TBall.Bewegen;
var
  rem : extended;
begin
  Darstellen;
  rem := sin(DegToRad(richtung));
  ymotion := ymotion + 2.5*rem;

  rem := cos(DegToRad(richtung));
  xmotion := xmotion + 2.5*rem;

  xm := xm + round(xmotion);
  xmotion := xmotion - round(xmotion);

  ym := ym + round(ymotion);
  ymotion := ymotion - round(ymotion);

  If xm+radius >= kTisch.Width then Reflektion(0);
  If ym+radius >= kTisch.Height then Reflektion(90);
  If xm-radius <= 0 then Reflektion(180);
  If ym-radius <= 0 then Reflektion(270);

  Darstellen;
end;

procedure TBall.Reflektion(Gegenwinkel : integer); //Der Gegenwinkel ist lediglich ein bezugswert zur Berechnung der Reflektion. Vielleicht habt ihr ja eine bessere Möglichkeit dafür. Die anderen Schüler lassen den Ball nur ohne Winkel in lediglich 4 Richtungen laufen. Deshalb habe ich mir ein vernünftiges System ausgedacht, damit der Ball auch in 360 verschiedene Richtungen wandern kann.
begin
  richtung := (540 - richtung + 2*gegenwinkel) mod 360;
end;

end.
Wie ihr seht, fehlt auch noch die Prozedur zur Berechnung des Abprallwinkels zweier Kugeln. Aber dafür kann ich ja auch die Prozedur Reflektion einsetzen. Ich muss den Gegenwinkel eben nur über den ArcSin anhand der relativen Positionen zwischen den zwei Kugelmittelpunkten bestimmen. Das ist ja kein Problem. Auch die Feststellung einer Überschneidung ist nicht weiter schwer, da das ja dann gegeben ist, wenn die Distanz zwischen den Kugelmittelpunkten geringer ist als die Summe der Radien.

Trotzdem bleibt das Problem: Wie kann der eine Ball wissen, wo der andere Ball ist? Und das nach Möglichkeit noch objektorientiert.
Hat vielleicht auch jemand von euch zufällig eine gute Definition der Objektorientierten Programmierung parat?

Schonmal danke im Voraus!

MfG,
Daniel.
  Mit Zitat antworten Zitat
daniel-volk

Registriert seit: 16. Jul 2003
170 Beiträge
 
Delphi 6 Enterprise
 
#5

Re: Zugriff auf Komponenten in einer anderen Unit

  Alt 16. Jun 2004, 18:53
@shima:

Hmm, das geht sicherlich, aber das muss auch einfacher gehen. Der Tisch hat ja schon einen Typ, nämlich TImage!
Es müssen sich ja nur noch die Bälle untereinander kennen.
Kann ich da nicht irgendwie mit der Komponentenliste arbeiten? Aber wie?

Danke,
Daniel.
  Mit Zitat antworten Zitat
nieurig

Registriert seit: 26. Apr 2004
113 Beiträge
 
Delphi 6 Professional
 
#6

Re: Zugriff auf Komponenten in einer anderen Unit

  Alt 17. Jun 2004, 10:14
Hi Daniel,
ich würde dem Konstruktor vom Ball eine Referenz auf den Tisch übergeben. Im Prinzip hast Du ja schon was ähnliches, nur das Du nicht auf das Objekt selbst sondern auf dessen Image verweist.
Aus:

 constructor TBall.Create(pX,pY,pRadius,pRichtung:integer; pTisch:TImage; Farbe : TColor); würde
  constructor TBall.Create(pX,pY,pRadius,pRichtung:integer; pTisch:>>TFrmBaelle<<; Farbe : TColor); Bei der Erstellung der Bälle könnte man dann die Referenz auf den Tisch übergeben
 Baelle[0] := TBall.Create(200,160,30,10,>>self<<,RGB(00,33,99)); und somit in der Klasse TBall auf alle öffentlichen Methoden der Klasse TFrmBaelle zugreifen.

Niels

P.S. Gibt es eigentlich eine Möglichkeit in einem DelphiCode-Tag die Fettschrift einzuschalten? In der Voranzeige werden nur die Tags angezeigt.
Erspare Dir die Gedanken über ungelegte Eier !!!
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:40 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz