![]() |
Break-Game, Kugel auf Rechtecklanden lassen ...
Hey Leutz,
Ich habe früher viel C++ Programmiert bin aber vor einiger Zeit auf Delphi umgestiegen. Nun bin ich dabei ein naja einfaches Game zu schreiben, mein Problem liegtnach if (bar.Top = Kugel.Top) then if vermute ich Code. Und zwar soll, wenn der Ball auf das Rechteck fliegt wieder zurück kehren. Dummerweiße erkennt mein Programm nicht dass der Ball die gleiche .left wie mein Balken(Rechteck) hat. Dass rechteck hat eine Width von 25 darum auch immer +1/-1 da er ja , egal auf welcher Fläche er landet es Merken soll. Ich hoffe ihr habts kapiert ... Hier der Code : Hey Leutz, Ich habe früher viel C++ Programmiert bin aber vor einiger Zeit auf Delphi umgestiegen. Nun bin ich dabei ein naja einfaches Game zu schreiben, mein Problem liegtnach if (bar.Top = Kugel.Top) then if vermute ich Code. Und zwar soll, wenn der Ball auf das Rechteck fliegt wieder zurück kehren. Dummerweiße erkennt mein Programm nicht dass der Ball die gleiche .left wie mein Balken(Rechteck) hat. Dass rechteck hat eine Width von 25 darum auch immer +1/-1 da er ja , egal auf welcher Fläche er landet es Merken soll. Ich hoffe ihr habts kapiert ... Hier der Code :
Delphi-Quellcode:
Mfg KleinAmann
var
Form1: TForm1; counter : integer; xK : integer; yK: integer; i : integer; implementation {$R *.dfm} procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var yy : string; xx : string; begin yy := IntToStr(Y); xx := IntToStr(X); aY.Caption := yy; aX.Caption := xx; if Y > 350 then if Y < 426 then bar.Top := Y; if X < 501 then bar.Left := X; // Bar der Maus nachlaufen lassen! end; procedure TForm1.FormActivate(Sender: TObject); begin counter := 1; xK := 300; end; procedure TForm1.Timer1Timer(Sender: TObject); begin Kugel.Left := xK; if (i = 1) then begin counter := counter +1; yK := counter; end else if (i = 2) then begin counter := counter -1; yK := counter; end; if (bar.Top = Kugel.Top) then if (bar.Left = (Kugel.Left) or (Kugel.Left +1) or (Kugel.Left -1) or (Kugel.Left +2) or (Kugel.Left -2) or (Kugel.Left +3) or (Kugel.Left -3) or (Kugel.Left +4) or (Kugel.Left -4) or (Kugel.Left +5) or (Kugel.Left -5) or (Kugel.Left +6) or (Kugel.Left -6) or (Kugel.Left +7) or (Kugel.Left -7) or (Kugel.Left +8) or (Kugel.Left -8) or (Kugel.Left +9) or (Kugel.Left -9) or (Kugel.Left +10) or (Kugel.Left -10) or (Kugel.Left +11) or (Kugel.Left -11) or (Kugel.Left +12) or (Kugel.Left -12) or (Kugel.Left +13) or (Kugel.Left -13) or (Kugel.Left +14) or (Kugel.Left -14) or (Kugel.Left +15) or (Kugel.Left -15) or (Kugel.Left +16) or (Kugel.Left -16) or (Kugel.Left +17) or (Kugel.Left -17) or (Kugel.Left +18) or (Kugel.Left -18) or (Kugel.Left +19) or (Kugel.Left -19) or (Kugel.Left +20) or (Kugel.Left -20) or (Kugel.Left +21) or (Kugel.Left -21) or (Kugel.Left +22) or (Kugel.Left -22) or (Kugel.Left +23) or (Kugel.Left -23) or (Kugel.Left +24) or (Kugel.Left -24) or (Kugel.Left +25) or (Kugel.Left -25)) then begin i := 2; end; if Kugel.Top < 410 then begin Kugel.Top := Kugel.Top + yK; end else begin yK := 160; xK := 372; Panel1.Visible := true; end; end; procedure TForm1.FormCreate(Sender: TObject); begin i := 1 end; end. |
Re: Break
Hi,
mach mal bitte die [delphi][/delphi]-Tags um Deinen Code :) |
Re: Break
hey sry ;(
|
DP-Maintenance
Dieses Thema wurde von "Matze" von "Programmieren allgemein" nach "Multimedia" verschoben.
Delphi-Frage ;) |
Re: Break
Das geht so nicht:
Zitat:
|
Re: Break
Hi,
macht nichts. Kann jedem mal passieren, so schauts aber deutlich besser aus. Zum Einen:
Delphi-Quellcode:
wäre vielleicht ein
if (bar.Top = Kugel.Top)
Delphi-Quellcode:
besser, da es sonst wirklich genau gleich sein muss.
if (Kugel.Top >= Bar.Top)
Zum anderen das lange If-Gewurschtel. Das kannst Du sicher mit
Delphi-Quellcode:
o.Ä. ersetzen.
if ((Kugel.Left - 25 >= Bar.left) or (Kugel.Left + 25 <= Bar.Left))
|
Re: Break
hey,
erstmal STAUN danke für die schnellen Antworten bin ich nicht gewohnt in anderen Fourms ;) DANKE so ich hab mal then if ((Kugel.Left - 25 >= Bar.left) or (Kugel.Left + 25 <= Bar.Left)) ausprobiert, leider macht er es immer noch nicht =( * noch ne Frage bei mir Debugt der Compiler also Borland Delphi 2005 nicht mehr, bin mal ausversehna auf : run -> run with out debugging gekommen wie mach ich dies Rückgängig? * Naja vielen Dank für die Antworten bis jetzt ;) Mfg KleinAmann |
Re: Break
Einfach auf Run -> Run klicken oder alternativ auf F9 drücken.
Es wäre besser, wenn Du den Code zuerst einmal debuggst, Dir die Werte anschaust und guckst, warum er nicht in die Abfrage springt. Sonst raten wir hier nur rum. Und mein Beispielcode muss nicht zwingend genau das sein, was es zum Laufen bringt. Es sollte nur als ein Beispiel dienen. |
Re: Break
Hey,
Leider stimmt was komplett nicht, unzwar macht er es nciht einmla wenn die Top also die Höhe übereinstimmt. Das hat eigentlich immer funktioniert..
Delphi-Quellcode:
if (bar.Top = Kugel.Top)
then //if //((Kugel.Left - 25 >= Bar.left) or (Kugel.Left + 25 <= Bar.Left)) // then begin i := 2; Panel1.Visible := true; Panel1.Caption := 'test'; end;
Delphi-Quellcode:
unit game;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls; type TForm1 = class(TForm) bar: TShape; aX: TLabel; Label2: TLabel; Label3: TLabel; aY: TLabel; Kugel: TShape; Timer1: TTimer; Panel1: TPanel; procedure FormCreate(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure FormActivate(Sender: TObject); procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } end; var Form1: TForm1; counter : integer; xK : integer; yK: integer; i : integer; implementation {$R *.dfm} procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); var yy : string; xx : string; begin yy := IntToStr(Y); xx := IntToStr(X); aY.Caption := yy; aX.Caption := xx; if Y > 350 then if Y < 426 then bar.Top := Y; if X < 501 then bar.Left := X; // Bar der Maus nachlaufen lassen! end; procedure TForm1.FormActivate(Sender: TObject); begin counter := 1; xK := 300; end; procedure TForm1.Timer1Timer(Sender: TObject); begin Kugel.Left := xK; if (i = 1) then begin counter := counter +1; yK := counter; end else if (i = 2) then begin counter := counter -1; yK := counter; end; if (bar.Top = Kugel.Top) then if ((Kugel.Left - 25 >= Bar.left) or (Kugel.Left + 25 <= Bar.Left)) then begin i := 2; Panel1.Visible := true; Panel1.Caption := 'test'; end; if Kugel.Top < 410 then begin Kugel.Top := Kugel.Top + yK; end else begin yK := 160; xK := 372; Panel1.Visible := true; end; end; procedure TForm1.FormCreate(Sender: TObject); begin i := 1; end; end. |
Re: Break
Was passiert, wenn Du auf größer gleich und nicht auf Gleichheit überprüft? (Oder auch auf <=, je nach, ob sich das Shape oben oder unten befindet)
|
Re: Break
Hai KleinAmann,
bitte gebe deinem Thread einen Titel von dem man auch gleich auf den Inhalt der Frage schliessen kann. Dafür musst Du nur auf den "Edit"-Button neben dem obersten Posting von Dir klicken. Nur wenn ein Thread einen Titel hat der auf die Frage schliessen lässt haben andere die Möglichkeit, durch benutzen der Suchfunktion, eine Lösung für ähnliche Fragen zu finden. Danke :!: |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
hey,
also wenn man das ungleich macht (<= | >=) dann funtz es aber es ist wichtig dass es genau ist weil sonst hat das Spiel dummerweiße keinen sinn :( Bitte um weitere Hilfe P.s ich schreibe so spät da unser Router den Geist aufgeben hat. sry |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Liste der Anhänge anzeigen (Anzahl: 1)
Genau wird dein Ball jedoch in den seltensten Fällen treffen, da er sich wahrscheinlich meist um mehr als nur einen Pixel pro Step bewegt. Die genauste Möglichkeit das in den Griff zu bekommen ist es, wenn du den Flugvektor den Balles nimmst, und die Gerade die er erzeugt mit der Kollisionsgeraden schneidest. Liegt der Schnittpunkt innerhalb des unskalierten Flugvektors, tritt zwischen dem letzten und nächsten Step die Kollision ein. Dann kannst du den Flugverktor an der Normalen der Kollisionsgeraden im Schnittpunkt spiegeln (Reflexion), und ihn um den restlichen Betrag den der vorige Flugvektor über die Kollisionsgerade hinaus geht in die neue Richtung verschieben. Damit hast du dann die Kollision "zwischen" zwei Steps korrekt berechnet, obwohl der Ball den Schläger niemals sichtbar berührt.
Der einfachere und ungenauere (meist aber ausreichende) Weg ist es, den Ball sobald der über die Kollisionsgerade hinaus ist, genau über diese zu platzieren, und fortan den reflektierten alten Flugvektor zum aktuellen zu machen. Damit erspart man sich die Schnittpunktbestimmung, und die Verhältnisbildung des Schnittpunktes zum Flugvektor, sowie ein paar Additionen. Nachteil der Variante ist, dass man den tatsächlichen Schnittpunkt ja nur noch approximiert, und nicht die exakte Flugbahn einhält. Dadurch kann das gerade bei hohen Geschwindigkeiten zu ruckartigem unerwarteten Verhalten führen. Gruß, Medium Edit: Hab mal noch n Bildchen zu obigem gemacht. In Worten ist das glaube ich schwer nachvollziehbar. |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
hey,
erstaml WOW für die geile Idee und für die Grafik. Leider denk ich nicht dass ich das hingrieg, werd aber mal versucehn. Vielen Dank nochmal an alle ich werd mich aufjedenfall melden ;) Mfg Domi |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
hey,
Hab jetzt sehr viel ausprobiert aber bekomms einfach nicht hin =( Könnt ihr mir ein Tipp geben? Mfg Domi |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Morgen,
häng doch bitte mal das Projekt an. |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Liste der Anhänge anzeigen (Anzahl: 1)
Morgen =),
Hier ist mein Code, und das ganze Projekt ist net grad das beste weil in die richtung hab ich noch nichts gemacht. Mfg Domi P.s wenn ich in Delphi mein Priójekt abspeichern will, kommt oft das ich eine Acess violation hab und dann noch was mit karasx2.dll. kennt jemand das Problem, und kann helfen wäre echt super nett =) |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
es gibt auch noch ptinRect evlt. reicht das schon für deine Kollision Erkennung.
|
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
wie funktioniert die Funktion?
|
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Ganz einfach: Du übergibst zuerst ein TRect und dann ein TPoint.
Es dürften hier genügend beispiele geben. Für ein BreakOut Clone dürfte das ausreichen. am besten währe es du schreibst dir eine Funktion die alle Objekte durch geht und die angeben Position vergleich. Die Funktion prüft letztendlich nur ob ein Punkt in Viereck liegt. Wenn ja wird True zurück geben wenn nein wird False zurück geben. Es gibt noch weitere nützliche Funktionen. z.b. eine die vergleich ob zwei Viereck sich schneiden. PS: Ich kann dir gerne mal meine 2D Engine geben bzw. die gibt es hier zum runter laden. Allerdings geht sie nur in Verbindung mit Lazarus. Die Engine basiert komplett auf Canvas. Oder du kannst auch noch Andorra nutzten, wie ich gesehen habe ist es damit auch recht einfach. Aber vermutlich währe es für ein einfachen BreakOut Clone übertrieben(dort gibt es übrings schon einen als beispiel) |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
hey,
würde mich über eine 2D engine sehr freuen wäre cool wenn du mla von beiden den Link postest. Vielen Dank Mfg Domi |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
naja die engine läuft nur unter Lazarus. Ich habe sie hier gerade nichte gefunden.
ich lade sie später hoch. Aber ich weiß nicht so recht, ob sie dir weiter helfen wird. |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
So hier habe ich die "2D Engine" gerade eben hochgeladen:
![]() Ich habe zwar auch ein eigenen BreakOut Clone geschrieben, aber ich glaube den veröffentliche ich erst später, weil der auf das GamePack basiert, welches intern meine "2D Engine" nutzt. |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Wenn man mit PtInRect arbeitet muss man aber mindestens von einem der möglichen Kollisionspartner wirklich JEDEN Pixel einzeln überprüfen, oder aber eine geschlossene "Sensorlinie" abprüfen. Beides Gefummel und nicht wirklich performant, und wenn das Rect zu schmal ist, bzw. der Ball zu schnell kann er dir dabei immer noch einfach durchfliegen. Das lässt sich dann nur noch mit Schnittpunktbestimmung umgehen, welche zudem nicht nur die reine Kollision feststellt, sondern auch gleich Infos zur korrekten Reflexion liefert. Auf Pixeltests basierende Kollisionen halte ich für grausiges Gefrickel (zumindest wenn darauf hin etwas "abprallen" soll) :)
|
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Nein, das ist nicht so richtig.
Wenn du den Ball bewegen möchtest, weißt du ja wohin. Jetzt muss du nur noch in einer schleife prüfen ob dort schon ein Objekt ist oder nicht. Rate mal wie das Andorra macht ? oder ich bei meiner 2D Engine. Die heutigen Rechner können das. und du wirst warscheinlich nicht 10000 Objekte haben. Wenn es hoch kommt wirst du evlt. gerade mal 100 oder 200 Objekte habe. und die Funktion prüft auch nur ob im angeben Viereck ein Punkt liegt. Das ist sehr viel schneller als jeden Pixel zu prüfen. Du hast ein Viereck und die Funktion prüft jetzt einfach nur noch ob in diesem Viereck die angeben Koordinaten liegen. Mehr nicht. Das sollte bei den meisten Rechner überhaupt kein Problem da stellen. Und wie möchtest du es sonst lösen ? In deinen Fall könntest du auch noch ein zweites BitMap einfügen, wo du nur unbewegliche Objekte rein tust. die werden dann in einer Farbe gezeichnet, der Rest in einer anderen. Wenn du den Ball bewegt, könntest du einfach nach schauen ob dort frei ist oder nicht. mit Hilfe von Pixels von Canvas. Aber diese Lösung wird viel mehr Speicher brauchen. Zum Aprallen hier gibt es auch ein Beispiel in der "Code Lib" dazu: ![]() |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Zitat:
Zitat:
Zitat:
Zitat:
Zitat:
![]() Zitat:
Versteh mich nicht falsch, ich will niemanden einfach nur anmachen, aber was du da geschrieben hast ist imho eine echte Sammlung von no-gos, die man so nicht stehen lassen kann. |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Wenn du meinst. Man kann es auch übertreiben das stimmt. Ich habe mir den Code jetzt nicht angesehen, weil unter Linux kann ich noch nicht ohne weiteres neue Rar Formate entpacken. Ich habe nur ein Komandozeilen tool.
Wenn ich mal lust habe mache ich das. |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
GIF <> RAR :gruebel:
|
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Hast recht, habe den falschen Anhang angeschaut.
Ich verstehe zwar das bild nicht so recht, aber ich glaube wie meinen im Grunde das gleiche, nur reden wir gerade aneinander vorbei. So wie das Bild aussieht meinte ich das eigentlich auch. So macht das ja auch ptinRect. Schau dir mal die Funktion an. |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
PtInRect macht folgendes:
Es nimmt einen 2D-Punkt entgegen, und ein Rect. Dann wird die X-Koordinate des Punktes auf größer/kleiner mit der linken/rechten Begrenzung des Rects verglichen, sowie die Y-Koordinate mit der oberen/unteren Grenze. Das ergebnis ist die 4 Vergleiche and-verknüpft. Das muss man nun für jeden Punkt des zu testenden Objektes machen, und für jeden Punkt den dieses im Laufe der Bewegung einnehmen wird. Was ich mache ist etwas völlig anderes. Ich nehme den Richtungsvektor des beweglichen Objektes, und erstelle mir eine Gerade auf den Ballmittelpunkt gestütz, setzte diese gleich mit der Gerade die die Kollisionsoberfläche bildet, und erhalte nach lösen des kleinen LGS einen Parameter, der angibt wie oft ich den Richtungsverktor "malnehmen" muss, um auf die Oberfläche zu treffen. Ist der Parameter kleinergleich eins, tritt die Kollision im anstehenden Schritt auf, und mit den dann vorhandenen Daten kann man zudem leicht ein physikalisch korrektes Abprallverhalten trotz mögl. großschrittiger Bewegung errechnen. Was man mit PtInRect macht ist Pixelweise rumfrickeln, was ich mache ist einfache lineare Algebra. Vorteile letztrer Variante: - Konstanter Zeitverbrauch (man muss nicht u.U. alle Pixel in einer Diagonalen quer über den Bildschirm abstesten) - Kollision wird IMMER gefunden, selbst wenn das Objekt so klein/schnell ist, dass es sonst weit über den Kollisionspartner "springen" würde - Analytischer statt diskreter Ansatz - Universell einsetzbar (Die Kollisionspartner müssen keine rechtwinkligen Vierecke oder Kugeln sein, auch wenn es die einfachsten Fälle sind) Nachteile: - Man muss in der Schule bei Vektorrechnung gerade wach gewesen sein, zumindest halb ;) Und wie vorher schon erwähnt, kann man in diesem speziellen Fall einige sehr deutliche Vereinfachungen machen, da man immer mit horizontalen Linien Kollidiert, diese keine Eigenbewegung haben, und die Präzision sehr wahrscheinlich ausreichen wird. Wie, hatte ich ja auch schon geschrieben. Der TE müsste nur mal ein wenig genauer werden als "geht nicht", dann könnte man vermutlich sogar konkret weiter helfen :roll: |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
okay,
dass war jetzt relativ viel aufeinmal. Ich werds wenn ich daheim bin nochmla ganz in ruhe durchlesen Vielen Dank fürs erste Mfg Domi |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Zitat:
Zitat:
Hier mal ein Beispiel, wie ich diese Funktion einsetzte:
Delphi-Quellcode:
Ganz verstehe ich deine Methode immer noch nicht.
function TPluto2SpriteManger.N_Collision(const ax, ay: Integer;
const aEvent: Boolean; const aPixelcheck: boolean): TPluto2DSprite; var i:Integer; sp:TPluto2DSprite; p:TPoint; r1:TRect; begin sp:=nil; p:=Point(ax,ay); r1:=Engine.GameFehld; // Schauen ob die Positions Angabe im Spielb Rect Liegt if (PtInRect(r1,p)) then begin for i:=0 to fItems.Count-1 do begin // p:=Point(ax+Items[i].Width,ay+Items[i].Height); if PtInRect(Items[i].GetR,p) then begin if (not items[i].NoCollision) and (items[i].visible) then begin sp:=Items[i]; //break; end; end; end; // for i end; if (aEvent) and (Assigned(Engine.onCollision) ) then begin Engine.onCollision(nil, sp); end; result:=sp; end; // TPluto2SpriteManger.N_Collision |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Entweder bin ich gerade wirklich sehr blind, oder du prüfst hier doch nur, ob der Pixel (ax, ay) im Spielfeld liegt, und wenn ja, ob er in einem anderen Sprite liegt, dass die Kollisionsprüfung an hat, wobei du zudem davon ausgehst, dass ein Sprite immer rechteckig und nicht gedreht ist.
Wenn ich aber nicht die Kollision eines einzelnen Pixels (ax, ay), sondern z.B. eines Kreises prüfen will, wie erledigst du das? edit: "aPixelcheck" klingt interessant, wird aber nirgends benutzt. |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Zitat:
Diese Stufe soll ja auch nur erstmal eine grobe Feststellung sein. hier noch mal ein code wi aPixelCheck auch genutzt wird:
Delphi-Quellcode:
Wie du siehst kann ich einmal nur eine Grobe Kollision Erkennung machen und eine genauere. Wobei eine Pixel Check Funktion natürlich länger dauert und auch mehr speicher Verbraucht. Darum mache ich es eine ungenauere.
function TPluto2SpriteManger.N_Collision(const ax, ay:Integer; const aSprite: TPluto2DSprite;
const aEvent: Boolean; const aPixelcheck: boolean): TPluto2DSprite; var i:Integer; sp:TPluto2DSprite; p:TPoint; r1, r2, r3,r4,r5:TRect; begin sp:=nil; p:=Point(ax,ay); r1:=Engine.GameFehld; r2:=Rect(ax, ay, ax+aSprite.Width, ay+aSprite.Height); r4:=rect(aSprite.Left,aSprite.Top,aSprite.Width,aSprite.Height); // Schauen ob die Positions Angabe im Spielb Rect Liegt if (PtInRect(r1,p)) then begin for i:=0 to fItems.Count-1 do begin if (aSprite.guid <> items[i].guid) then begin if IntersectRect(r3,items[i].GetR,r2) then begin if (not items[i].NoCollision) and (items[i].visible) then begin if not aPixelcheck then begin sp:=Items[i]; break; end else begin r5:=rect(items[i].Left,items[i].Top,items[i].Width,items[i].Height); if kollision(r4,r5,aSprite.SpriteImage,items[i].SpriteImage) then begin sp:=Items[i]; break; end; // if kollision(..) end; // else begin end; // if (not NoCollision) end; // if IntersectRect(..) end; // if asprite.guid <> items[i].guid end; // for i end; if (sp <> NIL) and (aEvent) and (Assigned(Engine.onCollision)) then begin Engine.onCollision(nil, sp); end; result:=sp; end; // TPluto2SpriteManger.N_Collision { Autor: umpani, Michael Springwald Update: Freitag den 25.Janur.2008, Freitag, 01.Febura.2008 Diese Funktion stammt von "umpani" und ist hier zu finden: [url]http://www.delphi-forum.de/viewtopic.php?t=12746&postdays=0&postorder=asc&start=20[/url] Ich habe sie "nur" Angepasst für mein zweck. Fragen also bitte an "umpani" richten im delphi-forum.de. } function kollision(r1,r2:TRect;B1,b2:TBitMap):boolean; var ueberlapp_breite, ueberlapp_hoehe:integer; ueberlapp_nr1_x, ueberlapp_nr1_y, ueberlapp_nr2_x, ueberlapp_nr2_y:integer; x,y:integer; farbenr1,farbenr2:TColor; z:Boolean; begin z:=False; if r1.left < r2.left then ueberlapp_breite := (r1.left + r1.Right) - (r2.left) else ueberlapp_breite := (r2.left + r2.Right) - r1.Left; if r1.Right > r2.Right then if ueberlapp_breite >= r2.Right then ueberlapp_breite := r2.Right; if r1.top < r2.top then ueberlapp_hoehe := (r1.Top + r1.Bottom) - (r2.Top) else ueberlapp_hoehe := (r2.Top + r2.Bottom) - (r1.Top); if r1.Bottom > r2.Bottom then if ueberlapp_hoehe > r2.Bottom then ueberlapp_hoehe := r2.Bottom; if (ueberlapp_breite > 0) and (ueberlapp_hoehe > 0) then begin if r1.Right >= r2.Right then begin if (r2.Left+r2.Right) >= (r1.Left+r1.Right) then begin ueberlapp_nr1_x := r1.Right - ueberlapp_breite; ueberlapp_nr2_x := 0; end; if ((r2.Left+r2.Right) < (r1.Left+r1.Right)) and (r2.left >= r1.left) then begin ueberlapp_nr1_x := (r2.Left-r1.Left); ueberlapp_nr2_x := 0; end; if (r2.Left) < (r1.Left) then begin ueberlapp_nr1_x := 0; ueberlapp_nr2_x := r2.Right - ueberlapp_breite; end; end; end; if r1.Right < r2.Right then begin if (r1.Left+r1.Right) >= (r2.Left+r2.Right) then begin ueberlapp_nr2_x := r2.Right - ueberlapp_breite; ueberlapp_nr1_x := 0; end; if ((r1.Left+r1.Right) < (r2.Left+r2.Right)) and (r1.Left >= r2.Left) then begin ueberlapp_nr2_x := (r1.Left-r2.Left); ueberlapp_nr1_x := 0; end; if (r1.Left < r2.Left) then begin ueberlapp_nr2_x := 0; ueberlapp_nr1_x := r1.Right - ueberlapp_breite; end; end; if r1.Bottom >= r2.Bottom then begin if (r2.Top+r2.Bottom) >= (r1.Top+r1.Bottom) then begin ueberlapp_nr1_y := r1.Bottom - ueberlapp_hoehe; ueberlapp_nr2_y := 0; end; if ((r2.Top+r2.Bottom) < (r1.top+r1.Bottom)) and (r2.Top >= r1.Top) then begin ueberlapp_nr1_y := (r2.top-r1.top); ueberlapp_nr2_y := 0; end; if (r2.top) < (r1.top) then begin ueberlapp_nr1_y := 0; ueberlapp_nr2_y := r2.Bottom - ueberlapp_hoehe; end; end; if r1.Bottom < r2.Bottom then begin if (r1.Top+r1.Bottom) >= (r2.Top+r2.Bottom) then begin ueberlapp_nr2_y := r2.Bottom - ueberlapp_hoehe; ueberlapp_nr1_y := 0; end; if ((r1.Top+r1.Bottom) < (r2.Top+r2.Bottom)) and (r1.Top >= r2.Top) then begin ueberlapp_nr2_y := (r1.top-r2.top); ueberlapp_nr1_y := 0; end; if (r1.top < r2.top) then begin ueberlapp_nr2_y := 0; ueberlapp_nr1_y := r1.Bottom - ueberlapp_hoehe; end; end; for x := 0 to (ueberlapp_breite-1) div 2 do begin for y := 0 to (ueberlapp_hoehe -1) div 2 do begin farbenr1 :=B1.Canvas.Pixels[ueberlapp_nr1_x+x*2,ueberlapp_nr1_y+y*2]; farbenr2 :=B2.Canvas.Pixels[ueberlapp_nr2_x+x*2,ueberlapp_nr2_y+y*2]; if ( farbenr1 <> b1.TransparentColor) and (farbenr2 <> b2.TransparentColor) then begin result:=True; exit; end; end; // for y end; // for x result:=False; end; // kollision Ich nutzte sowieso eigentlich nur Vierecke. Aber für den Fall der Fälle habe ich so eine Funktion eingebaut. Per Default Paramenter wird immer eine Pixel Check Prüfung durch gefürht sowie ein Event ausgelöst. Was beides aber abgestellt werden kann. Ich habe die "2D Engine" geschrieben für einfache 2D Spiele. Ich rechne nicht damit das ein Spiel 10000 Objekte hat. Dafür sollte besser Andorra oder so genutzt werden. Ich denke die Collisions Funktion dürfte für die meisten Spiele ausreichen oder ? |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Das ganze ist zwar soweit schon deutlich besser, wenn auch recht wenig auf Performance optimiert, jedoch bleibt der wichtigste Punkt offen:
Was passiert, wenn ein 10*10 Pixel großes Sprite kurz vor einem anderen 5*5 Pixel großem Sprite steht, sich aber mit sagen wir mal 10 Pixel pro Bild darauf zu bewegt? Das Sprite überspringt das andere, und die eigentlich stattfindende Kollision wird nicht erkannt. Darüber hinaus liefert deine Methode trotz ihrer Aufwendigkeit nur die Information "Kollision" (das aber wie gesagt nichtmal verlässlich), wogegen mein Ansatz quasi nebenbei auch gleich weiter nutzbare Größen ausspuckt, über die man den Stoß gleich mit berechnen kann, und zudem IMMER eine Kollision entdeckt, selbst wenn sich ein Sprite mit drei Bildschirmbreiten pro Bild schnell bewegen würde, und die "Wand" nur einen Pixel breit ist. DAS ist doch der Punkt um den es mir geht! |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
hey,
sry ich blick jetzt nicht mehr durch sry kann mir bitte jetzt einer erklären wie ich dass machen soll? wäre super nett =) GN8 Domi |
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
Sag uns doch bitte nochmal ganz genau was du vor hast, und wo ganz genau das Problem liegt, und was du evtl. schon probiert hast.
|
Re: Break-Game, Kugel auf Rechtecklanden lassen ...
hey,
Das Problem liegt bei dem ab brallen, die Idee von der Grafik hat mich sehr überzeugt leider nicht hinbekommen, deshalb hab ich ja gefragt. würde mich sehr freuen wenn mir ihr jemand ein Beispiel oder ein gut Kommentierten Code Posten könnte. So das der Ball ab brallt in in dem bestimmten errechneten Winkel zurück brallen lässt. Mfg Domi |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:46 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz