| Autor |
Beitrag |
mimi 
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Di 01.07.03 19:48
@umpani
nach dem die kolisions funktion mit kreisen und dreicken prima funktioniert wollte ich noch gere das sie schaut ob ein quadrat bzw. rechtect im weg ist... aber mit der gleichen procendure wir oben:)
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
umpani
      
Beiträge: 389
|
Verfasst: Di 01.07.03 20:31
Hallo,
da ich die Kollisionsabfrage mit Pixelvergleichen mache, müsste es doch eigentlich egal sein, was für eine geometrische oder nichtgeometrische Form die Figur hat.
Funktioniert es denn nicht?
Ach ja, ich werde mich morgen mit dem "Schussproblem" befassen.
Gruß Umpani
_________________ Lernen, ohne zu denken, ist eitel; denken, ohne zu lernen, ist gefährlich. Konfuzius
|
|
mimi 
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Di 01.07.03 21:13
was für ein schluss problem ?
nein, getestet habe ich das noch nicht, ich dachte halt das diese funktion nur bei greißen und drei ecken funktioniert....
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
mimi 
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: So 02.05.04 09:18
ich wollte gerade deine collisions funktions in ein andres projekt übertragen und es funktiont dort leider nicht
hier der code:
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: 188:
| function TGame.kollision(nr1,nr2,nr1x,nr1y,nr2x,nr2y, pat1,pat2:integer):boolean; var ueberlapp_breite, ueberlapp_hoehe:integer; ueberlapp_nr1_x, ueberlapp_nr1_y, ueberlapp_nr2_x,ueberlapp_nr2_y:integer; x,y:integer; nr1_breite, nr2_breite, nr1_hoehe, nr2_hoehe:integer; farbenr1,farbenr2:tcolor; begin farbenr1:=clBlack; farbenr2:=clBlack; ueberlapp_nr1_x:=-1; ueberlapp_nr1_Y:=-1;
ueberlapp_nr2_x:=-1; ueberlapp_nr2_Y:=-1;
if (ListImage.Items[nr1].PatternWidth = 0 ) then begin nr1_breite := ListImage.Items[nr1].Width; nr1_hoehe := ListImage.Items[nr1].Height; end else begin nr1_breite := ListImage.Items[nr1].PatternWidth; nr1_hoehe := ListImage.Items[nr1].PatternHeight; end; if (ListImage.Items[nr2].PatternWidth = 0 ) then begin nr2_breite := ListImage.Items[nr2].Width; nr2_hoehe := ListImage.Items[nr2].Height; end else begin nr2_breite := ListImage.Items[nr2].PatternWidth; nr2_hoehe := ListImage.Items[nr2].PatternHeight; end;
kollision := false; if nr1x < nr2x then ueberlapp_breite := (nr1x + nr1_breite) - (nr2x) else ueberlapp_breite := (nr2x + nr2_breite) - nr1x; if nr1_breite > nr2_breite then if ueberlapp_breite >= nr2_breite then ueberlapp_breite := nr2_breite;
if nr1y < nr2y then ueberlapp_hoehe := (nr1y + nr1_hoehe) - (nr2y) else ueberlapp_hoehe := (nr2y + nr2_hoehe) - (nr1y); if nr1_hoehe > nr2_hoehe then if ueberlapp_hoehe > nr2_hoehe then ueberlapp_hoehe := nr2_hoehe;
if (ueberlapp_breite > 0) and (ueberlapp_hoehe > 0) then begin if nr1_breite >= nr2_breite then begin if (nr2x+nr2_breite) >= (nr1x+nr1_breite) then begin ueberlapp_nr1_x := nr1_breite - ueberlapp_breite; ueberlapp_nr2_x := 0; end; if ((nr2x+nr2_breite) < (nr1x+nr1_breite)) and (nr2x >= nr1x)then begin ueberlapp_nr1_x := (nr2x-nr1x); ueberlapp_nr2_x := 0; end; if (nr2x) < (nr1x) then begin ueberlapp_nr1_x := 0; ueberlapp_nr2_x := nr2_breite - ueberlapp_breite; end; end; if nr1_breite < nr2_breite then begin if (nr1x+nr1_breite) >= (nr2x+nr2_breite) then begin ueberlapp_nr2_x := nr2_breite - ueberlapp_breite; ueberlapp_nr1_x := 0; end; if ((nr1x+nr1_breite) < (nr2x+nr2_breite)) and (nr1x >= nr2x)then begin ueberlapp_nr2_x := (nr1x-nr2x); ueberlapp_nr1_x := 0; end; if (nr1x < nr2x)then begin ueberlapp_nr2_x := 0; ueberlapp_nr1_x := nr1_breite - ueberlapp_breite; end; end;
if nr1_hoehe >= nr2_hoehe then begin if (nr2y+nr2_hoehe) >= (nr1y+nr1_hoehe) then begin ueberlapp_nr1_y := nr1_hoehe - ueberlapp_hoehe; ueberlapp_nr2_y := 0; end; if ((nr2y+nr2_hoehe) < (nr1y+nr1_hoehe)) and (nr2y >= nr1y)then begin ueberlapp_nr1_y := (nr2y-nr1y); ueberlapp_nr2_y := 0; end; if (nr2y) < (nr1y) then begin ueberlapp_nr1_y := 0; ueberlapp_nr2_y := nr2_hoehe - ueberlapp_hoehe; end; end; if nr1_hoehe < nr2_hoehe then begin if (nr1y+nr1_hoehe) >= (nr2y+nr2_hoehe) then begin ueberlapp_nr2_y := nr2_hoehe - ueberlapp_hoehe; ueberlapp_nr1_y := 0; end; if ((nr1y+nr1_hoehe) < (nr2y+nr2_hoehe)) and (nr1y >= nr2y)then begin ueberlapp_nr2_y := (nr1y-nr2y); ueberlapp_nr1_y := 0; end; if (nr1y < nr2y)then begin ueberlapp_nr2_y := 0; ueberlapp_nr1_y := nr1_hoehe - ueberlapp_hoehe; end; end;
for x := 0 to (ueberlapp_breite-1) div 4 do for y := 0 to (ueberlapp_hoehe -1)div 4 do begin if (pat1 = 0) and (ListImage.Items[nr1].PatternWidth = 0 ) then begin farbenr1:=ListImage.Items[nr1].picture.Bitmap.Canvas.Pixels[ueberlapp_nr1_x+x*4,ueberlapp_nr1_y+y*2]; end; if (pat2 = 0) and (ListImage.Items[nr2].PatternWidth = 0 )then begin farbenr2:=ListImage.Items[nr2].picture.Bitmap.Canvas.Pixels[ueberlapp_nr2_x+x*4,ueberlapp_nr2_y+y*2]; end; if (pat1 >= 0) and (ListImage.Items[nr1].PatternWidth > 0 ) then begin farbenr1:=ListImage.Items[nr1].PatternSurfaces[pat1].Canvas.Pixels[ueberlapp_nr1_x+x*4,ueberlapp_nr1_y+y*2]; end;
if (pat2 >= 0) and (ListImage.Items[nr2].PatternWidth > 0 ) then begin farbenr2:=ListImage.Items[nr2].PatternSurfaces[pat2].Canvas.Pixels[ueberlapp_nr2_x+x*4,ueberlapp_nr2_y+y*2]; end;
if ( farbenr1 <> ListImage.Items[nr1].TransparentColor) and (farbenr2 <> ListImage.Items[nr2].TransparentColor) then kollision := true; end; ListImage.Items[nr1].Restore; ListImage.Items[nr2].Restore; end;
end;
function TGame.CheckCollision:Boolean; var i:Integer; begin result:=False; for i:=0 to high(Items) do begin result:=kollision( ListImage.Items.Find(items[i].Name).Index, ListImage.Items.Find('u-boot.bmp').Index,items[i].x,items[i].y,player.x,player.y,0,1); exit; end; end;
procedure TGame.MovePlayer(richtung:Integer); begin if not CheckCollision then begin if Player.x+dirs[richtung].x >= 0 then Player.x:=(Player.x+dirs[richtung].x);
if Player.y + dirs[richtung].y >=0 then Player.y:=Player.y+dirs[richtung].y else Player.y:=Player.y;
Player.richtung:=richtung; end; end; |
es wird kein zusammenstoß gemledet... kann es dein, das es dranliegt, das ich scrollen kann in meinen spiel ???
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
umpani
      
