Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Problem mit Ballbewegung (Anfänger) (https://www.delphipraxis.net/120159-problem-mit-ballbewegung-anfaenger.html)

Halbgard 6. Sep 2008 11:10


Problem mit Ballbewegung (Anfänger)
 
Morgen :)

Ich bin gerade dabei, mit nem Freund sowas in der Art wie Brixx zu machen,
er kümmert sich um das mathematische Zeug, und ich versuch das dann irgendwie in den Quelltext zu basteln, also er dann auch mit.
Aber auf jeden Fall, ich bin gerade dabei, erst einmal einen Ball, nachdem man auf einen Button geklickt hat, in dem Fenster hinundher bewegen zu lassen.
Das wollt ich mit nem Timer machen, (hab dazu noch keine Tuts gefunden,) aber der Ball bewegt sich net wirklich :(

Delphi-Quellcode:
type
  TBall=Class
    x,y,r:Integer;
    BallFarbe:TColor;
    procedure anzeigen;
  End;

{...}

procedure TBall.anzeigen;
begin
  form1.Canvas.Pen.Color:=BallFarbe;
  form1.Canvas.brush.color:=ballfarbe;
  Form1.Canvas.Ellipse(x,y,x+2*r,y+2*r);
end; //nun, der Ball wird dann schonmal angezeigt...^^"

procedure TForm1.Button1Click(Sender: TObject);
var Ball:Tball;
begin
  Timer1.Enabled:=true;
  Ball:=Tball.Create;
  ball.BallFarbe:=clgreen;
  ball.BallFarbe:=clgreen;
  ball.x:=100;
  ball.y:=100;
  ball.r:=10;
  ball.anzeigen;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var ball:TBall;
    BallLeftRight,BallUpDown:Integer;
begin
BallLeftRight:=1;   //Jenachdem, wo er "anstößt", ändert sich seine Richtung.
BallUpDown:=2;
Ball:=TBall.create;
if ball.x+2*ball.r=400 then BallLeftRight:=2;
if Ball.x=0 then BallLeftRight:=1;
if Ball.y=0 then BallUpDown:=2;
if Ball.y+2*ball.r=400 then BallUpDown:=1;

Case BallUpDown of
  1:ball.y:=ball.y+1;
  2:ball.y:=ball.y-1;
End;

Case BallLeftRight of
  1:ball.x:=ball.x+1;
  2:ball.x:=ball.x-1;
End;

ball.anzeigen; //glaub, das is eher unnötig??
end; //den Quelltext vom Timer hatte ich erst in ner eigenen Procedure drinne,
     //aber das hatte auch net geklappt, also das er die Procedure immer wieder-
     /holt.
Das war der Erste Teil.

Hier mein zweites Problem.

Okai, des weiteren hab ich schonmal versucht, die Rechtecke hinzumalen.
Die haben jedoch nur nen schwarzen Rand, und keinen roten, und ne Füllfarbe schon garnicht, wenn sie angezeigt werden...^^"

Delphi-Quellcode:
type
  TBlock=class
    {var
      x,y,l,b:Integer;}  //Werden noch net wirklich gebraucht.
    RandFarbe:TColor;
    FuellFarbe:TColor;
    procedure aufbauen;virtual;
  end;
 
  TPunktBlock=class(TBlock)
    procedure aufbauen;override;
    procedure verschwinden;
  end;

{...}

procedure TBlock.aufbauen;
begin
  Form1.Canvas.Pen.color:=RandFarbe;
  Form1.Canvas.Brush.color:=FuellFarbe;
end;

{----------------------------------}

procedure TPunktBlock.aufbauen;
var i:Integer;
begin
  for I := 1 to 10 do
    begin
      Form1.canvas.Rectangle(i*30,15,i*30+20,30);
    end;
end;

procedure TForm1.Button1Click(Sender: TObject); //Der gleiche, wie oben
var Punktblock:TPunktblock;
begin
  Punktblock:=TPunktblock.Create;
  Punktblock.fuellFarbe:=ClGreen;
  PunktBlock.RandFarbe:=CLRed;
  Punktblock.aufbauen;
  Button1.Visible:=false;
  Timer1.Enabled:=true;
end;
Okai, Danke für eure Antworten schonmal, und dass ihr mir bei sowas helft :)
Ähhm, wenn das komplett falsch ist, könntet ihr mir dann evlt n link geben oder auch erklären??

gut, also dann,
Hoffe die Fragen sind klar gestellt :)
Aso, ja, ich müsste die ganzen Objekte am Ende noch zerstören, aber ich denke mal, das das damit nicht zusammenhängt. Ich will die dann ja auch später verschwinden lassen, wenn der Ball ihre Koordinaten berührt.

Grüße,
Halbgard

