Entwickler-Ecke

Sonstiges (Delphi) - "Torwart"


julian2304 - Di 09.01.07 17:13
Titel: "Torwart"
Hallo!
Ich brauche Hilfe beim Erstellen eines "Torwartprogramms".

Ein Button soll in der unteren Bildschirmhälfte als Torwart dienen. Das hab ich auch schon hinbekommen :)
Nur jetzt soll der zweite Button (der Ball) an dem ersten Button (dem Torwart) abprallen wenn er ihn trifft. Das hab ich nicht hinbekommen ^^

Danke für eure Hilfe!


Quelltext:


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

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button: TButton;
    Timer1: TTimer;
    Button_start: TButton;
    Button1: TButton;
    procedure Button_startClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);

  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;



implementation
Var
 vx:integer;
 vy:integer;
 vz:integer;
 vw:integer;

{$R *.DFM}

procedure TForm1.Button_startClick(Sender: TObject);
begin
 vw:=5;
 vx:=-1;
 vy:=1;
 vz:=-5;

Timer1.Enabled:=True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
Button.left:=Button.left+vx;
Button.top:=button.top+vz;
  If Button.left<0
  Then
    begin
     button.left:=-button.left;
     vx:=-vx;
end;
  If Button.left>660
  Then
    begin
     button.left:=-button.left;
     vy:=-vy;
end;


  If Button.top<0
   then
     begin
      button.top:=-button.top;
      vz:=-vz;
end;
   If button.top>form1.height-55
    then
      begin
       button.top:=-button.top;
       vw:=-vw;
end;

end;

procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
begin
  
 if x>31
  then
   begin
    button1.left:=button1.left+2;
   end;
 if x<29
  then button1.left:=button1.left-2;

   end;
  end.


Gintonik - Di 09.01.07 17:19

Möchtest du ein Ping-Pong programmieren? Diesen klassichen Arcadeklassiker Break-Out oder so?


.50AE - Di 09.01.07 17:36

Hi,

Wieso du einen Button nimmst frag ich jetzt mal nicht ;-)


Delphi-Quelltext
1:
button.left:=-button.left;                    

Wieso das? Nur die "Geschwindigkeit" umzukehren würde vollkommen genügen.

Wenn du die Koordinatenabfragen (x und y) alle in einzelne If-Statements packst, funktioniert das ganze in der Regel nicht..

Deine Kollisionsabfrage sollte dann etwa so aussehen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
if ((bBall.Top+bBall.Height > bBlocker.Top) and (bBall.Top<bBlocker.top+bBlocker.Height)) 
  and
  ((bBall.Left < bBlocker.Left+bBlocker.Width) and (bBall.Left+bBall.Width > bBlocker.Left)) then 
 begin
 vy := -vy;
 end;

Wenn der "Ball"Button auch schräg fliegen kann (überlagerung mit einer horizontalen Geschwindigkeit) könntest du auch noch prüfen, ob der Ball von links/rechts an den Button prallt und dann die horizontale Geschwindigkeit ebenfalls umkehren.

An deiner Stelle würde ich statt Buttons aber auf TShape Komponenten zurückgreifen oder gleich Bilder einfügen..

Falls da ein PingPong Spiel draus werden soll wäre es noch besser "bBlocker" durch eine Variable zu ersetzen und das Ganze in eine Prozedur Kollision(Objekt: TObject); oder ähnliches zu packen. Dann kannst du gleich noch Wände und Hindernisse dazusetzen und musst nur für jedes Objekt auf dem Spielfeld die Prozedur aufrufen.

Viel Glück,
50ae


JayEff - Di 09.01.07 17:59


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
Var
    Form1: TForm1;
    vx, vy: integer;

Implementation

{$R *.dfm}

Procedure TForm1.FormCreate(Sender: TObject);
Begin
    vx := 1;
    vy := 5;
End;

Procedure TForm1.Timer1Timer(Sender: TObject);
Begin
    Button2.Top := Button2.Top + vy;
    Button2.Left := Button2.Left + vx;
    If (Button2.Top + Button2.Height >= Button1.Top) and ((Button2.Left < Button1.Left+Button1.Width) and (Button2.Left+Button2.Width > Button1.Left)) Then
        vy := -vy;