Beiträge: 389
|
Verfasst: So 02.05.04 09:56
tu mir einen gefallen und schick mir das ganze projekt per email:
benno@bekr.de
Ich werde es mir dann morgen mittag mal anschauen.
Gruß Umpani
_________________ Lernen, ohne zu denken, ist eitel; denken, ohne zu lernen, ist gefährlich. Konfuzius
|
|
mimi 
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: So 02.05.04 10:17
habs dir gesendet bzw. bin dabei..... vielen dank für deine hilfe.... das komische ist, immer nur das erste objekt wird in der collisions abfrage anerkann, warum ??? und wenn du von unten an das objekt rankommst gehts auch nicht....
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
MathiasH
      
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: So 02.05.04 11:50
schonmal auf die Idee gekommen für jedes Objekt einfach
a) eine verkleinerte Kollisionsmaske anzulegen, also ein array of Boolean, das für etwa jeden 2. bis 4. Pixel pro Zeile /Spalte einen wert enthält
b) statt dieser maske die vorderseite des objekts als array von punkten zu speichern, sobald ein schuss knapp hinter diese linie gelangt ist es ein treffer
allgemeiner könnte man für zweiteres auch eine Polygon-Polygon Kollisionsabfrage basteln, also kein punkt darf im Inneren des anderen Polygons liegen. Die einfachere Methode dafür wäre dann mit mehreren Dreiecke, da ist die Abfrage Leichter na man nur Punkt Dreieck kollision machen muss
_________________ "Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
|
|
mimi 
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: So 09.05.04 07:19
kannst du mal bitte ein kleines beispiel schreiben ???
ich arbeite im 2D bereich..... und wie gesagt mit delphiX für Delphi 7
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
MathiasH
      
