AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Ein Panel an eine Instanz einer Klasse TBall übergeben
Thema durchsuchen
Ansicht
Themen-Optionen

Ein Panel an eine Instanz einer Klasse TBall übergeben

Ein Thema von Smiley · begonnen am 9. Mär 2022 · letzter Beitrag vom 11. Mär 2022
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von Smiley
Smiley

Registriert seit: 9. Dez 2004
Ort: Gedern
205 Beiträge
 
Delphi 10.4 Sydney
 
#1

Ein Panel an eine Instanz einer Klasse TBall übergeben

  Alt 9. Mär 2022, 17:29
Delphi-Version: 10.4 Sydney
Hallo Delphi Freunde
ich habe eine Klasse TBall erstellt, die soll einen Ball auf einem übergebenen TPanel fliegen lassen.
Das Aufrufende Form mit dem Panel1 soll eine Instanz von TBall erstellen und das Panel an die Klasse TBall übergeben.
In TBall erzeuge ich einen Timer der den Ball fliegen lässt (Kreis prallt an den Rändern ab).

1. Ich habe versucht das Panel als Property zu übergeben (BallA:=TBall.Create; BallA.Panel:=Panel1; BallA.Start)
über BallA.Start soll sich der Ball in dem Panel bewegen.
Es ist aber nicht im Panel zu sehen.
Wie würdet ihr das übergeben des Panels machen, kann ich das "übergeben" eventuell auch mit dem Create machen? (BallA:=TBall.Create(Panel1)
Das hat, bei mir, in dieser Syntax so nicht funktioniert.

2. Geht das überhaupt, dass der Timer den ich in der Klasse Ball erzeuge unabhängig läuft und ich mit jeder erzeugten Instanz von TBall ein eigenes Intervall im Timer setzen kann?
Sollte doch funktionieren.
Ich habe jedoch gelesen, dass das Timer-Objekt nicht Threadsave ist, somit kann ich die Erzeugten Bälle dann wohl nicht in einen eigenen Thread auslagern, nehme ich an.
Oder gibt es dafür eine Lösung?

3. Im Constructor Create funktioniert keinen Haltepunkt. Erst wenn ich die Initialisierung meiner Variablen in eine procedure Init auslagere und diese aufrufe, dann bleibt das Prgramm beim Haltepunkt im Init stehen. Ist das so normal?
Angehängte Dateien
Dateityp: pas uMain.pas (847 Bytes, 0x aufgerufen)
Dateityp: pas uBall.pas (5,2 KB, 0x aufgerufen)

Geändert von Smiley (10. Mär 2022 um 13:26 Uhr) Grund: Unit hinzugefügt
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben

  Alt 9. Mär 2022, 19:02
Aus Zeitgründen habe ich jetzt nicht Deinen Quellcode eingesehen.

1) Grundsätzlich musst Du einem zur Laufzeit erzeiugten Control aber auch noch einen Parent zuweisen.
MyBall.Parent := MyPanel; Damit sollte Dein Control zumindest schon mal sichtbar sein.

2) Die VCL ist für Spiele und Echtzeitanwendungen eher ungeeignet.
Du kannst zwar einen Timer verwenden und so einzelne Schritte von Objekte berechnen während Du auch noch auf Maus und Tastatur reagierst, aber das ist eher nur für Testzecke und zum Lernen tauglich.
Irgendwann wird das hakelig und umständlich.
Aber zum Lernen ist das erst mal völlig in Ordnung. Threads zu verwenden ist aufwendig und eher für umfangreichere (längere) Positionsberechnungen die Ergebnisse dann innerhalb der VCL darzustellen muss wieder synchronisiert werden. Das heißt, man muss genau überlegen, was man wie und warum in einen Thread auslagert.
Wir hatten hier https://www.delphipraxis.net/175033-...-schlecht.html mal ein paar Überlegungen zu dem Themenbereich angestellt und bei #59 habe ich mal ein kleines Testprojekt vorgestellt.

3) Ein Haltepunkt sollte auch im Constructor funktionieren. Vermutlich wird der bei Dir nicht korrekt aufgerufen.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Smiley
Smiley

Registriert seit: 9. Dez 2004
Ort: Gedern
205 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben

  Alt 9. Mär 2022, 19:17
Danke Stahli für Deine Antwort.

Das zuweisen des Balls habe ich mit:
shpBall := TShape.create(fSpielfeld);
shpBall.Left := 10;
shpBall.Top := 10;
shpBall.Pen.Color := fPenColor;
shpBall.Brush.Color := fBrushColor;
shpBall.SetParentComponent(fSpielfeld); <---

gemacht.
Das scheint aber nicht korrekt zu sein.

Mein Contructor von TBall sieht so aus:
constructor Tball.Create;
begin
Init;
end;
Wenn ich einen Haltepunkt auf das Init setze, bleibt der Debugger da nicht stehen.
Als würde der Constructor gar nicht aufgerufen.
Sollte er aber doch bei TBall.Create oder?
  Mit Zitat antworten Zitat
Benutzerbild von Smiley
Smiley