End;

Wie .50AE gesagt hat, so gehts. Beim ausführen von ButtonX.top:=-ButtonX.Top; wird die Position des Buttons einfach aus dem Bildschirm gesetzt (- Koordinaten sind immer irgendwo links oder oberhalb der Formgrenze), und das ist sicher nicht in deinem Sinne!

Ausserdem noch ne Kleinigkeit zur Formatierung: zusammengehörende Begin-Ends setzt man normalerweise auf die gleiche Höhe. Dein Code 1:1 kopiert und ... naja, nach meiner Vorstellung formatiert, sähe so aus:

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:
Procedure TForm1.Button_startClick(Sender: TObject);
Begin
    vw := 5;
    vx := -1;
    vy := 1;
    vz := -5;

    Timer1.Enabled := True;
End;

Procedure TForm1.Timer1Timer(Sender: TObject);
Begin
    Button.left := Button.left + vx;
    Button.top := Button.top + vz;
    If Button.left < 0 Then
    Begin
        Button.left := -Button.left;
        vx := -vx;
    End;
    If Button.left > 660 Then
    Begin
        Button.left := -Button.left;
        vy := -vy;
    End;

    If Button.top < 0 Then
    Begin
        Button.top := -Button.top;
        vz := -vz;
    End;
    If Button.top > Form1.height - 55 Then
    Begin
        Button.top := -Button.top;
        vw := -vw;
    End;

End;

Procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
    Y: integer);
Begin

    If X > 31 Then
    Begin
        Button1.left := Button1.left + 2;
    End;
    If X < 29 Then
        Button1.left := Button1.left - 2;
End;

Und nochwas: Wenn du etwas wie

Delphi-Quelltext
1:
2:
3:
4:
5:
Var 
 vx:integer; 
 vy:integer; 
 vz:integer; 
 vw:integer;

hast, kannst du es vielleicht übersichtlicher zusammenfassen:

Delphi-Quelltext
1:
2:
Var 
   vx, vy, vz, vw:integer;


Dragon06 - Mi 10.01.07 17:19

ich bin im gleichen informatik-kurs wie julian2304 und komme an der stelle jetzt nich weiter!

wie kriege ich es hin, dass der "ball" an meinem beweglichen Button abprallt (am besten an alle seiten)?

wäre nett wenn mir wer helfen könnte, da wir das programm bis morgen anfertigen sollen ^^

mfg


Dragonclaw - Mi 10.01.07 18:35


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
     _____   _____
    |__1__| |__2__|
<-----a---->|
<-----b-->|

a = Button2.left
b = Button1.left + Button1.width  

Kollision wenn
a <= b


Genau das selbe gilt natürlich für rechts oben und unten.


julian2304 - Mi 10.01.07 18:36

@ Dragonclaw

hä?
das versteh ich nicht?
wie muss den der quelltext jetzt aussehen?


Raffo - Mi 10.01.07 18:37

Kleiner Spass beiseite, Du meinst, Du musst es morgen abliefern? Bei Deinem Lehrer? Hey, wir haben 1985 einfache Matheaufgaben mit dieser Super-Wahnsinnig-Rechenmaschine ausführen müssen. Hausausgaben für dieses Fach wurden noch nicht mal erfunden...

Dennoch habe ich damals ein AUSREICHEND bekommen, nämlich durch meinen EINSATZ, weil ich schon damals weit mehr konnte als die anderen, ja ich sage sogar: ICH BIN DARIN GEBOREN, und der Lehrer hat mich voll verarscht, weil er es nicht abkonnte, das ich sogar damals schon versucht habe, so was ähnliches wie eine grafische Oberfläche zu programmieren - eben was einfaches.

Also mein Tipp für Dich, mach Dich nicht "zu klug" mach nur DAS was Dein Lehrer verlangt - ja mach niemals das, was Du selbst schon kannst. Ok, vielleicht hat sich das nach 20 Jahren schon geändert, aber ich habe schon manche Foren gelesen, und da wars ähnlich, also die Lehrer haben sich nicht geändert, weil sie wohl genauso dumm sind wie annodazumal.

