Entwickler-Ecke
Multimedia / Grafik - Kreis bewegen und abprallen lassen
wayne123 - Do 27.01.11 17:11
Titel: Kreis bewegen und abprallen lassen
Also ich möchte möglichst einfach/billig einen Kreis erzeugen lassen, der sich in eine Richtung bewegt und an allen Seiten abprallt. Das ganze hab ich dann mit einer großen for-Schleife und if-then Strukturen in die for-Schleife probiert. Jetzt häng ich aber schon bei dem ersten if-then, denn wenn der Kreis unten abprallt, tut er dies auch richtig, es wird aber ein zweiter Kreis erschaffen, der weiter nach unten geht. Achja ich weiß, dass das mir refresh nicht wirklich was bringt, aber vllt. kann mir ja trotzdem jemand helfen. Das mit dem random kann man ja hoffentlich nachher noch einfügen, oder?
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: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54:
| unit UnitKreis2;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var v,x,y,z,i,j,k,l: integer; begin v:= 200; x:= 200; y:= 300; z:= 300; j:= 1; k:=1; l:=1; for i:= 1 to 1000 do begin if z+j >= Clientheight then begin refresh; l:=l+1; Canvas.Ellipse(v+k,x+j-2*l,y+k,z+j-2*l); end else refresh; Canvas.Ellipse(v+k,x+j,y+k,z+j); j:=j+1; k:=k+1; end;
end;
end. |
Regan - Do 27.01.11 17:25
Statt
Refresh einfach
Application.ProcessMessages(); einwerfen.
wayne123 hat folgendes geschrieben : |
sich in eine Richtung bewegt und an allen Seiten abprallt |
Möchtest du einen Kreis malen, der einfach innerhalb der Form herumspringt? Dann müsstest du auch die alten Kreise löschen.
guinnes - Do 27.01.11 17:26
Wenn man den Quelltext formatieren würde, würde man sehen, dass da möglicherweise ein Begin..end-BBlock fehlt
wayne123 - Do 27.01.11 17:33
Ich wollte möglichst wenig neues nehmen und eig. nur mit Canvas.Ellipse und for-Schleife und if-then arbeiten, aber wie funktioniert denn Application.ProccessMessages()? Ich hab jetzt mal mit sleep nachgeguckt, wie genau diese beiden Kreise verlaufen und hab gemerkt, dass der abprallende Kreis und der weiterlaufende Kreis sich abwechselnd einen nach vorne bewegen, nur wieso, weiß ich nicht.
Regan - Do 27.01.11 17:38
wayne123 hat folgendes geschrieben : |
wie funktioniert denn Application.ProccessMessages()? |
Du ersetzt einfach nur dieses
Refresh(); durch
Application.ProccessMessages() und dann sollte das Programm auch ordnungsgemäß neuzeichnen.
Application.ProccessMessages(); lässt das Programm Nachrichten verarbeiten (z. B. eine Zeichnung oder den Klick auf den Schließenbutton). Es friert nicht ein.
wayne123 hat folgendes geschrieben : |
nur wieso, weiß ich nicht. |
guinnes hat folgendes geschrieben : |
Wenn man den Quelltext formatieren würde, würde man sehen, dass da möglicherweise ein Begin..end-BBlock fehlt |
Und konkret:
wayne123 hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| if z+j >= Clientheight then begin Application.ProccessMessages(); l:=l+1; Canvas.Ellipse(v+k,x+j-2*l,y+k,z+j-2*l); end else Application.ProccessMessages();
Canvas.Ellipse(v+k,x+j,y+k,z+j); j:=j+1; k:=k+1; end;
| |
Ändern in:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| if z+j >= Clientheight then begin Application.ProccessMessages(); l:=l+1; Canvas.Ellipse(v+k,x+j-2*l,y+k,z+j-2*l); end else begin Application.ProccessMessages(); Canvas.Ellipse(v+k,x+j,y+k,z+j); j:=j+1; k:=k+1; end; end;
|
wayne123 - Do 27.01.11 17:45
Ohh, stimmt, jetzt ist nur noch ein Kreis da, der sich dafür gerade nach oben bewegt, aber das werd ich mir erstmal noch angucken. Nur dass Application.ProcessMessages() funktioniert nicht, denn dann sind auf einmal alle Kreise da, die insg. gezeichnet werden, was dann so ne Art Rohr ergibt.
Regan - Do 27.01.11 18:14
wayne123 hat folgendes geschrieben : |
denn dann sind auf einmal alle Kreise da, die insg. gezeichnet werden, was dann so ne Art Rohr ergibt. |
Regan hat folgendes geschrieben : |
Dann müsstest du auch die alten Kreise löschen. |
Du müsstest die ganze Canvas-Fläche wieder mit einer Farbe füllen und so die alten Kreise überschreiben. Mit
sleep(100); kannst du die Ausführung des Programmes um 100 Millisekunden anhalten, womit du dann einen schönen flüssigen Effekt erreichst ;)
wayne123 - Do 27.01.11 19:26
Das sleep nur einmal, oder einmal in der Schleife und einmal in if-then? Em, wie genau geht der Befehl fürs überzeichnen? und hier auch wieder die Frage, zweimal oder einmal?
bummi - Do 27.01.11 19:40
Ich hab Dir mal ein kleines Beispiel angehängt
wayne123 - Do 27.01.11 20:18
Da kommt bei mir ein Fehler, weil glaub ich die .res Datei fehlt. Geht das dann nur mit dieser Box oder kann man das auch ohne Box fast genauso machen?
bummi - Do 27.01.11 22:06
den Res-Fehler kannst Du ignorieren, Du kannst auf jedem Canvas malen, die Paintbox macht es Dir am einfachsten ohne eigene Komponenten oder Erweiterung bestehenden Komponenten zu arbeiten.
Eine Implementierung im OnPaint eines Forms geht ebenso einfach, im Timer dann halt z.B. Form1.Invaidate aufrufen und selbstredend das Canvas des Forms verwenden.
kwhk - Sa 29.01.11 14:24
Ich habe das Beispiele etwas überarbeitet
- der Kreis ist eine Ellipse
- das Programm läuft endlos, bis im Fenster die Maustaste gedrückt wird
- Ich benutze Delphi7, da muss Application.ProcessMessages und nicht Application.ProcessMessages() geschrieben werden. Die Klammern sind bei C++ anzugeben. Es ist eine Procedure und keine Function.
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: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Buttons;
type TForm1 = class(TForm) BitBtn1: TBitBtn; procedure BitBtn1Click(Sender: TObject); procedure FormClick(Sender: TObject); private public end;
var Form1: TForm1;
Beenden : Boolean = False; implementation
{$R *.dfm}
Procedure TForm1.BitBtn1Click(Sender: TObject); Var x,y,b,h,i,j,xa,ya: integer; Begin i := 1; j := 1; x := 100; y := 200; b := 200; h := 150; xa := x; ya := y; Canvas.Pen.Style := pssolid; Canvas.Pen.Width := 2; Canvas.Brush.Style := bssolid; Canvas.Brush.Color := Form1.Color;
While True do Begin Canvas.Pen.Color := Form1.Color; Canvas.Ellipse(xa, ya, xa+b, ya+h); Canvas.Pen.Color := clBlack; Canvas.Ellipse(x, y, x+b, y+h); xa := x; ya := y; x := x+i; y := y+j; Sleep(10); if ((x < 1) and (i < 0)) then i := 1; if ((y < 1) and (j < 0)) then j := 1; if (x+b+1) > ClientWidth then i := -1; if (y+h+1) > ClientHeight then j := -1; Application.ProcessMessages; if Beenden then Halt(1); End; End;
procedure TForm1.FormClick(Sender: TObject); begin Beenden := True; end;
End. |
Probiere es einfach mal aus ...
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!