Beiträge: 699
WinXP, Win98SE, Debian, Win95
D5 Stand, D6 Prof
|
Verfasst: So 09.05.04 10:28
Also hier nun etwas Anleitung zu Vorschlag b (a sollte keine weiteren Erklärungen brauchen)
Ziel ist, herauszufinden, ob ein Punkt von Objekt B(grün) in A ist oder Umgekehrt man überprüft also für jeden Punkt ob er in dem jeweils anderen polygon liegt. Da poly-point kollision etwas schwierig ist kann man jedoch das polygon in Dreiecke unterteilen (graue linien). eine Kollision zwischen einem dreiech und einem Punkt ist dann wieder recht einfch, google einfach mal nach POINT POLYGON INTERSECTION, da solltest du das richtige finden können
diese technik sollte allerdings nicht eingesetzt werden, wenn der fall eintreten kann, das sich 2 objekte zwar schneiden, aber keinen Eckpunkt in der Gläche des jeweils anderen Polygons haben (Beispiel - schneidet |, in etwa so: t sie haben also keine eckpunkte im anderen polygon. In diesem (seltenen) Fall müsste man zusätzliche dreiecke einfügen damit die Kollision verlässlich arbeitet.)
MathaisH
_________________ "Viel von sich reden, kann auch ein Mittel sein, sich zu verbergen."
Friedrich Nietzsche
|
|
mimi 
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Fr 25.01.08 20:49
Ich weis der Letzte Beitrag ist eine zeit Lang her, aber ich möchte hier meine Variante der Collisions Funktion von "umpani"
vorstellen. Da ich schon zeit längere zeit kein DelphiX mehr nutze musste ich diese Funktion anpassen.
Mitlerweile nutze ich Lazarus unter Linux(Ubuntu 7.04). Zu diesen zweck habe ich diese Funktion verändert.
Ich hoffe umpani hat nix dagegen. Wenn alle Tests Positiv sind möchte ich diese Funktion in meiner 2D Engine einbauen.
Natürlich prüfe ich nicht ständig sondern nur, wenn ein Viereck in ein anders schon drin ist. Zuerst wird diese Funktion
aufgerufen:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| function TForm1.collision(const px, py: Integer; aGenger:TGameItem):Integer; var r:TRect; r2:TRect; z:integer; t:Boolean; begin z:=-1; r:=rect(px,py,px+Player.Width,py+player.Height); if IntersectRect(r2,aGenger.GetR,r) then begin
t:=kollision(rect(px,py,Shot.Width,Shot.Height),rect(Gegner.Left,Gegner.top,gegner.Width,Gegner.Height),Shot.SpriteImage,Gegner.SpriteImage); if t then begin z:=1; writeln('TESTSS'); end; end; result:=z; end; |
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:
| function TForm1.kollision(r1,r2:TRect;B1,b2:TBitMap):boolean; var nr1_x, nr1_y:integer; nr2_x, nr2_y:integer; ueberlapp_breite, ueberlapp_hoehe:integer; ueberlapp_nr1_x, ueberlapp_nr1_y, ueberlapp_nr2_x, ueberlapp_nr2_y:integer; x,y:integer; kol:boolean; picture:tpicture; farbenr1,farbenr2:TColor; begin kollision := 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 <> b1.TransparentColor) then kollision := true; end; end; end; |
Natürlich werde ich dich" umpani" in meinem Spiel(evlt. auch in der engine, wenn ich diese Funktion einbaue) als
Mit Autor erwähnen !
Du musst mir nur sagen was für Daten da von dir rein sollen.
Ich würde sonst nur:
Die Pixel Genaue Kollisions Funktion die ich verwende und Verändert habe stammt von "umpani"
aus dem DelphiForum: www.delphi-forum.de/...der=asc&start=20
Ich hoffe ich habe kein Fehler gemacht. Bisher scheint alles zu klappen. Vielen Dank noch mal für diese Tolle Funktion "umpani". Ich habe diese Funktion an meinem Schreibt Styl noch angepasst wie dir noch auffallen wird.
Was ich jetzt von euch noch toll finden würde, wenn diese Funktion Optimiert würde. Sofern das überhaupt geht.
Ich finde es immer toll wenn uralte Thread wieder zum Vorschein kommen.... ihr nicht ?
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Fr 25.01.08 21:27
umpani hat folgendes geschrieben: | | Farbvergleiche sind viel genauer als wenn man nur die Körpergeometrie berechnet. |
err...
Warum sollte ein Farbvergleich genauer sein als eine mathematische Berechnung?^^
Die Mathematik ist schliesslich exakt^^ (bis auf die Rechenungenauigkeit von Extended maximal)
Ich würde das Problem zuerst einmal aufsplitten:
Wann gibt es eine Kollision?
 Kreis in Dreieck
 Dreieck in Kreis
 Kreis schneidet Dreieck