Stimmt doch, oder?


Dragonclaw - Mi 10.01.07 18:46

user profile iconjulian2304 hat folgendes geschrieben:
hä?
das versteh ich nicht?
wie muss den der quelltext jetzt aussehen?


steht da doch...

du hast 4 Variablen, die die x/y Koordinate der Buttons(Kästchen mit 1 und 2 in der "zeichnung") wieder spiegeln.

a ist die x Koordinate der LINKEN Seite von Button2(kannste auch einfach XCoordTorwart nennen. Ich hab a gewählt weil ich faul bin.

b ist die x Koordinate der RECHTEN Seite von Button1, daher muss hier noch die Breite des Buttons dazu genommen werden.

Eine Kollision entsteht , wenn die linke Seite von Button2 an, oder über der rechten Seiten von Button1 ist. Dies kann man mit den X Koordinaten überprüfen

if a <= b then ....


Dragon06 - Mi 10.01.07 18:47

häää was laberst du denn? xD
sry aber was hat das bitte mit der sache zu tun?

also die aufgabe lautet ein programm zu erstellen, in dem ein "ball" (button) an den wänden abprallt und an einem weiteren button abprallt, den man mit der maus bewegen kann (die maus soll ich der mitte des buttons sein)

naja und mit den wänden und der bewegung habe ich bereits geschafft bzw. manche lösungen auch durch die gute hilfe hier herausgekriegt!

aber was ich leider nicht hinbekomme ist das abprallen des balls an dem bewegbaren button!

und nochmal zu Raffos SEHR informativen post :D ... JA die lehrer sind immer noch *mist*e und NEIN ich mache nicht mehr als von mir verlangt wird :/

mfg

EDIT: der beitrag hier war noch auf Raffo's Beitrag bezogen!!


Dragon06 - Mi 10.01.07 19:34

user profile iconDragonclaw hat folgendes geschrieben:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
     _____   _____
    |__1__| |__2__|
<-----a---->|
<-----b-->|

a = Button2.left
b = Button1.left + Button1.width  

Kollision wenn
a <= b


Genau das selbe gilt natürlich für rechts oben und unten.


also irgendwie kann ich das noch nicht nachvollziehen, tut mir leid ^^
so ungefähr für den oberen rand??

Delphi-Quelltext
1:
2:
3:
4:
5:
    If Button.top < Buton1.top + Button1.height Then
    Begin
        Button.top := -Button.top;
        vz := -vz;
    End;

naja also richtig is es nicht ^^
wäre nett wenn jemand das berichtigen kann,
ich kriege es nämlich irgendwie nicht hin =(


Raffo - Mi 10.01.07 20:05

> naja und mit den wänden und der bewegung habe ich bereits geschafft
> bzw. manche lösungen auch durch die gute hilfe hier herausgekriegt!

Ist da nicht ein Äquivalent zum Button gegeben - auf Deutsch: Wenn Du das mit den Wänden geschafft hast, ist das Gleiche nicht auch auf den Button zu beziehen / anzuwenden?

Mach mal nen Beispiel Code hier, und viele Leute werden "drübergehen" und Deinen Code analysieren und ggf. optimieren (wollen).


Dragon06 - Mi 10.01.07 20:27

ja die wände sind ja auch nich beweglich wie der button :-/
mhhh könnt ihr mir vll wenigstens für die obere seite den queltext hier reinschrieben?

so durch eure erklärungen check ich grad irgendwie nich sry ^^


JayEff - Mi 10.01.07 20:35

julian2304... Ich helf dir gern, klar, aber nicht per PN, da hat dann ausser dir ja niemand was von ;)
Im prinzip ist alles bereits gesagt worden. Du musst eine Kolisionsabfrage programmieren, wie das geht, steht bereits im Thread hier, und zwar in Dragonclaws Post. Er hat euch 2 Buttons aufge"zeichnet" und 2 Strecken mit a und b markiert, sowie deren Längen über delphieigene Variablen ausgedrückt. Die Kollision findet statt, wenn die Abfrage, die er ebenfalls schon geliefert hat, true ergibt (allerdings natürlich nur für diese eine Kante).

Was ihr nun tun müsst, ist diese eine Abfrage für die anderen Kanten anpassen. Dazu müsst ihr euch die Form wie ein Koordinatensystem vorstellen mit dem Ursprung 0/0 oben links. Top ist der Wert nach unten, also je größer, desto weiter unten ist die position, Left ist der wert nach Links, also je größer, desto weiter links die Position. Der Rest ist simples rechnen, einfach mal Papier und Bleistift nehmen, eine kleine Zeichnung machen und genau wie Dragonclaw es bereits schematisch gemacht hat, Strecken markieren und in Delphivariablen ausdrücken.


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
     ^
     | Button.Top
     |
     v *=Button.Left
|<-->+___________  _
  *  |           | ^
     |  Button   | | Button.Height
     |           | |
     |___________| _

     |<--------->| Button.Width

Hier nochmal zur Verdeutlichung.

Nachdem ihr die Kolisionsabfragen (Per If-Abfragen natürlich) habt, müsst ihr dem Programm noch sagen, was es bei einer Kollision tun muss. Dazu die entsprechende Komponente des Bewegungsvektors umkehren.
Was ein Vektor ist, und wie man eine Komponente umkehrt? Ein Vektor ist praktisch vx und vy zusammen genommen, die geschwindigkeit der Bewegung auf der X achse und die der Bewegung auf der Y achse. Beides zusammen ist der Bewegungsvektor, jedes für sich ist eine Komponente des Bewegungsvektors. Wenn ihr eine Kollision auf der horizontalen (X) Achse feststellt, müsst ihr also die horizontale (X) komponente des Vektors umkehren: vx:=-vx;
Klartext: Die Bewegung auf der horizontalen Achse wird einfach umgedreht.

Jetzt sollte eigentlich alles klar sein und du/ihr müsstet es hinbekommen ;) Aber hey: Bis ich all das kapiert hab, hab ich auch ne weile gebraucht und wenn man sich mit Vektoren auskennt (Mathe 12te Klasse) hat man einen ganz schönen Vorteil ...


