Autor Beitrag
julian2304
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 26



BeitragVerfasst: Di 09.01.07 17:13 
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:

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:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 66

Win MCE 2005
Delphi7 Enterpr.
BeitragVerfasst: Di 09.01.07 17:19 
Möchtest du ein Ping-Pong programmieren? Diesen klassichen Arcadeklassiker Break-Out oder so?
.50AE
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 100



BeitragVerfasst: Di 09.01.07 17:36 
Hi,

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

ausblenden 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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: Di 09.01.07 17:59 
ausblenden 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:
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:
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
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
Var 
 vx:integer; 
 vy:integer; 
 vz:integer; 
 vw:integer;

hast, kannst du es vielleicht übersichtlicher zusammenfassen:
ausblenden Delphi-Quelltext
1:
2:
Var 
   vx, vy, vz, vw:integer;

_________________
>+++[>+++[>++++++++<-]<-]<++++[>++++[>>>+++++++<<<-]<-]<<++
[>++[>++[>>++++<<-]<-]<-]>>>>>++++++++++++++++++.+++++++.>++.-.<<.>>--.<+++++..<+.
Dragon06
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 196

Windows Vista
Delphi 7 Prof.
BeitragVerfasst: Mi 10.01.07 18:35 
ausblenden 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 26



BeitragVerfasst: Mi 10.01.07 18:36 
@ Dragonclaw

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


Zuletzt bearbeitet von julian2304 am Mi 10.01.07 18:43, insgesamt 1-mal bearbeitet
Raffo
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 300



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 196

Windows Vista
Delphi 7 Prof.
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Mi 10.01.07 19:34 
user profile iconDragonclaw hat folgendes geschrieben:
ausblenden 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??
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 300



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2971

Windows Vista Ultimate
D7 Enterprise
BeitragVerfasst: 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.

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



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

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25



BeitragVerfasst: Mi 10.01.07 23:15 
wieso verschwindet der button denn dann plötzlich??
das versteh ich nich -.-

plz help me ^^
.50AE
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 100



BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 26



BeitragVerfasst: Mi 10.01.07 23:47 
Titel: Quelltext?!?!
Wieso kann denn keiner den Quelltext posten?? Bitte :)
Dragonclaw
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 196

Windows Vista
Delphi 7 Prof.
BeitragVerfasst: Do 11.01.07 00:24 
Ehmmm

Was ist bei

" Lass die Zeile blablabla Weg" nicht zu verstehen, aber egal: Euer(Dein) Code
ausblenden 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.

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


Nur so zur Sicherheit ;)
julian2304 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 26



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