Entwickler-Ecke

Sonstiges (Delphi) - warum prallen die Baelle nicht gegen die Wand?


xman236 - Sa 23.10.10 19:17
Titel: warum prallen die Baelle nicht gegen die Wand?

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:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
 unit mKugel;

interface

uses
mBaukasten1, mBillardtisch1, Forms, Graphics,StdCtrls,ExtCtrls;

type TKugel = class  (TKreis)

private
zZF : TForm;
zX : integer;
zY : integer;
zR : integer;
zFarbe : TColor;
zT : real;
zRT : real;
zXRichtung : real;
zYRichtung : real;
hTimer: TTimer;
public

constructor Create (Zeichenflaeche: TForm; XPos, YPos, Radius: Integer;Tempo,Richtung:Real; Farbe: TColor);
procedure bewegen(sender : TObject);
end;

type TBillardkugel = class  (TKugel)
 private
  zZF : TForm;
zX : integer;
zY : integer;
zR : integer;
zFarbe : TColor;
zT : real;
zRT : real;
zXRichtung : real;
zYRichtung : real;
hTimer: TTimer;


 public
   kKugel1,kKugel2 : TBillardkugel;
   procedure bewegen(sender : TObject);//override;
   function Abstandvon(Kugel:TBillardkugel):real;
   function Kollidiertmit(Kugel:TBillardkugel):boolean;
   procedure Abstossen(Kugel:TBillardkugel);
   procedure kennt(Kugel : TBillardkugel);
   constructor Create(Zeichenflaeche: TForm; XPos, YPos, Radius: Integer;Tempo,Richtung:Real; Farbe: TColor);
end;

implementation

constructor TKugel.Create (Zeichenflaeche: TForm; XPos, YPos, Radius: Integer;Tempo,Richtung:Real; Farbe: TColor);
begin
inherited Create(Zeichenflaeche, XPos, YPos, Radius, Farbe);
zZF:= Zeichenflaeche;
zX := XPos;
zY := YPos;
zR := Radius;
zT := Tempo;
zRT := Richtung;
zFarbe := Farbe;
zXRichtung := cos(0.017453292*zRT)*zT ;
zYRichtung := sin(0.017453292*zRT)*zT ;

hTimer := TTimer.Create(nil);
hTimer.Enabled := False;
hTimer.Interval := 5;
hTimer.OnTimer := bewegen;

end;

constructor TBillardKugel.Create (Zeichenflaeche: TForm; XPos, YPos, Radius: Integer;Tempo,Richtung:Real; Farbe: TColor);
begin
 inherited Create(Zeichenflaeche, XPos, YPos, Radius,Tempo,Richtung, Farbe);
zZF:= Zeichenflaeche;
zX := XPos;
zY := YPos;
zR := Radius;
zT := Tempo;
zRT := Richtung;
zFarbe := Farbe;
zXRichtung := cos(0.017453292*zRT)*zT ;
zYRichtung := sin(0.017453292*zRT)*zT ;

hTimer := TTimer.Create(nil);
hTimer.Enabled := False;
hTimer.Interval := 5;
hTimer.OnTimer := bewegen;
end;

procedure TKugel.bewegen(sender : TObject);
var
zXReal : real;
zYReal : real;
begin

zXReal := LiesXposition;
zYReal := LiesYposition;

zXRichtung := cos(0.017453292*zRT)*zT ;
zYRichtung := sin(0.017453292*zRT)*zT ;

zXReal     := zXReal+zXRichtung;
zYReal     := zYReal+zYRichtung;

if(zXReal+zR>=zZF.clientwidth)
  then
 begin
  zXRichtung:=-zXRichtung;
  end;
if(zXReal-zR<=0)
  then
 begin
  zXRichtung:=-zXRichtung;
  end;
if(zYReal+zR>=zZF.Clientheight)
  then
 begin
  zYRichtung:=-zYRichtung;
  end;
if(zYReal+zR>=0)
  then
 begin
  zYRichtung:=-zYRichtung;
  end;

SetzePosition(Round(zXReal),Round(zYReal));

end;

 function TBillardkugel.Abstandvon(Kugel:TBillardkugel):real;
   var
    Xreal,Yreal:integer;
   begin
    Xreal:= zX-Kugel.LiesXPosition;
    Abstandvon:=sqrt((Xreal*Xreal)+(Yreal*Yreal))
   end;

   procedure TBillardkugel.Abstossen(Kugel:TBillardkugel);
   var
    XKugel,YKugel : real;
   begin
    XKugel:=Kugel.zXRichtung;
    YKugel:=Kugel.zYRichtung;
    Kugel.zXRichtung:=self.zXRichtung;

    Kugel.zYRichtung:=self.zYRichtung;
    self.zXRichtung:=xKugel;
    self.zYRichtung:=YKugel;

   end;

   procedure TBillardkugel.kennt(Kugel : TBillardkugel);
   begin
    if(kKugel1=nil)
     then kKugel1:=Kugel
     else kKugel2:=Kugel;
   end;

   function TBillardkugel.Kollidiertmit(Kugel:TBillardkugel):boolean;
    begin
     if Abstandvon(Kugel)<2*zR
      then Kollidiertmit := true
      else Kollidiertmit := false;

     end;


   procedure TBillardkugel.bewegen;
    begin
     if kKugel1<>nil
     then
      if (Kollidiertmit(kKugel1)=true)
      then Abstossen(kKugel1);
      inherited bewegen(kKugel2);
     if kKugel2<>nil
     then
      if (Kollidiertmit(kKugel2)=true)
      then Abstossen(kKugel2) ;

     inherited bewegen(kKugel2);
    end;



end.