Dragon06 - Mi 10.01.07 21:12

so weit so gut ^^
und danke für die hilfe, bin leider noch nich so das Delphi-Ass ;D

naja also habe nun folgenen quelltext für den ball, wenn er gegen die obere kante des anderen button läuft...


Delphi-Quelltext
1:
2:
3:
4:
5:
    If Button.Top > Button1.height - 55 Then
    Begin
        Button.left := -Button.left;
        vx := -vx;
    End;


also so weit ich die erklärungen verstanden hab, müsste das doch so richtig sein oder?

also es kommt wenn ich das programm abspielen will auch keine fehlermeldung, jedoch ist plötzlich der ball verschwunden wenn ich es starte -.-

warum..... ? :(


Dragon06 - Mi 10.01.07 23:15

wieso verschwindet der button denn dann plötzlich??
das versteh ich nich -.-

plz help me ^^


.50AE - Mi 10.01.07 23:24

Wie ich in meiner Antwort ganz oben schon geschrieben habe, musst du das:
Button.left := -Button.Left weglassen!
Und wenn der eine Button nach oben abprallen soll müsste das vy und nicht vx sein..

So oft wie das alles hier schon durchgekaut wurde könntest du es ja so langsam mal hinkriegen ;-)

Ob der Button beweglich ist oder nicht spielt überhaupt keine Rolle bei der Kolliionsabfrage.
Du musst einfach herausfinden, ob der eine Button im anderen "drinsteckt". Und wie das geht, habe ich auch bereits geschrieben (und einige Andere inzwischen auch......)

MfG
50ae


julian2304 - Mi 10.01.07 23:47
Titel: Quelltext?!?!
Wieso kann denn keiner den Quelltext posten?? Bitte :)


Dragonclaw - Do 11.01.07 00:24

Ehmmm

Was ist bei