Wann ist Dreieck in Kreis? Solltest du schaffen^^
Wann ist Kreis in Dreieck?
 Wenn der Mittelpunkt drin ist.
Dein Dreieck besteht aus drei Geraden. Eine oder zwei müssen überschritten werden,
die anderen unterschritten:
Y >= m*X + b
Y >= m*X + b //jeweils m1,m2,m3,b1,b2,b3...
Y <= m*X + b...
wenn alle drei Bedingungen erfüllt sind liegt dein Punkt im Dreieck.
Ob eine Gerade unter- oder überschritten werden muss entscheidest du darüber, ob der
Mittelpunkt sie über- oder unterschreitet...
Wann schneidet Kreis Dreieck?
Wie gesagt hast du drei Geraden...
 Du berechnest die Schnittpunkte mit allen drei Geraden.
Wenn keine Gerade geschnitten wird kannst du schon aufhören, result := false.
 Nun überprüfst du die Schnittpunkte darauf, ob sie im(auf) dem Dreieck liegen,
s.o.
Wie berechnet man die Schnittpunkte von Kreis und Gerade?
 Kreisformel: (X - Xm)² + (Y - Ym)² = r²
 Gerade: Y = m*X + b
 (X - Xm)² + ((m*X + b) - Ym)² = r²
 nach X auflösen und mit pq-Formel ausrechnen überlasse ich dir
