Autor |
Beitrag |
julian2304
      
Beiträge: 26
|
Verfasst: 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:
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 public 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
      
Beiträge: 66
Win MCE 2005
Delphi7 Enterpr.
|
Verfasst: Di 09.01.07 17:19
Möchtest du ein Ping-Pong programmieren? Diesen klassichen Arcadeklassiker Break-Out oder so?
|
|
.50AE
      
Beiträge: 100
|
Verfasst: 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
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: 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:
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
      
Beiträge: 25
|
Verfasst: 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
      
Beiträge: 196
Windows Vista
Delphi 7 Prof.
|
Verfasst: 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 
      
Beiträge: 26
|
Verfasst: 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
      
Beiträge: 300
|
Verfasst: 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
      
Beiträge: 196
Windows Vista
Delphi 7 Prof.
|
Verfasst: Mi 10.01.07 18:46
julian2304 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
      
Beiträge: 25
|
Verfasst: 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  ... 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
      
Beiträge: 25
|
Verfasst: Mi 10.01.07 19:34
Dragonclaw 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
      
Beiträge: 300
|
Verfasst: 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
      
Beiträge: 25
|
Verfasst: 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
      
Beiträge: 2971
Windows Vista Ultimate
D7 Enterprise
|
Verfasst: 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
      
Beiträge: 25
|
Verfasst: 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
      
Beiträge: 25
|
Verfasst: Mi 10.01.07 23:15
wieso verschwindet der button denn dann plötzlich??
das versteh ich nich -.-
plz help me ^^
|
|
.50AE
      
Beiträge: 100
|
Verfasst: 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 
      
Beiträge: 26
|
Verfasst: Mi 10.01.07 23:47
Titel: Quelltext?!?!
Wieso kann denn keiner den Quelltext posten?? Bitte 
|
|
Dragonclaw
      
Beiträge: 196
Windows Vista
Delphi 7 Prof.
|
Verfasst: 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 
      
Beiträge: 26
|
Verfasst: 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 
|
|