" Lass die Zeile blablabla Weg" nicht zu verstehen, aber egal: Euer(Dein) Code

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
 
   If Button.Top > Button1.height - 55 Then
    Begin
        Button.left := -Button.left;
        vx := -vx;
    End;


Jetzt die Zeile Button.left := -Button.left; entfernen.


Delphi-Quelltext
1:
2:
3:
4:
    If Button.Top > Button1.height - 55 Then
    Begin
        vx := -vx;
    End;


Nur so zur Sicherheit ;)


julian2304 - Do 11.01.07 08:19
Titel: danke!
danke aber es funktioniert immer noch nicht?!?!?
der ball verschwindet nach unten ins unendliche und prallt nicht ab.....

kann vielleicht jemand den kompletten quelltext posten?

Wäre nett :)


ZeitGeist87 - Do 11.01.07 08:31

Was springt für uns dabei raus?

Wenn ich jedesmal wenn ich n Problem hätte nach Quelltext fragen würde, dann hätt ich in meiner Ausbildung nix gelernt...

LG
Stefan

PS Probieren geht über Studieren. Und wenn das nicht mehr geht -> DF :)


julian2304 - Do 11.01.07 11:37
Titel: lol?
back to topic^^

ich habe doch geschrieben das ich nicht weiterkomme mit dem "torwart".
da hab ich schon so viel ausprobiert aber es hat nicht funktioniert! darum habe ich mich hier im forum gemeldet!!! ALSO!!

ich brauche den quelltext!!

danke :)


ZeitGeist87 - Do 11.01.07 11:52

Ich hab zwar sowas noch nie gemacht, allerdings ergeben sich aus den vorherigen Posts alle Antworten..

Wo ist dein Problem?
Du musst doch nur prüfen, ob sich die Position des Balls mit denen des Torwarts überschneidet.

Ist dies der Fall, einfach alle Richtungen ändern..

Betrachte den Torwart einfach als Wand, also Außenwand.
Wie n Haus um den Garten ist. Wenn du dann den Ball schießt prallt er irgendwo vom Haus (Hauswand) ab, weil er kollidiert ist.

Du musst einfach nur prüfen, von welcher wand, links, rechts, oben oder unten.

So hab ichs mir vorgestellt und ich programmiers jez einfach mal!

Und du auch!

LG
Stefan


julian2304 - Do 11.01.07 16:08
Titel: -.-
wenn ich den torwart als "wand" nehme, prallt der ball aber auch dort ab wo der torwart gar nich ist, also an der ganzen seite!??!
ich hab doch gesagt das ich ein noob bei delphi bin, darum hab ich mich ja auch hier gemeldet


ZeitGeist87 - Do 11.01.07 16:24

Das Problem hat ich auch =)

dann hab ich mir ne skizze gemacht und gesehen, dass er nur abprallen darf, wenn er auf der höhe des torwarts ist und natürlich in den dimensionen (links bis rechts = oberkante) liegt.

Ich poste mal das was ich bis jez hab =)

Ist noch bissl buggy..unten funktionier noch nicht richtig..naja kann man alles optimieren, ging halt rein um die Kollissionskontrolle..

LG
Stefan


julian2304 - Do 11.01.07 16:26

ahh ok!nur du hast ja auch das problem das der ball so komisch blinkt? was ist das?


ZeitGeist87 - Do 11.01.07 16:48

bei mir is das der refresh =)


JayEff - Do 11.01.07 17:50

user profile iconjulian2304 hat folgendes geschrieben:
ahh ok!nur du hast ja auch das problem das der ball so komisch blinkt? was ist das?

Nun, da gibts eine Universalantwort die immer zieht: DoubleBuffered:=true; :mrgreen:
Egal wohin, am besten aber ins Form1Create oder in den Startbutton, muss ja nur einmal auf true gesetzt werden fürs ganze Programm.
(Kleine Einschränkung: DoubleBuffered ist eine Variable der Form, das heißt, es muss für jede Form einzeln auf True gesetzt werden, auf der eine Bewegung dargestellt werden soll. Einfachster Weg: Ins Form1Create für jede Form dies braucht einstellen:

Delphi-Quelltext
1:
2:
Form1.DoubleBuffered := true;
Form2.DoubleBuffered := true; //etc.
)


