Autor |
Beitrag |
InformatikWurst
Hält's aus hier
Beiträge: 4
|
Verfasst: Fr 21.01.11 13:46
Ahoi Delphi-Community,
da ich bereits seit gefühlten 5 tagen versuche mein Programm zu erstellen ohne bisher zum Ergebnis gekommen zu sein,dachte ich mir,ich könne mich ja mal in diesem Forum anmelden um evt. hier die nötige Hilfe zu finden.
Da ich jemandem etwas zeigen möchte,indem ich es leicht vereinfacht darstelle,möchte ich in Delphi mit einem Image mehrere Kreise in 3 verschiedenen Farben bewegen.Das simulationsprogramm soll zeigen,dass sich diese Kreise zufällig bewegen,doch wenn sich 2 stück mit unterschiedlicher Farbe berühren,stoßen sie sich ab und nehmen die dritte Farbe an und so soll das dann weitergehen...
Also ich stecke derzeit als Delphi-Neuling noch bei der Bewegung fest -.-
Ich schaffe es eine Kugel in einer Farbe zum bewegen zu bringen,sobald ich das aber mit mehreren versuche geht es ,egal wie ich es versuche, nicht mehr(entweder bewegt sich nur eine,oder das programm hängt sich auf).Wenn ich dann auch noch die Farben mit einbeziehen muss und noch den zusammenstoß und farbwechsel simulieren soll,bin ich glaube doch ein wenig überfordert^^
Also bisher sieht mein Quelltext wie folgt aus (sry,kriege igwie kein spoiler hin oO):
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: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77:
| unit kreisbewegung;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type TForm1 = class(TForm) Image1: TImage; Timer1: TTimer; Schliessenbutton: TButton; beginnbutton: TButton; procedure SchliessenbuttonClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure beginnbuttonClick(Sender: TObject); private public end;
var Form1: TForm1; x,y,y1,x1,dx,dx1,a:integer; implementation {$R *.dfm}
procedure TForm1.SchliessenbuttonClick(Sender: TObject); begin close; end;
procedure TForm1.FormCreate(Sender: TObject); begin randomize; a:= 1; repeat begin x:= random(499)+1; dx:=random(5)+1; y:= random(499)+1; dx1:=random(5)+1;
with image1.Canvas do begin pen.Width:=5; Pen.Color:=clblack; ellipse(x,y,x+6,y+6); end; a:=a+1; end; until a=4; end;
procedure TForm1.beginnbuttonClick(Sender: TObject); begin
with image1.Canvas do begin pen.Width:=5; Pen.Color:=clwhite; ellipse(x,y,x+6,y+6); end;
if (x>500) or (x<1) then dx:=-dx; x:=x+dx; if (y>500) or (y<1) then dx1:=-dx1; y:=y+dx1;
with image1.Canvas do begin pen.Width:=5; Pen.Color:=clblack; ellipse(x,y,x+6,y+6); end; end; end. |
Wär schön,wenn ihr mir igwie helfen könnt.Vielleicht habt ihr irgendwelche Vorschläge,oder könnt mir sagen,was ich falsch mache >.<
mfg InfoWurst
€dit: also ich glaube,wenn ich das zb mit 45 kugeln simulieren will,bräuchte ich für diese kugeln ein array,oder?
ach..ich komm einfach nich weiter >.<
Moderiert von Martok: Quote- durch Delphi-Tags ersetzt
Moderiert von Martok: Topic aus Sonstiges (Delphi) verschoben am Fr 21.01.2011 um 12:52
|
|
Xion
      