P.S.:Wenn es um ein Schulprojekt geht ist wohl die mathematische Lösung gefragt...
Edit: Aso, Credits, dann wohl kein Schulprojekt^^
|
|
Hidden
      
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Fr 25.01.08 21:36
Titel: Farbmethode
Ich weiss, ihr seid schon sehr weit auf de Weg...
trotzdem mal:
Was ist überhaupt der Vorteil?
Mathe ist glaub' ich schneller und eventuell exakter,
ich muss hier mal kurz meine Ahnungslosigkeit konstatieren
programmiere selber erst ca. 5 Wochen und versuche gerade, meinem lahmen Kurs
davonzulaufen^^
(Was ich glaub' ich bereits ein paar Mal geschafft habe^^)
|
|
F34r0fTh3D4rk
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Fr 25.01.08 21:40
Ich weiß nicht, ob's schon vorgeschlagen wurde:
www.delphi-library.d...iewtopic.php?t=71497
aber da gibt es auch ein Kapitel über Polygone und Kreise.
mfg
|
|
mimi 
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Sa 26.01.08 12:23
Der Pixel Vergleich hat den Vorteil das es universal ist. Wenn ich sowas auf den "Mahte" Weg lösen, ist es meistens auf ein Object abgestimmt oder ?
Es sei denn du/ihr beweist mir das gegenteil ! Ich möchte nicht immer bei jedem Object Viel Vorarbeit haben.
Das Ziel ist es eine einfache Funktion die unversal auf kleine Objekte losgelassen werden kann. Meine Objekte sind alle nicht so Groß. Und ich mache das ja auch nur wenn der zweiten stufe...
Mit Optimierung meinte ich halt, ob diese Funktion verbessert werden kann, oder schneller gemacht werden kann.
edit: Das Tutorial habe ich mir schon durch gelesen und kann damit nicht viel anfangen...
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
F34r0fTh3D4rk
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Sa 26.01.08 16:55
mimi hat folgendes geschrieben: | | edit: Das Tutorial habe ich mir schon durch gelesen und kann damit nicht viel anfangen... |
In wie fern ? Verständnismäßig oder von dem was das SAT leistet ?
mfg
|
|
mimi 
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Sa 26.01.08 17:04
Ich verstehe das so, das man für jede Form ein eigene Formel braucht. Und das ist mir bei einem kleinen spiel doch zu aufwendig.
Bei einem Größeren mag das ja Praktisch sein.... oder ich verstehe da was nicht.
Im Tutorial selbst wird immer von Kreisen und Dreiecken gesprochen, aber ich habe sowas nicht.
Ich werden BitMaps. Aufjedenfall konnte ich noch keine eigene Kollsisions Funktion schreiben die eine art Poliyon verarbeitet:
ich lese das Bitmap ein alle Punkte die eine bestimmte Farbe haben kommt in eine Liste und wird als eine Datei geschrieben.
Dann müsste nur noch die zwei Objekte miteinernader verglichen werden. Aber naja, so wie ich das jetzt habe reicht mir das. So viele Objekte habe ich nicht, das es zu langsam sein könnte.
Also meint ihr die Funktion von oben kann nicht weiter Optimiert werden ? Außer das Prinzip zu verändern ?
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
F34r0fTh3D4rk
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Sa 26.01.08 17:21
Das Separating Axis Theorem funktioniert für beliebige konvexe Polygone, ohne eine Zeile Code ändern zu müssen.
Anwendungsbeispiel: www.exec-dev.de/Downloads/ActionPong.zip
mfg
|
|
mimi 
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: So 27.01.08 14:13
Oh ! Danke für dein Beispiel ! Leider habe ich keine E-Mail bekommen von deiner Antwort, kann auch sein, das ich sie übersehen habe... naja... ich werde es mir mal ansehen, evelt. ist es eine alternative, dann nehme ich beides *G*
für meine 2D Engine.
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
mimi 
      
Beiträge: 3458
Ubuntu, Win XP
Lazarus
|
Verfasst: Fr 01.02.08 13:48
Ich habe mir das beispiel angesehen, ist leider ohne Soruce... also für mich nicht brauchbar...
Ich habe noch ein kleinen BUG gefunden, heute:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| 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; end; |
und zwar die if abfrage, (farbenr2 <> b2.TransparentColor) da war vorer b1 das habe ich jetzt zu b2 geändert.
somit können die Bilder Unterschiedliche Tranzparent Farben haben.
Hier noch mal die Ganze Funktion:
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:
|
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; end; result:=False; end; |
Ich hoffe da sind nicht noch mehr Fehler drin versteckt *G* bzw. das ich neue eingebaut habe, ich musste ja alle Variablen verändert die in den Parametern angeben waren.
Ich verwende diese Funktion jetzt in meiner "2D Engine". Dort habe ich sie heute eingebaut. Für kleine Objekte genau das richtige, für Größere evlt. nicht.
_________________ MFG
Michael Springwald, "kann kein englisch...."
|
|
F34r0fTh3D4rk
      
Beiträge: 5285
Erhaltene Danke: 29
Win Vista (32), Win 7 (64)
Eclipse, SciTE, Lazarus
|
Verfasst: Fr 01.02.08 14:02
mimi hat folgendes geschrieben: | | Ich habe mir das beispiel angesehen, ist leider ohne Soruce... also für mich nicht brauchbar... |
Den Source hast du doch schon:
wiki.delphigl.com/in...arating_Axis_Theorem
Beispiel-Sources:
hier wiki.delphigl.com/in...lygon_.3C.3E_Polygon
hier wiki.delphigl.com/in...Kreis_.3C.3E_Polygon
und hier wiki.delphigl.com/in...ennung_von_Polygonen
mfg
|
|
|