BerTeL - Do 11.01.07 18:27

Ihr wollt euren source: eines meiner alten projeckte (wirklich alt) und hatt noch ein paar fehler. Aber müsste reichen (und ja nicht das abgeben ^^). Und nicht gleich jammer wenn ihr es nciht versteht :P anschauen und es versuchen es zu verstehen.


Dragon06 - Do 11.01.07 18:31

user profile iconBerTeL hat folgendes geschrieben:
Ihr wollt euren source: eines meiner alten projeckte (wirklich alt) und hatt noch ein paar fehler. Aber müsste reichen (und ja nicht das abgeben ^^). Und nicht gleich jammer wenn ihr es nciht versteht :P anschauen und es versuchen es zu verstehen.


oha :D naja also sooo professionell sollte unser prog nun nicht werden xD

aber nice!! ^^

werde es heut abend oder so noch mal versuchen und dann hier posten ob ich's hingekriegt hab ;)


BerTeL - Do 11.01.07 18:41

Es reicht schon wenn du dir anschaust wie die kollision arbeitet ...
außerdem: argh 2. seite übersehen -.-. Dann hätte ich das nicht gepostet :P


julian2304 - Do 11.01.07 19:25

me^2 @ Dragon06


julian2304 - Sa 13.01.07 16:46

also.......^^

ich habe es immer noch nicht hinbekommen das der ball am torwart abprallt.

könnte mir jemande jetzt hier mal den quelltext hinschreiben?

danke :)

mfg


JayEff - Sa 13.01.07 16:53

:motz: Wenn das so ist, dann ließ dir einfach nochmal den ganzen Thread durch ... :roll:
Da wäre zum Beispiel meine Ausführung, wie man das auf dem Blatt Papier berechnen kann, dann wär da BerTels fertiges Programm das er euch zur Verfügung gestellt hat, und viele weitere Tipps und Hilfestellungen anderer Leute...
Zeitgeist87 hat auch, extra für euch, ein Programm geschrieben, das euch das demonstrieren soll...

Poste uns doch mal deinen Quelltext, der nicht funktioniert, dann sehn wir ja, ob du unsere Ratschläge befolgt hast ;) Ausserdem sehn wir dann, was du falsch machst und können es verbessern.


jaenicke - Sa 13.01.07 16:59

user profile iconjulian2304 hat folgendes geschrieben:
könnte mir jemande jetzt hier mal den quelltext hinschreiben?

:rofl: :rofl: :rofl: :rofl: :rofl:
Ich lach mich gleich tot... Das gibts doch nicht nach dem was hier schon alles gepostet wurde... :roll:


julian2304 - Mo 15.01.07 09:04

-.-


ZeitGeist87 - Mo 15.01.07 09:27

Also!

Noch mal von vorn, so dass es jeder versteht!

Du hast das Ding ja "Torwart" getauft.

Ergibt es dann also sinn, dass der Ball links oder rechts vom Torwart abprallen kann?
Nein!
Warum? Weil der sich nur auf der Linie bewegt, sprich nach links und rechts.

Alles was an ihm vorbeigeht ist nunmal n Tor!
Weil was bringts wenn der "rausläuft"?

Also reicht es, wenn du die Kollissionsabfrage deines "Torwarts" nur von oben her implementierst.

Wie gehts das?

Ich poste mal den Quelltext aus meinem Beispiel und erklär ihn:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
 //Torwart (halten)
 if ((rund.Top + rund.height) >= Torwart.Top) and
    (rund.Top <= Torwart.Top) then
 begin
  if (rund.left >= Torwart.Left) and
     ((rund.left + rund.Width) <= (Torwart.Left + Torwart.Width)) then
  begin
   rund.Top:= -rund.Top;
   vw:= -vw;
   debugbox.lines.add('Gehalten');
  end;
 end;


Erklärung:

mit


Delphi-Quelltext
1:
2:
if ((rund.Top + rund.height) >= Torwart.Top) and
    (rund.Top <= Torwart.Top) then


prüfen wir, ob sich der Ball überhaupt in der Nähe des Torwarts befindet, sprich ob der in berührt.