Beiträge: 1952
Erhaltene Danke: 128
Windows XP
Delphi (2005, SmartInspect), SQL, Lua, Java (Eclipse), C++ (Visual Studio 2010, Qt Creator), Python (Blender), Prolog (SWIProlog), Haskell (ghci)
|
Verfasst: Fr 21.01.11 15:34
_________________ a broken heart is like a broken window - it'll never heal
In einem gut regierten Land ist Armut eine Schande, in einem schlecht regierten Reichtum. (Konfuzius)
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Fr 21.01.11 17:41
Kollision ist unproblematisch
statt FigReg dann halt 2 CircleReg's
haariger wird es IMHO mit der Entscheidung was bei einer Kollision zu tun ist, schon beim Erzeugen überlappungen vorhanden? , was wenn mehrere Bälle gleichzeitig kollidieren, was bei Kollisionen mit Seiten und Bällen gleichzeitig etc...
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| procedure TForm1.Button1Click(Sender: TObject); var FigReg,CircleReg:HRGN; begin Figure1[0].X := 0; Figure1[0].Y := 0; Figure1[1].X := 50; Figure1[1].Y := 0; Figure1[2].X := 50; Figure1[2].Y := 50; Figure1[3].X := 25; Figure1[3].Y := 75; Figure1[4].X := 0; Figure1[4].Y := 50; FigReg := CreatePolygonRgn(Figure1,5,WINDING); CircleReg := CreateEllipticRgn(30,30,100,100); if not (CombineRgn(FigReg,FigReg,CircleReg,RGN_AND)=NULLREGION) then Showmessage('Collision'); SetWindowrgn(Panel1.Handle,FigReg,true); Deleteobject(FigReg); Deleteobject(CircleReg); end; |
EDIT:
Nimm statt eines Images lieber eine Paintbox..
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
InformatikWurst 
Hält's aus hier
Beiträge: 4
|
Verfasst: Mo 24.01.11 15:03
danke erstmal für die beiden antworten und sry,dass ich nicht gleich antworten konnte,hatte noch viel zu tun in letzter zeit.Hoffe,dass ich jetzt mich öfter dran setzen kann.
@bummi: naja also ganz ehrlich wirds langsam seeeeehr kompliziert,ich hab vorher schon nicht so richtig durchgeblickt,doch spätestens bei deinem beitrag hörts glaub auf >.< mit image könnt ich noch so halbwegs umgehen,aber was ist eine paintbox und wie benutz ich die? ach und warum die kollision in nem extra buttonclick?die sollen ja automatisch igwann kollidieren,nicht erst beim drücken des buttons,oder geht das dank des timers automatisch?
@Xion: wegen deiner schleife zum bewegen der kugeln,funktioniert das denn so?weil ich dachte man muss da immer dieses dx etc. mit einbeziehen (siehe erster post),du hast da ja nur igwas mit pos und speed oder so ?
naja ich versuch jetzt mal eure beiden vorschläge igwie zu verbinden,mal schaun was bei rauskommt
ok..hab jetzt erstmal versucht Xion seine Vorschläge zu verwenden..doch ich glaube,da ich ständig fehlermeldungen bekomme,gehe ich mal stark davon aus,dass ich da igwas noch falsch habe...
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:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
type TForm1 = class(TForm) Timer1: TTimer; Image1: TImage; Button1: TButton; Button2: TButton; procedure Button2Click(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure Button1Click(Sender: TObject);
TKugel=record Pos: TPoint; Speed: TPoint; Color: TColor; end; private public end;
var Kugeln:array[0..45] of TKugel; K:integer; Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button2Click(Sender: TObject); begin close; end;
procedure TForm1.Button1Click(Sender: TObject); begin for K:= 0 to 45 do ellipse(Kugeln[K].Pos.X-3,Kugeln[K].Pos.Y-3,Kugeln[K].Pos.X+3,Kugeln[K].Pos.X+3);
for K:= 0 to 45 do begin Kugeln[K].Pos.X:=Kugeln[K].Pos.X+Kugeln[K].Speed.X; Kugeln[K].Pos.Y:=Kugeln[K].Pos.Y+Kugeln[K].Speed.Y; end;
end;
end. |
naja..hoffe ihr könnt mir nochmal igwie helfen
danke und mfg InfoWurst
|
|
InformatikWurst 
Hält's aus hier
Beiträge: 4
|
Verfasst: Fr 04.03.11 13:34
sooo..sry,dass ich ne ganze weile nicht da war..war zeitlich sehr stark beschränkt ...
habe es nun aber doch endlich mal hinbekommen das programm komplett zu programmieren,allerdings stört mich noch eine sache,worauf mir so spontan einfach keine antwort einfällt.Nahezu immer kommt es vor,dass etwa 2/3mal 2 kugeln zusammenstoßen ,aber dann aneinanderkleben ohne sich abzustoßen oO
Falls jemand weiß,woran das liegt,dann mal bitte melden,wär schön,wenn auch dieser kleine makel noch beseitigt wäre =)
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: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97:
| unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type Kugel = Record x,y,vx,vy:Integer; c:Tcolor; end; TForm1 = class(TForm) Button1: TButton; Image1: TImage; Button2: TButton; Button3: TButton; Timer1: TTimer; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure FormCreate(Sender: TObject); private public Procedure ball(var vx,vy:Integer;x,y:Integer;c:Tcolor); end; var Kugeln : Array[1..45] of Kugel; Form1: TForm1; implementation {$R *.dfm} procedure TForm1.ball(var vx,vy:Integer;x,y:Integer;c:Tcolor); begin image1.Canvas.Pen.Color:=c; image1.Canvas.Brush.Color:=c; image1.Canvas.Ellipse(x+10,y+10,x-10,y-10); end; procedure TForm1.Button1Click(Sender: TObject); begin close; end; procedure TForm1.Button2Click(Sender: TObject); var i,j:Integer; begin image1.Canvas.Pen.Color:=clwhite; image1.Canvas.Brush.Color:=clwhite; image1.Canvas.Rectangle(0,0,Image1.Width,Image1.Height); for i:=1 to 45 do begin kugeln[i].x:=kugeln[i].x+kugeln[i].vx; kugeln[i].y:=kugeln[i].y+kugeln[i].vy; ball(kugeln[i].vx,kugeln[i].vy,kugeln[i].x,kugeln[i].y,kugeln[i].c); end; for i:=1 to 45 do begin if kugeln[i].x > image1.Width-10 then kugeln[i].vx:=-kugeln[i].vx; if kugeln[i].x < 10 then kugeln[i].vx := -kugeln[i].vx; if kugeln[i].y > image1.Height-10 then kugeln[i].vy := -kugeln[i].vy; if kugeln[i].y < 10 then kugeln[i].vy := -kugeln[i].vy; end; for i:=1 to 45 do begin for j:=i to 45 do begin if sqrt(sqr( kugeln[i].x-kugeln[j].x)+sqr(kugeln[i].y-kugeln[j].y)) <= 20 then begin kugeln[i].vx:=-kugeln[i].vx ; kugeln[i].vy:=-kugeln[i].vy ; kugeln[j].vx:=-kugeln[j].vx ; kugeln[j].vy:=-kugeln[j].vy ; if (kugeln[i].c=clred) and (kugeln[j].c=clgreen) then begin kugeln[i].c:=clyellow; kugeln[j].c:=clyellow end; if (kugeln[i].c=clgreen) and (kugeln[j].c=clred) then begin kugeln[i].c:=clyellow; kugeln[j].c:=clyellow end; if (kugeln[i].c=clred) and (kugeln[j].c=clyellow) then begin kugeln[i].c:=clgreen; kugeln[j].c:=clgreen end; if (kugeln[i].c=clyellow) and (kugeln[j].c=clred) then begin kugeln[i].c:=clgreen; kugeln[j].c:=clgreen end; if (kugeln[i].c=clyellow) and (kugeln[j].c=clgreen) then begin kugeln[i].c:=clred; kugeln[j].c:=clred end; if (kugeln[i].c=clgreen) and (kugeln[j].c=clyellow) then begin kugeln[i].c:=clred; kugeln[j].c:=clred end; end; end; end; timer1.enabled:=true; end; procedure TForm1.Button3Click(Sender: TObject); var i,f:Integer; begin for i:=1 to 45 do begin kugeln[i].vx:=random(2)+1; kugeln[i].vy:=random(2)+1; kugeln[i].x:=Random(image1.Width-10)+1; kugeln[i].y:=Random(image1.Height-10)+1; f:=random(3)+1; case f of 1: kugeln[i].c:=clred; 2: kugeln[i].c:=clyellow; 3: kugeln[i].c:=clgreen; end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin randomize; end; end. |
|
|
Jakob_Ullmann
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: Fr 04.03.11 19:34
Sorry, ich weiß nicht, ob ich es jetzt einfach übersehen habe, aber für mich sah diese Kollision unnötig kompliziert aus. Ich würde folgende Bedingung vorschlagen: Der Abstand der Mittelpunkte ist kleiner oder gleich dem doppelten Kreisradius (oder bei unterschiedlichen Größen der Summe der Radii).
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| für alle Kreise k1: für alle Kreise k2: falls (k1 <> k2) und ((k1.X - k2.X)² + (k1.Y - k2.Y)² > (k1.Radius + k2.Radius)²): falls (k1.Farbe <> k2.Farbe): neueFarbe = not (k1.Farbe or k2.Farbe) neueFarbe = (neueFarbe and 1) + (neueFarbe and 2) shl 1 + (neueFarbe and 4) shl 2; |
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Fr 04.03.11 20:33
Ich kann auf dem Handy leider nicht scrollen in eingebetteten Containern, deshalb weiß ich nicht, was welcher Code genau macht. Aber bei deiner Beschreibung fehlt irgendwie der Bewegungsvektor.
Schließlich musst du ja auch wissen in welche Richtung die Kugeln abprallen.
|
|
Jakob_Ullmann
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: Sa 05.03.11 14:20
Bezüglich Kollision: Es wäre sicher auch einfacher (aus Gründen der Eindeutigkeit), nicht den Vektor, sondern den Winkel abzuspeichern. Aus dem Winkel kann der Geschwindigkeitsvektor (mit konstantem Betrag, versteht sich) eindeutig bestimmt werden. Aus dem Vektor kann man zwar auch eindeutig den Winkel bestimmen, allerdings wird dann die Umsetzung schwieriger, wegen der Periodizität der trigonometrischen Funktionen. Und für die Kollision braucht man nun einmal den Winkel.
gestrichelte Linie: 0° [Vektor 1*i+0*j]. Größere Winkel im math. pos. Drehsinn.
Ich kann nicht ausschließen, dass ich mich irgendwo vertan habe, aber ich denke, das müsste so stimmen.
Einloggen, um Attachments anzusehen!
|
|
InformatikWurst 
Hält's aus hier
Beiträge: 4
|
Verfasst: Mo 07.03.11 14:56
oh man...das erscheint mir viel zu kompliziert,ich lass es lieber vorerst so wie es ist...
bin nicht sonderlich gut im programmieren,also bitte keine so umständlichen antworten^^
stehe aber grade vor dem nächsten problem,im unterricht soll ich mein programm jetzt igwie mit OOP oder so programmieren(objektorientierte programmierung),aber davon hab ich noch nie etwas gehört und das internet hilft mir auch nicht sonderlich weiter...
könnte mir jemand sagen,was ich da jetzt ändern muss,damit es igwie in OOP ist ? oO
|
|
gnomecoder
      
Beiträge: 51
Erhaltene Danke: 5
|
Verfasst: Mo 07.03.11 23:52
www.delphi-treff.de/...klassen-und-objekte/
statt dem record benutzt du dann eine klasse usw...
sollte ohne viel aufwand umzuschreiben sein.
|
|
|