Registriert seit: 9. Dez 2004
Ort: Gedern
205 Beiträge
 
Delphi 10.4 Sydney
 
#4

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben

  Alt 9. Mär 2022, 19:34
Mir fällt gerade auf, ich sollte dem Shape auch sagen welche Form es annehmen soll.
  Mit Zitat antworten Zitat
Blup

Registriert seit: 7. Aug 2008
Ort: Brandenburg
1.464 Beiträge
 
Delphi 12 Athens
 
#5

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben

  Alt 10. Mär 2022, 08:30
Das zuweisen des Balls habe ich mit:
shpBall := TShape.create(fSpielfeld);

Das scheint aber nicht korrekt zu sein.

Mein Contructor von TBall sieht so aus:
constructor Tball.Create;
Du rufst den richtigen virtuellen constructor von TComponent auf, deklarierst aber einen anderen, der aber nicht aufgerufen wird.
Deine Deklaration müsste eigentlich so aussehen:
Delphi-Quellcode:
type
  TBall = class({...})
  public
    constructor Create(AOwner: TComponent); override;
  {...}
Und nicht das "inherited;" als erste Zeile im constructor vergessen.
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#6

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben

  Alt 10. Mär 2022, 09:19
Vielleicht kannst du dir hier etwas von abschauen..
..gelöscht!