jfheins 6. Sep 2008 12:08

Re: Problem mit Ballbewegung (Anfänger)
 
AAAlso .. das mit dem Canvas der Form mag funktionieren, gut ist das aber nicht.

Eine gute Lösung ist folgendes:

1. Nimm eine Paintbox und tu sie aufs form - das ist deine Zeichenfläche

2. Deklariere im private-Bereich deines Form ein Bitmap: TBitmap;

3. Im OnCreate: Bitmap erstellen, und auf die Größe der Paintbox setzen, im OnDestroy zerstören

4. Im OnPaint der Paintbox ein Hier im Forum suchenBitblt vom Bitmap auf das Canvas der Paintbox.

5. Eine "Spielschleife" wie folgt:
Delphi-Quellcode:
procedure Form1.GameLoop()
var
  dt, lastt: Cardinal;
begin
  dt = 0;
  lastt = Gettickcount();

  while (not Application.Terminated)
  begin
    dt = Gettickcount() - lastt;
    lastt = lastt + dt;

    for each obcect in Objectlist do
      Object.anzeigen(Bitmap, dt);
    Paintbox.Refresh(dt);
    Bitmap.Clear();
    Application.Processmessages;
  end;
end;
So ähnlich zumindest - ist jetzt Pseudocode ;) (Ist jetzt etwas Quick and Dirty)

Wenn du es richtig gut machen möchtestm, solltest du die Sxchlefe in einen Thread auslagern ;)

6. Die Prozedur .anzeigen deines Balls muss dann in Abhängigkeit der Zeitdifferenz sich auf das übergebene Bitmap malen. Objects sind deine Objekte ;)

Halbgard 6. Sep 2008 12:18

Re: Problem mit Ballbewegung (Anfänger)
 
oh man..^^"
danke, ich hab zwar nur die ersten 4 Punkte verstanden (den 5. da kenn ich kaum was von), aber um das andere werd ich mich weiter belesen :)

Danke^^

Grüße,
Habgard

jfheins 6. Sep 2008 12:46

Re: Problem mit Ballbewegung (Anfänger)
 
Ok, nochmal eine kleine Skizze in Pseudocode:

Basisklasse:
Delphi-Quellcode:
TGameObject = class(TPersistent)
protected
x, y, vx, vx: Single;
Engine: TEngine;
public
procedure PaintTo(Dest: Bitmap); abstract;
procedure Step(deltaT: Cardinal); abstract;
end;

TGameCircle = class(TGameObject)
protected
radius: Integer;
Color: TColor;
public
procedure PaintTo(Dest: Bitmap); overrride;
procedure Step(deltaT: Cardinal); override;
end;

implementation

TGameCircle.PaintTo(Dest: Bitmap)
begin
  Bitmap.Canvas.Ellipse(x-radius, x+radius, y-radius, y+radius);
end;

TGameCircle.Step(deltaT: Cardinal)
begin
  x = x + vx * deltaT;
  y = y + vy * deltaT;

  //CheckForCollision(); // ggf. Kollisionserkennung ==> Änderung von vx & vy
end;
So ... du definierst also ein Gamebject und leitest davon deine Objekte ab.

Und jetzt kommt die Engine:

Delphi-Quellcode:
TEngine = class(TThread)
protected
  Dest: HDC; // Für bitblt()
  Objects: array of TGameObject;
  Bitmap: TBitmap;

  procedure OutputFrame();
  procedure Execute(); override;
public
  constructor Create(destination: HDC); override;
end;

implementation

constructor TEngine.Create(destination: HDC)
begin
  dest = destination;

  Bitmap = TBitmmap.Create();
  // Objeke erstellen
end;

procedure TEngine.Execute()
var
  lastt, dt: Cardinal;
begin
  lastt = Gettickcount() // ggf. queryperformancecounter benutzen
  dt = 0;
 
  while (not Terminated)
  begin
    Bitmap.Clear(); // Füllen mit schwarz

    for each TGameObject in Objects do
      Object.step(dt);

    for each TGameObject in Objects do
      Object.PaintTo(dt);

    synchronize(OutputFrame);

    dt = Gettickcount() - lastt;
    lastt = lastt + dt;
  end;
end;

procedure TEngine.OutputFrame()
begin // synchronized!
  BitBlt({von Bitmap nach HDC von der paintbox kopieren});
  // evtl. ein form1.Paintbox.Refresh();
end;
So, das sollte aber verständlich sein :)

Ist jetzt im Browser hinggetippt, werden also noch fehler drin sein - aber ich glaube, man erkennt wie ich das meine ^^

Halbgard 7. Sep 2008 18:59

Re: Problem mit Ballbewegung (Anfänger)
 
ah okai, jetz wirds klarer^^ danker sehr :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:48 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