Einzelnen Beitrag anzeigen

Benutzerbild von d3g
d3g

Registriert seit: 21. Jun 2002
602 Beiträge
 
#17
  Alt 21. Nov 2002, 17:23
Hallo Raiden,

der Grund, warum sich der Ball nicht bewegt, ist, dass du die Variable i zwar global deklarierst, aber bei jedem Timerdurchlauf wieder auf 1 setzst. Eine Variable i ist aber ohnehin der falsche Weg, da die Position eines Balles nicht eindimensional, sondern zweidimensional ist. Du kannst also eine Variable pos vom Typ TPoint einführen (TPoint ist ein [packed] Record mit zwei Intergervariablen, x und y). Dieser speichert die Position des Balles.
Code:
[b]var[/b]
  pos: TPoint = (x: 0; y: 0);
Wenn du jetzt deine Funktion ausführst, wirst du erkennen, dass der Ball einen "Kondensstreifen" hinterlässt, da die alte Position des Balles nicht übermalt wird. Du musst also ein
Code:
PaintBox1.Repaint;
vor dem Zeichnen einbauen, damit ist der Fehler behoben.

Jetzt prallt der Ball leider noch nicht von den Seiten ab. Um das zu realisieren, führe zei neue Integervariablen vx und vy ein:
Code:
[b]var[/b]
  vx: Integer = 1;
  vy: Integer = 1;
Der Trick besteht darin, dass diese Variablen mit dx bzw. dy multipliziert werden. Hier passiert (weil vx und vy noch 1 sind) nichts. Nach dem Zeichnen wird dann aber überprüft, ob der Ball gerade an einer Wand ist. wenn an der linken oder rechten, wird vx mit -1 multipliziert, an der oberen und unteren vy mit -1. Jetzt passiert beim nächsten Zeichnen folgendes: Nehmen wir an dx beträgt 8, der Ball sollte also um 8 Pixel nach rechts verschoben werden. Jetzt wird dx mit -1 multipliziert und damit wird der Ball um -8 Pixel nach rechts, also 8 Pixel nach links verschoben - das Abprallen ist perfekt. Analog dazu verhält sich die Beziehung zwischen vy und dy.

Die gesamte Funktion könnte jetzt so aussehen:
Code:
[b]var[/b]
  pos: TPoint = (x: 0; y: 0);
  vx: Integer = 1;
  vy: Integer = 1;

[b]procedure[/b] TForm1.Timer1Timer(Sender: TObject);
[b]begin[/b]
  dx := vx * round(cos(winkel * Pi / 180) * r);
  dy := vy * round(sin(winkel * Pi / 180) * r);
  Inc(pos.x, dx);
  Inc(pos.y, dy);
  PaintBox1.Repaint;
  PaintBox1.Canvas.Draw(pos.x, pos.y, a);
  [b]if[/b] ((pos.x + a.Width >= PaintBox1.Width) [b]or[/b]
      (pos.x <= 0))
  [b]then[/b]
    vx := -vx;

  [b]if[/b] ((pos.y + a.Height >= PaintBox1.Height) [b]or[/b]
      (pos.y <= 0))
  [b]then[/b]
    vy := -vy;
[b]end[/b];
Ich habe die beiden FloatToStr-Anweisungen in die BitBtn1Click-Prozedur verschoben, da r und winkel nur einmal eingelesen werden müssen.

Ab hier darfst du selber weiterdenken, jetzt dürfte es nicht mehr so schwierig sein, zwei Paddles einzubauen.

MfG,
d3g

PS. Ich würde die Grafik niht von H:\ball.bmp laden, sondern in einem relativen Pfad, weil es bei anderen Rechnern, auf denen H:\ nicht existiert, Probleme gibt.

[edit]Tippfehler korrigiert.[/edit]
-- Crucifixion?
-- Yes.
-- Good. Out of the door, line on the left, one cross each.
  Mit Zitat antworten Zitat