Autor Beitrag
InformatikWurst
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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):

ausblenden volle Höhe 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:
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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  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>500or (x<1then dx:=-dx;
  x:=x+dx;
  if (y>500or (y<1then 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 user profile iconMartok: Quote- durch Delphi-Tags ersetzt
Moderiert von user profile iconMartok: Topic aus Sonstiges (Delphi) verschoben am Fr 21.01.2011 um 12:52
Xion
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
EE-Maler
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)
BeitragVerfasst: Fr 21.01.11 15:34 
Mal ein Grobkonzept:

Records
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
type TKugel=record
  Pos: TPoint;
  Speed: TPoint;
  Color: TColor;
end;


Arrays
ausblenden Delphi-Quelltext
1:
Kugeln: array [0..45of TKugel;					


Zeichnen als Schleife
ausblenden Delphi-Quelltext
1:
2:
for K:= 0 to High(Kugeln) do
  ellipse(Kugeln[K].Pos.X-3,Kugeln[K].Pos.Y-3,Kugeln[K].Pos.X+3,Kugeln[K].Pos.X+3);


Bewegen als Schleife
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
for K:= 0 to High(Kugeln) 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;


Das schwierigste wird wohl die Kollission, weil gerade Kollission von 2 Kreisen(!) ist fies. Mit Rechtecke gings leichter ;) .

_________________
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: 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...
ausblenden 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); // Anzeige des Ergebnisses
    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 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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 :D

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...

ausblenden volle Höhe 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:
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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
Kugeln:array[0..45of 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 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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:

ausblenden volle Höhe 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:
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
    { Private-Deklarationen }
  public
    Procedure ball(var vx,vy:Integer;x,y:Integer;c:Tcolor);
    { Public-Deklarationen }
  end;
var
  Kugeln : Array[1..45of 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: 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).

ausblenden 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)²):
        // Kollisionsbewegung
        // ...
        {Vorschlag für die Farbwahl: nimm die letzten Ziffern
         einer Binärzahl: 001   010   100   als Farben}

        falls (k1.Farbe <> k2.Farbe):
          neueFarbe = not (k1.Farbe or k2.Farbe)  // dasselbe (not F1) and (not F2)
          neueFarbe = (neueFarbe and 1) + (neueFarbe and 2shl 1 + (neueFarbe and 4shl 2;
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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. :gruebel:

Schließlich musst du ja auch wissen in welche Richtung die Kugeln abprallen.
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: 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.

kollision-kugeln
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 Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 51
Erhaltene Danke: 5



BeitragVerfasst: 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.