Das ist meine ganze Kugel Klasse.
Also die Baelle muessen gegen die Waende und auch gegenseitig abprallen, aber
die Baelle prallen nicht mals gegen die Wand, sondern gehen durch die Wand!!
Kann einer mir helfen?

Moderiert von user profile iconGausi: Quote- durch Delphi-Tags ersetzt


Delete - Sa 23.10.10 19:47

Hast du das ganze schon mal debuggt und dir die Werte mal angeguckt, was da überhaupt drin steht?


xman236 - Sa 23.10.10 19:53

das Programm laeuft eigentlich super. Das einzige Problem ist dass die Baelle
nicht gegen die Wand abprallen.
Meinst du mit den Werten Tempo, Geschwindigkeit und Radius?


Delphi-Laie - Sa 23.10.10 19:58

user profile iconxman236 hat folgendes geschrieben Zum zitierten Posting springen:
das Programm laeuft eigentlich super. Das einzige Problem ist dass die Baelle
nicht gegen die Wand abprallen.


Bälle können nicht gegen eine Wand abprallen, sondern nur gegen eine Wand prallen oder von dieser abprallen. Das nur nebenbei.

user profile iconxman236 hat folgendes geschrieben Zum zitierten Posting springen:
Meinst du mit den Werten Tempo, Geschwindigkeit und Radius?


Auch wenn "Tempo" n.m.W. wörtlich übersetzt Zeit bedeutet, so wird hierzulande doch eher synonym für Geschwindigkeit verwandt. Was ist demnach der Unterschied zwischen Tempo und Geschwindigkeit?

user profile iconxman236 hat folgendes geschrieben Zum zitierten Posting springen:
if (Kollidiertmit(kKugel1)=true)


Ein Vergleich mit true ist Redundanz bis Unfug, weil mit "if" schon der Wahrheitsgehalt gefragt bzw. geprüft wird.


xman236 - Sa 23.10.10 20:07

sorry ich habe vertippt. Ich wollte Richtung hinschreiben.


Delphi-Laie - Sa 23.10.10 20:09

user profile iconxman236 hat folgendes geschrieben Zum zitierten Posting springen:
sorry ich habe vertippt. Ich wollte Richtung hinschreiben.


Danke für die Richtigstellung! Eine - sicher nicht essentielle, weil nicht zu Fehlern führende - Kleinigkeit fand ich noch (editierte meinen vorigen Beitrag).


xman236 - Sa 23.10.10 20:17

Die Stelle, die du erwaehnst, hat mit der Prallung gegenseitig zu tun.
Ich habe die Quelle, die nicht mit der Prallung gegen die Wand zu tun hat, weggemacht.


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:
unit mKugel;

interface

uses
mBaukasten1, mBillardtisch1, Graphics,StdCtrls,ExtCtrls;

type TKugel = class  (TKreis)

private
zZF : TFrmBillardtisch1;
zX : integer;
zY : integer;
zR : integer;
zFarbe : TColor;
zT : real;
zRT : real;
hTimer: TTimer;
public

constructor Create (Zeichenflaeche: TFrmBillardtisch1; XPos, YPos, Radius: Integer;Tempo,Richtung:Real; Farbe: TColor);
procedure bewegen(sender : TObject) ;
end;

implementation

constructor TKugel.Create (Zeichenflaeche: TFrmBillardtisch1; XPos, YPos, Radius: Integer;Tempo,Richtung:Real; Farbe: TColor);
begin
inherited Create(Zeichenflaeche, XPos, YPos, Radius, Farbe);
zZF:= Zeichenflaeche;
zX := XPos;
zY := YPos;
zR := Radius;
zT := Tempo;
zRT := Richtung;
zFarbe := Farbe;

hTimer := TTimer.Create(nil);
hTimer.Enabled := False;
hTimer.Interval := 5;
hTimer.OnTimer := bewegen;
end;

procedure TKugel.bewegen(sender : TObject)      ;

var
zXRichtung : real;
zYRichtung : real;
zRT : real ;
zT : real;
zXReal : real;
zYReal : real;
begin

zXReal := LiesXposition;
zYReal := LiesYposition;

zXRichtung := cos(0.017453292*zRT)*zT ;
zYRichtung := sin(0.017453292*zRT)*zT ;

zXReal     := zXReal+zXRichtung;
zYReal     := zYReal+zYRichtung;

SetzePosition(Round(zXReal),Round(zYReal));

end;



end.


Moderiert von user profile iconMartok: Quote- durch Delphi-Tags ersetzt


Delphi-Laie - Sa 23.10.10 20:23

Ich kann und werde mich nicht in Deine Unit hineindenken, geschweige denn, hineinversetzen.

Das wesentliche beim (Ab)Prallen ist allerdings, daß es sich um eine Reflexion (bzw. das mechanische/kinematische Pendant zur optischen Reflexion) handelt, und es gilt: Eintrittswinkel=Austrittswinkel (egal, ob von bzw. zur Wand oder der Orthogonale, die die Wand an der Prallstelle berührt, betrachtet oder gemessen).

Du mußt demnach - bei konstanter Geschwindigkeit, denn im Idealfalle geht keine mechanische, konkret kinetische Energie verloren - den Winkel, also die Kugelrichtung entsprechend genau zum bzw. ab dem Prallzeitpunkt verändern.


Flamefire - Sa 23.10.10 21:28

Und zu deinem Problem: Du hast deinen obigen Code genau auf den relavanten Teil gekürzt. Alles was sonst noch drin stand, hatte (zumindest für die Bewegung) keinerlei Bedeutung.
Und damit solltest du deinen Fehler schon sehen.

Konkret: Entscheide dich, wie du die Bewegungsrichtung abspeicherst. So ist das Unfug.