Geändert von venice2 (10. Mär 2022 um 16:42 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Smiley
Smiley

Registriert seit: 9. Dez 2004
Ort: Gedern
205 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben

  Alt 10. Mär 2022, 12:06
@Venice2
Dein Strandball ist toll, aber zu kompliziert für ein Tutorial, wegen der vielen Windows und OpenGL Aufrufe.
Du hast im Main zuviel von den OpenGL Aufrufen drin, das verwirrt mich.
Das Global.pas ist schön aufgeräumt und mit normalem DelphiCode, das hätte ich in das Main.pas mit reingenommen und das aus dem Main.pas ausgelagert.
Ich versuche im Main.pas nur das nötigste reinzuschreiben, um einen Überblick zu haben.
Soviel zu meiner Meinung zu Deinem SourceCode.

Jetzt zu meinem eigentlichen Problem:
Im TBall möchte ich beim erstellen eine InitRoutine aufrufen, daher dachte ich mir ich benutze den Contructor, der sollte doch aufgerufen werden, wenn das Object angelegt wird.
(Ball:=TBall.Create)
Weiterhin ist die Überlegung von welchem Typ ich mein TBall anlegen sollt.
TObject oder TComponent oder ???
Wie deklariere ich den Constructor und wie implementiere ich ihn dann.
Benutze ich override oder virtual oder ???
Im Init create erstelle ich auch einen Timer den ich verwende.
Den muss ich doch später wieder freigeben.
Dafür dachte ich, verwende ich doch den destructor.

1. Hier ist also einmal die Frage von welchen Typ sollte ich am besten ableiten.
2. Wie sieht die Syntax für den Constructor und Destructor aus (in der Deklaration und der Implemetation)
3. Geht es auch anders, dass ich eine Init Routine beim Create aufrufen kann ohne einen Constructor anzulegen?

Das ganze ist für mich der Einstieg in die OOP und die Erstellung von Objekten.
Der Ball ist nur ein Beispiel für das Aufrufen eines Objektes und das arbeiten auf Objekten des Aufrufenden.
Danach versuche ich mehrere Möglichkeiten den Ball darzustellen (Mit Draw,als Shape, als Image oder als letztes mit OpenGL)

Geändert von Smiley (10. Mär 2022 um 12:40 Uhr)
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#8

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben

  Alt 10. Mär 2022, 16:42
Zitat:
@Venice2
Dein Strandball ist toll, aber zu kompliziert für ein Tutorial, wegen der vielen Windows und OpenGL Aufrufe.
Na dann.. kein OpenGL

Geändert von venice2 (11. Mär 2022 um 12:25 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Smiley
Smiley

Registriert seit: 9. Dez 2004
Ort: Gedern
205 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben

  Alt 10. Mär 2022, 17:20
@Venice2
Sehr schön gemacht, sieht auch gut aus ohne das OpenGL.
Du hast hier SKAERO verwendet, ist das etwas zusätzliches, konnte auf die schnelle nichts dazu finden.
Viel WindowsCode(Fensterverwaltung mit drin) und einiges das aussieht als sei es zu einer Zeit geschrieben als Delphi noch nicht so viel mit drin hatte (StrUtils gibts mittlerweile für MidStr,LeftStr usw., hatte ich mir früher auch mal selbst gebastelt aus dem Copy Befehl).
Globals.pas ist scheinbar eine alte Zusammenstellung von Befehlen, um es mit einigen Befehlen leichter zu haben. (Einiges gibt es jetzt schon in Delphi).

Die Sprite Technik ist was für mich, das scheint etwas einfacher zu sein als OpenGL.

Danke für den Code, da kann ich noch einiges draus lernen.
  Mit Zitat antworten Zitat
venice2
(Gast)

n/a Beiträge
 
#10

AW: Ein Panel an eine Instanz einer Klasse TBall übergeben

  Alt 10. Mär 2022, 18:01
@Venice2
Sehr schön gemacht, sieht auch gut aus ohne das OpenGL.
Du hast hier SKAERO verwendet, ist das etwas zusätzliches, konnte auf die schnelle nichts dazu finden.
Viel WindowsCode(Fensterverwaltung mit drin) und einiges das aussieht als sei es zu einer Zeit geschrieben als Delphi noch nicht so viel mit drin hatte (StrUtils gibts mittlerweile für MidStr,LeftStr usw., hatte ich mir früher auch mal selbst gebastelt aus dem Copy Befehl).
Globals.pas ist scheinbar eine alte Zusammenstellung von Befehlen, um es mit einigen Befehlen leichter zu haben. (Einiges gibt es jetzt schon in Delphi).

Die Sprite Technik ist was für mich, das scheint etwas einfacher zu sein als OpenGL.

Danke für den Code, da kann ich noch einiges draus lernen.
Es geht hier eben darum keine VCL zu verwenden und einige Funktionen bzw. Units auszusparen das ist der ganze Trick!
SKAERO ist eine von mit erstellte Engine mit der man unabhängig von der VCL ist. Inclusive Skin Support und Verwendungen von Sprites.
Diese kann man mit der Maus selektieren und verschieben solange wie sie bei der Erstellung nicht gesperrt werden.
Der Cursor ändert sich dann zum Kreuz.

Hier ein Update damit kannst du anschließend den Ball (Sprite(0..3)) zur Laufzeit auf eine andere Position verschieben.
Auch der Lauftext ist ein Sprite und kann verschoben werden.

Einfach diese Funktion ersetzen.
Delphi-Quellcode:
{$REGION 'DrawBounce'}
procedure DrawBounce;
var
  K: Integer;
  x, y: Integer;
  s: PSpriteData;
  rc: TRect;
begin

  if bAnimate then
  begin
    GetClientRect(HSprCtrl, rc);

    for K := 3 downto 0 do
    begin
      // wenn der linke Button gedrückt wird und die Maus sich auf einem Sprite (Ball(0..3))
      // befindet kann man ihn verschieben von dieser Position aus bewegt er sich dann weiter.
      if not gSprCtrl.GI_IsLButtonDown then
      begin
        s := @gSpriteData[k];
        if s.xDir > 0 then
        begin
          if s.xPos + s.nWidth > rc.Right then
            s.xDir := -s.xDir;
        end else
        if s.xPos < 0 then
          s.xDir := -s.xDir;

        if s.yDir > 0 then
        begin
          if s.yPos + s.nHeight > rc.Bottom then
            s.yDir := -s.yDir;
        end else
        if s.yPos < 0 then
          s.yDir := -s.yDir;

        s.xPos := s.xPos + s.xDir;
        s.yPos := s.yPos + s.yDir;
        gSprCtrl.GD_SetObjectXY(s.ID, s.xPos, s.yPos);
      end else
      begin
        s := @gSpriteData[k];
        // x, y Position vom aktuell selektierten Sprite
        // abhängig von der dazu gehörigen ID einlesen.
        gSprCtrl.GD_GetObjectXY(s.ID, x, y);
        s.xPos := x;
        s.yPos := y;
        // neue Position setzen
        gSprCtrl.GD_SetObjectXY(s.ID, s.xPos, s.yPos);
      end;
    end;

    if UseMarquee then
    begin
      gSprCtrl.GD_GetObjectXY(ID_OBJECT_MARQUEE, x, y);

      x := x - 2;
      if x < -MarqueeWidth then
        x := rc.Right + MarqueeWidth;
      gSprCtrl.GD_SetObjectXY(ID_OBJECT_MARQUEE, x, y);
    end;

    gSprCtrl.GI_UpdateWindow(HSprCtrl, false);
  end;
end;
{$ENDREGION}
uControls..
Delphi-Quellcode:
  for K := 0 to ID_MAX_SPRITE - 1 do
  begin
    gSpriteData[K].hBmp := gSprCtrl.GI_CreateBitmapFromFile(PWideChar(gSpriteData[K].ImageName), ImgW, ImgH);
    gSpriteData[K].ID := ID_OBJECT_SPRITE + K;
    gSpriteData[K].nWidth := ImgW;
    gSpriteData[K].nHeight := ImgH;
    gSpriteData[K].xPos := random(400);
    gSpriteData[K].yPos := random(300);

    gSprCtrl.GD_DrawBitmapToCtrl(HSprCtrl, gSpriteData[K].xPos, gSpriteData[K].yPos, gSpriteData[K].hBmp, $FFFFFFFF,
      gSpriteData[K].ID, GS_VISIBLE);
    // Werden die Sprites gesperrt lassen sie sich nicht mehr verschieben.
    gSprCtrl.GD_SetObjectLocked(gSpriteData[K].ID, true);
  end;

Geändert von venice2 (10. Mär 2022 um 18:20 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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 08:50 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