Allerings erfolgt diese Berührung mit Einschränkung:


Delphi-Quelltext
1:
2:
if (rund.left >= Torwart.Left) and
     ((rund.left + rund.Width) <= (Torwart.Left + Torwart.Width)) then


Denn nur wenn rund (der Ball) auch im Bereich des Torwarts ist, also sich so:

| * |
---------
|Torwart|
---------

befindet, darf er auch abprallen. Befindet er sich links oder rechts vom Torwart, aber auf gleicher Höhe, so darf er nicht abprallen.

Erst wenn diese beiden Bedingung erfüllt sind (auf gleicher Höhe und im Bereich des Towarts/Buttons), dann darfst du den Ball abprallen lassen:


Delphi-Quelltext
1:
2:
 rund.Top:= -rund.Top;
 vw:= -vw;


Ich hoffe es ist einigermaßen gut erklärt!

LG
Stefan


Dragon06 - Mo 15.01.07 18:05

jo cool danke, jetz hab ich's auch endlich gerafft xD
naja aber die aufgabe war jetzt nicht ein fussball-programm zu machen ^^ sondern einfach nur einen bewegbaren button und einen anderen button der an dem bewegbaren abprallt!
also hab ich das auch noch für die untere seite gemacht...


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
    If (Button.Top <= Button1.Top + Button1.height) and
    (Button.Top >= Button1.Top + Button1.height)
    then
    begin
    if (Button.left <= Button1.Left) and
     ((Button.left + Button.Width) >= (Button1.Left + Button1.Width)) then
    begin
     Button.Top:= -Button.Top;
     vw:= -vw;
    end;
    end;


klappt auch soweit... naja der "ball" prallt zwar irgendwie eher in der mitte des anderen buttons ab, aber das dürfte ja nich so schlimm sein... oder hab ich da noch nen fehler drin??

danke für die reichliche hilfe ^^


JayEff - Mo 15.01.07 20:54

user profile iconDragon06 hat folgendes geschrieben:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
    If (Button.Top <= Button1.Top + Button1.height) and
    (Button.Top >= Button1.Top + Button1.height)
    then
    begin
    if (Button.left <= Button1.Left) and
     ((Button.left + Button.Width) >= (Button1.Left + Button1.Width)) then
    begin
     Button.Top:= -Button.Top;
     vw:= -vw;
    end;
    end;

oder hab ich da noch nen fehler drin??

Ja, erstens: grauenhafte Formatierung. Zweitens: Wenns nicht richtig klappt, ist ein Fehler drin.
Ich würde dir empfehlen, nicht mit Button und Button1, sondern vielleicht mit Player und Keeper zu arbeiten oder was die grad am liebsten ist, solangs eindeutig ist.
Die markierte Zeile ist, wie wir schon seeehr oft gesagt haben, totaler Blödsinn.
Man verschachtelt If-Abfragen nicht sondern verknüpft sie mit and (einfach alle statements die du schon hast in klammern setzen und mit nem and verbinden)
Wenn uns dann klar ist, welcher der Torwart und welcher der "Ball" ist, dann machen wir weiter ;)


Dragon06 - Mo 15.01.07 21:14

ach so ja...

button = ball
button1 = keeper

und es klappt ja auch jetzt! nur halt bei der unteren kante müsste noch n kleiner fehler sein... der ball prallt nicht an der kante ab, sondern in der mitte des keepers soweit ich das sehe ^^

hier ich hänge mal die anwundung an, könnt euch das ja mal angucken wie ich das meine;)


JayEff - Mo 15.01.07 21:25

Noch ein Fehler:
Wenn etwas GRÖSSER GLEICH und gleichzeitig KLEINER GLEICH etwas anderem ist, dann ist es GLEICH diesem anderen:

Delphi-Quelltext
1:
2:
If (Button.Top <= Button1.Top + Button1.height) and 
    (Button.Top >= Button1.Top + Button1.height)

Hierbei wird also so gut wie nie die kollision ausgelößt(da die werte beinah nie genau gleich sein werden ...). Bei dir wird beim von-unten-kommen vermutlich die von-oben-kommen Kollision ausgelößt.
Richtig wäre:

Delphi-Quelltext
1:
2:
3:
If (Button.Top <= Button1.Top + Button1.height) and 
    ((Button.Left >= Button1.Left) and (Button.Left <= Button1.Left + Button1.Height)) then
     vw:=-vw;


PS: Ob das stimmt kann ich nicht testen, könntest du gleich den rest von deinem Source anhängen, damit ich meinen Code einfügen und ausprobieren kann? ;)


Dragon06 - Di 16.01.07 15:49

jo hier is der quelltext zu der beigefügten anwendung aus meinem letzten post...


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:
implementation
Var
vx:integer;
vy:integer;
vz:integer;
vw:integer;
va:integer;
vb:integer;

{$R *.DFM}

Procedure TForm1.Button_startClick(Sender: TObject);
Begin
    vw := 5;
    vx := -1;
    vy := 1;
    vz := -5;

    Timer1.Enabled := True;
    Button_start.visible := false;
End;

Procedure TForm1.Timer1Timer(Sender: TObject);
Begin
    Button.left := Button.left + vx;
    Button.top := Button.top + vz;
    If Button.left < 0 Then
    Begin
        Button.left := -Button.left;
        vx := -vx;
    End;
    If Button.left > 660 Then
    Begin
        Button.left := -Button.left;
        vy := -vy;
    End;

    If Button.top < 0 Then
    Begin
        Button.top := -Button.top;
        vz := -vz;
    End;
    If Button.top > Form1.height - 55 Then
    Begin
        Button.top := -Button.top;
        vw := -vw;
    End;

    If ((Button.Top + Button.height) >= Button1.Top) and
    (Button.Top <= Button1.Top) then
    begin
    if (Button.left >= Button1.Left) and
     ((Button.left + Button.Width) <= (Button1.Left + Button1.Width)) then
    begin
     Button.Top:= -Button.Top;
     vw:= -vw;
    end;

    If (Button.Top <= Button1.Top + Button1.height) and
    (Button.Top >= Button1.Top + Button1.height)
    then
    begin
    if (Button.left <= Button1.Left) and
     ((Button.left + Button.Width) >= (Button1.Left + Button1.Width)) then
    begin
     Button.Top:= -Button.Top;
     vw:= -vw;
    end;
    end;

End;

End;


Procedure TForm1.Button1MouseMove(Sender: TObject; Shift: TShiftState; X,
    Y: integer);
Begin

    If X > 31 Then
    Begin
        Button1.left := Button1.left + 2;
    End;
    If X < 29 Then
        Button1.left := Button1.left - 2;
End;

end.


ZeitGeist87 - Di 16.01.07 15:52

sag mal wer hatt euch nur diese sche*** formatierung angedreht..


Leuchtturm - Di 16.01.07 15:56

user profile iconZeitGeist87 hat folgendes geschrieben:
sag mal wer hatt euch nur diese sche*** formatierung angedreht..

Das <frgate ich mich auch gerade :)


Dragon06 - Do 18.01.07 13:41

user profile iconLeuchtturm hat folgendes geschrieben:
user profile iconZeitGeist87 hat folgendes geschrieben:
sag mal wer hatt euch nur diese sche*** formatierung angedreht..

Das <frgate ich mich auch gerade :)


mhh das hilft mir jetz auch nich weiter xD


Danny W. - Do 18.01.07 14:40

<OT>
Naja, jeder hat nen anderen Stil...aber das ist wirklich hart ^^ da kommt man ja voll durcheinander..ich würde es als tipp mitnehmen...

Ich mach das immer so (Ich weiß, dass das auch nicht optimal ist, aber vom stil her isses recht übersichtlich!)


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
if ((zahl = wert) and (zahl2 = wert2)) then 
      begin
         tuwas;
         undzwarzügig;
         sofort;
      end
  else
      begin
         oderlasses;
         einfach;
         sein;
      end;


</OT>

Gruß
Danny


julian2304 - Sa 20.01.07 21:59

@ ALL!!
danke für eure hilfe!! :)