Kollisionsabfrage mittels imagescollide !
Übersicht

![]() |
OxcomBetreff: Kollisionsabfrage mittels imagescollide ! |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo zusammen,
nachdem ich nun auch meinen Level auslagern und einlesen kann, hänge ich an der Kollisionsabfrage fest. Ich habe ein animiertes Image mit 8 Frames und ein Tileset ( ebenfalls via loadanimage ) mit 32 verschiedenen Frames für die einzelnen Level Tiles. Wie kann ich denn nun mittels imagescollide jedes der 32 Frames abfragen ? Beispielsweils gibt es auch Tiles in den 32 Frames, in denen man hindurchlaufen können soll. Man muss ja hoffentlich nicht 32 Abfragen schreiben oder ? ![]() Gruss Oxcom |
||
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF |
![]() |
Justus |
![]() Antworten mit Zitat ![]() |
---|---|---|
1. Du weißt ja, welche Animationsstufe für deine Spielfigur gerade genutzt wird --> nur 1 Durchgang für deinen Hauptheini.
2. Du weißt, wo sich dein Spieler befindet --> außerdem weißt du, wo sich welche Tiles befinden. Und du weißt, wo sich der Spieler befindet --> nur die undurchlässigen Tiles in der Umgebung des Spielers überprüfen. 3. Und wenn sich der Spieler gerade nur horizontal bewegt, kannst du auch nochmal ne Menge Tiles ausschließen. usw. Diese Optimierung ist sicher keine leichte Aufgabe, aber sie würde sich sicher lohnen. |
||
![]() |
Oxcom |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hallo zusammen !
Um nochmal auf dieses Thema zurückzukommen: Ich habe gestern den ganzen Tag mit den Funktionen imagescollide und collideimage verbracht und keine vernünftige Abfrageroutine für mein Problem gefunden. ![]() Meiner Meinung nach sind für mein beschriebenes Problem beide Funktionen nicht sonderlich geeignet. Man stelle sich vor: Ich habe ein Tileset mit 32 Tiles via loadanimage für die Gestaltung eines Labyrinths definiert. Dann die ganze Map als Datei im Mainprogramm geladen. Funktioniert soweit sehr gut. imagescollide und collideimage beziehen sich auf festgelegte Koordinaten ... egal ob dort tatsächlich ein Image gezeichnet ist oder nicht ! In dieser Koordinate werden letztendlich nur die Dimensionen für das angegebene Frame berücksichtigt ... auch wenn dort das betreffende Frame gar nicht gezeichnet ist. Wäre doch wesentlich komfortabler als Bezugspunkt die Imagebezeichnung und den gewünschten Frame zu verwenden. Grösse und Frameanzahl werden doch via loadanimage so oder so gespeichert. Somit müsste die Funktion flexibel jede Kollision unabhängig von festgelegten Koordinaten fesstellen sobald sich Pixel beider Images überlappen oder kollidieren. Ich bin trotz allem noch ein Noob und fände die Eigenschaft recht sinnvoll im Spielebereich. Wäre auf der anderen Seite wahrscheinlich auch eine Frage der Performance. Wie auch immer. Ich kann doch nicht mit diesen Funktionen jedes einzelne Tile abfragen. Da ist die Performance bereits bei 30 Prozent der Fertigstellung aufgrund horrender Abfragen im Keller. Manche Tiles kommen stellenweise 30 mal verteilt an den verschiedensten Positionen vor. Eigentlich wollte ich immer nur nach dem Prinzip: spielfigur + x pixel prüft kollision mit tile x abfragen. Bisher ohne Erfolg. ![]() imagescollide und collideimage wären in Ordnung bei Levels mit wenigen Elementen. Beispiel ein Labyrinth mit 4 rechteckigen Objekten. Man bezieht sich nur auf die Koordinaten und den Rest übernimmt die Funktion. Es müssen keine Schenkelmasse manuell abgefragt werden. Wie würdet Ihr mein Problem lösen ? Bin für jede Hilfe dankbar und erwarte auch keinen vollständigen Quellcode. Man muss schon selber irgendwie drauf kommen aber ein kleines Fundament sollte man da als Noob schon haben. Schon alleine dem Zeitfaktor zuliebe. Dafür dürft Ihr mein Spiel dann irgendwann auch mal spielen ! Versprochen ! ![]() |
||
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF |
![]() |
Oxcom |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wirklich keine Idee ? ![]() |
||
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF |
![]() |
rema |
![]() Antworten mit Zitat ![]() |
---|---|---|
Wen man eine Spielfigur hat, und so auch die Position im Tilemap, so kann man nur die Positionen ermitteln die auch relevant sind für eine Kollision. Da sollte es in BlitzBasic haufenweise Dokus und Examples haben. | ||
![]() |
Oxcom |
![]() Antworten mit Zitat ![]() |
---|---|---|
So weit verstanden. Nur um nochmals Zweifel aus dem Weg zu räumen:
Wenn ich ein Image mit 32 Frames mittels loadanimage für die Levelumgebung geladen habe ... dann sprechen wir doch von Tiles oder gibt es dafür eine andere Funktion ? Gruss Oxcom |
||
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF |
![]() |
Oxcom |
![]() Antworten mit Zitat ![]() |
---|---|---|
rema hat Folgendes geschrieben: Wen man eine Spielfigur hat, und so auch die Position im Tilemap, so kann man nur die Positionen ermitteln die auch relevant sind für eine Kollision. Da sollte es in BlitzBasic haufenweise Dokus und Examples haben.
Falls es in Blitzmax verwandt zutreffende Funktionen geben sollte. Ansonsten wären die Tutorials nicht besonders hilfreich. Den Sinn oder die Theorie habe ich schon verstanden. Auch habe ich diesbezüglich schon in Blitzbasic und Artverwandte gesucht ... aber die Funktionen scheinen sich dennoch so manchmal stark und nicht anwendbar in Blitzmax zu unterscheiden. Keine Frage ... ich werde jedenfalls alle möglichen Tutorials zu diesem Thema nochmals prüfen. Ansonsten muss ich nochmal auf mein Problem zurückkommen. Nicht zu vergessen: Bin noch ein Noob und bin somit auf die Hilfe der fortgeschrittenen Coder abhängig ... falls nicht selbst gelöst. Jedenfalls bin ich der Letzte, der aus Bequemlichkeit heraus nur den Rat in Foren sucht. Damit bleibt der Lernfaktor sicherlich auf der Strecke. Ich bleibe dran. Gruss Oxcom |
||
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Meinste net, es wäre vielleicht ein Versuch wert in die Examples zu gucken die mit der Vollversion kommen?
Da ist so ziemlich alles drin was die grundlegenden Techniken betrifft. Teils sogar hochstehende Dinge. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Oxcom |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich habe bisher leider nur die Trial Version. Und in diesen Examples habe ich keine einzige Kollisionsabfrage mittels imagescollide oder collideimage gesehen. Zumindest nicht bei den für mein Problem in Frage kommenden Beispielen. Habe mir gestern einen ganzen Stapel von Blitzbasic Tutorials ausgedruckt. Werde ich mir dann am WE anschauen.
Gruss Oxcom |
||
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Nun, ich denke eine kurze Einführung wäre vielleicht hilfreich, wobei ich denke das es hier in der FAQ schon sowas hat:
alte Blitz -> BM hat sich ja insofern grundlegend geändert, dass nun 32 parallel operierende Kollisionsebenen hat, nicht mehr nur eine wie früher. Als Folge davon kann man mittels CollideImage / CollideRect stark optimierte Kollisionssysteme machen, wenn man viele unbewegliche Objekte hat, da man in diesem Falle die Kollisionsdaten nur 1x erzeugen muss und die für den Rest ihrer Existenz unangetastet lassen kann. Dazu wählt man einfach einen Layer für die Tile Ebene und zeichnet dort die Kollisionsdaten rein (das heisst beim Coll Write gibt man diesen Layer an, Coll Read brauchts nicht, sie sollen ja selbst nicht kollidieren mit was anderem). Beim ResetCollisions darf dieser Layer dann nicht gelöscht werden. Dadurch kannst du dir da schon sehr viel Zeit sparen. Um nun die Kollision von beweglichen Objekten zu machen, nimmst du einen anderen Layer, wo die dynamischen Objekte ihre Kollisionsdaten reinschreiben. Beim Coll Read jedoch nutzt du beide Layer um auf Kollision zu überprüfen, also den Layer der Tiles als auch den der dynamischen Daten (mit | die Layerkonstanten verknüpfen). Wenn du nun ResetCollisions aufrufst, dann tust du dies lediglich mit Layern in welchen dynamische Daten gespeichert sind. ImageCollide nutzt man vor allem dann, wenn man nur wenige Objekte hat, die mit einander kollidieren können und schon vorher sagen kann, was potentiell übehaupt mit einander kollidieren kann. Hier gibst du direkt die beiden Bildobjekte an, die mit einander kollidieren, es wird keine automatische Kollision ausgeführt. Beispiele für einen solchen Fall wäre zum Beispiel ein Spiel im Sinne des alten Ping-Pong oder AirHockey (2 Bretter, 1 Ball), wo nur 2 Kollisionen zu prüfen sind und CollideImage viel zu viel "mehrarbeit" verursacht durch die jedes Frame aufzurufende CollisionReset und Kollisionsneuzeichnung. Ich kann dir bei anderer Gelegenheit sonst noch ein Beispiel liefern, dass dir die effiziente Nutzung der mächtigen CollideImage / Rect Funktionen zeigt. EDIT Muss mich korrigieren. Hab grad nochma in die Hilfe geguckt. ImageCollide bringt scheinbar eigentlich garnix ... da es gemäss Hilfe auf dem Collision Layer 32 läuft, läuft es auch übers gleiche System ... es bringt insofern nicht wirklich etwas, ausser das man explizit 2 Bilder gegeneinander testet, anstatt das man das Bild gegen jedes beliebige Objekt testet und das Rückgabeobjekt auswertet. Vermute ist hauptsächlich zur Abwärtskompatibilität mit den alten Blitz drin ... |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Oxcom |
![]() Antworten mit Zitat ![]() |
---|---|---|
Danke Dir für deine Einführung. Dann bin ich wenigstens mit meiner Meinung über imagescollide schon mal gar nicht falsch gelegen ... immerhin ein kleiner Fortschritt. collideimage scheint dann wohl doch etwas komplizierter zu sein.
Zitat: Ich kann dir bei anderer Gelegenheit sonst noch ein Beispiel liefern, dass dir die effiziente Nutzung der mächtigen CollideImage / Rect Funktionen zeigt.
Wäre sicherlich sehr hilfreich. Gruss Oxcom |
||
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF |
Dreamora |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ganz im Gegenteil. CollideImage ist einfacher. Es schreibt einfach die aktuellen Bilddaten (inkl Rotation und Skalierung) in einen "Kollisionsspeicher", wobei es 32 verschiedene Kollisionsspeicher gibt. (den / die Kollisionsspeicher gibst du beim Write Parameter an)
Wenn du dann schauen willst, ob eine Kollision in einem bestimmten Layer geschehen ist, testest du das Mittels der Verwendung der entsprechenden Layer Konstante im Read Parameter. Wenn du alle Kollisionsdaten aus einem Layer löschen willst, dann nutzt du ResetCollisions mit dem entsprechenden Layer. Das spezielle ist, dass du bei CollideImage ein Objekt mitangeben kannst, wenn du das Objekt in den Layer schreibst. Wenn später eine Kollision erkannt wirst, erhälst du eine Liste mit allen vorher angegebenen Objekten (das Objekt muss nicht das Bild sein, du könntest zb einen Type Spieler haben der zurück gegeben wird) die du mit for EachIn durchwandern kannst. Das erlaubt viel mächtigere und besser strukturierte Kollisionsbehandlung als es in den alten Blitz je möglich war. Hat halt eine kurze eingewöhnungszeit. (wenn man sich das ganze Mal mit einem Blatt Papier überlegt ist es eigentlich einleuchtend und simpel, wie es funktioniert) Mit der alten Blitz Variante müsstest du jedes Bild mit jedem Bild testen um jede mögliche Kollision zu finden und selbst dann noch einmal in allen type listen suchen, wofür das Bild genau steht wenns nicht ein global bild war. |
||
Ihr findet die aktuellen Projekte unter Gayasoft und könnt mich unter @gayasoft auf Twitter erreichen. |
![]() |
Oxcom |
![]() Antworten mit Zitat ![]() |
---|---|---|
So ... heute ist wieder Wochenende und der brave Oxcom wird wieder fleissig lernen und ausprobieren ! ![]() Gruss Oxcom |
||
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF |
![]() |
Oxcom |
![]() Antworten mit Zitat ![]() |
---|---|---|
Da bin ich wieder ! ![]() Ich habe nun eine Kollisionsabfrage herausgefunden. Der Geist bewegt sich im Labyrinth noch ein bisschen planlos herum ... erkennt aber jede Kollision. Ich habe beim Speichern der Mapdaten in einem Array alle Kollisionslayer ebenfalls gespeichert. Möglicherweise nicht ganz performanceschonend. Was sagen die Experten ? Nachfolgend der aktuelle Code mit den Images: ![]() ![]() Code: [AUSKLAPPEN] Strict Incbin "granim.png" Incbin "maze.png" SeedRnd MilliSecs() Graphics 800,600,0 Global ghostred:TImage=LoadAnimImage("granim.png",14,14,0,8) Global mazetile:TImage=LoadAnimImage("maze.png",8,8,0,36) Global map:Int[28,31] Global x:Int = 5 ' startposition x Global y:Int = 5 ' startposition y Global count = 0 ' zaehler framewechsel Global framegrr = 2 ' startframe ghostred rechts Global framegrl = 0 ' startframe ghostred links Global framegru = 4 ' startframe ghostred oben Global framegrd = 6 ' startframe ghostred unten Global timer = 0 ' zaehler zufallsrichtungsswechsel Global rndirection = Rnd(4) ' zufallsrichtung If ghostred = Null Then DebugLog "ghostred kann nicht geladen werden" End If mazetile = Null Then DebugLog "maze kann nicht geladen werden" End ResetCollisions ' leveldaten in array speichern Local mapx = 0 Local mapy = 0 For mapy = 0 To 30 For mapx = 0 To 27 ReadData map[mapx,mapy] DrawImage(mazetile,mapx*8,mapy*8,map[mapx,mapy]) CollideImage mazetile,mapx*8,mapy*8,map[mapx,mapy],0,1 ' kollisionslayer speichern Next Next Repeat DrawText "Horizontal: "+x,400,10 ' anzeige der aktuellen x position DrawText "Vertikal: "+y,400,30 ' anzeige der aktuellen y position Local oldx:Int Local oldy:Int oldx = x ' x position speichern oldy = y ' y position speichern ' leveldaten auslesen und darstellen For mapy = 0 To 30 For mapx = 0 To 27 DrawImage(mazetile,mapx*8,mapy*8,map[mapx,mapy]) Next Next ' abfrage timer zufallsrichtungswechsel If timer = 40 rndirection = Rnd(4) timer = 0 Else ' zufallsrichtungen ghostred Select rndirection Case 0 DrawImage(ghostred,x,y,framegrr) If count = 9 count = 0 framegrr:+1 If framegrr = 4 framegrr = 2 count:+1 x:+1 Case 1 DrawImage(ghostred,x,y,framegrl) If count = 9 count = 0 framegrl:+1 If framegrl = 2 framegrl = 0 count:+1 x:-1 Case 2 DrawImage(ghostred,x,y,framegru) If count = 9 count = 0 framegru:+1 If framegru = 6 framegru = 4 count:+1 y:+1 Case 3 DrawImage(ghostred,x,y,framegrd) If count = 9 count = 0 framegrd:+1 If framegrd = 8 framegrd = 6 count:+1 y:-1 End Select timer:+1 ' kollisionsabfrage If CollideImage (ghostred,x+1,y+1,0,1,0) Or CollideImage (ghostred,x-1,y-1,0,1,0) DrawText "Kollision",400,50 x = oldx y = oldy EndIf Flip Cls FlushMem Until KeyHit(key_escape) ' leveldaten DefData 1,5,5,5,5,5,5,5,5,5,5,5,5,9,10,5,5,5,5,5,5,5,5,5,5,5,5,2 DefData 7,0,0,0,0,0,0,0,0,0,0,0,0,21,22,0,0,0,0,0,0,0,0,0,0,0,0,8 DefData 7,0,29,23,23,30,0,29,23,23,23,30,0,21,22,0,29,23,23,23,30,0,29,23,23,30,0,8 DefData 7,0,21,0,0,22,0,21,0,0,0,22,0,21,22,0,21,0,0,0,22,0,21,0,0,22,0,8 DefData 7,0,31,24,24,32,0,31,24,24,24,32,0,31,32,0,31,24,24,24,32,0,31,24,24,32,0,8 DefData 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8 DefData 7,0,29,23,23,30,0,29,30,0,29,23,23,23,23,23,23,30,0,29,30,0,29,23,23,30,0,8 DefData 7,0,31,24,24,32,0,21,22,0,31,24,24,30,29,24,24,32,0,21,22,0,31,24,24,32,0,8 DefData 7,0,0,0,0,0,0,21,22,0,0,0,0,21,22,0,0,0,0,21,22,0,0,0,0,0,0,8 DefData 3,6,6,6,6,30,0,21,27,23,23,30,0,21,22,0,29,23,23,28,22,0,29,6,6,6,6,4 DefData 0,0,0,0,0,7,0,21,25,24,24,32,0,31,32,0,31,24,24,26,22,0,8,0,0,0,0,0 DefData 0,0,0,0,0,7,0,21,22,0,0,0,0,0,0,0,0,0,0,21,22,0,8,0,0,0,0,0 DefData 0,0,0,0,0,7,0,21,22,0,17,6,16,33,33,15,6,18,0,21,22,0,8,0,0,0,0,0 DefData 5,5,5,5,5,32,0,31,32,0,8,0,0,0,0,0,0,7,0,31,32,0,31,5,5,5,5,5 DefData 0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,7,0,0,0,0,0,0,0,0,0,0 DefData 6,6,6,6,6,30,0,29,30,0,8,0,0,0,0,0,0,7,0,29,30,0,29,6,6,6,6,6 DefData 0,0,0,0,0,7,0,21,22,0,19,5,5,5,5,5,5,20,0,21,22,0,8,0,0,0,0,0 DefData 0,0,0,0,0,7,0,21,22,0,0,0,0,0,0,0,0,0,0,21,22,0,8,0,0,0,0,0 DefData 0,0,0,0,0,7,0,21,22,0,29,23,23,23,23,23,23,30,0,21,22,0,8,0,0,0,0,0 DefData 1,5,5,5,5,32,0,31,32,0,31,24,24,26,25,24,24,32,0,31,32,0,31,5,5,5,5,2 DefData 7,0,0,0,0,0,0,0,0,0,0,0,0,21,22,0,0,0,0,0,0,0,0,0,0,0,0,8 DefData 7,0,29,23,23,30,0,29,23,23,23,30,0,21,22,0,29,23,23,23,30,0,29,23,23,30,0,8 DefData 7,0,31,24,26,22,0,31,24,24,24,32,0,31,32,0,31,24,24,24,32,0,21,25,24,32,0,8 DefData 7,0,0,0,21,22,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,22,0,0,0,8 DefData 11,23,30,0,21,22,0,29,30,0,29,23,23,23,23,23,23,30,0,29,30,0,21,22,0,29,23,12 DefData 13,24,32,0,31,32,0,21,22,0,31,24,24,26,25,24,24,32,0,21,22,0,31,32,0,31,24,14 DefData 7,0,0,0,0,0,0,21,22,0,0,0,0,21,22,0,0,0,0,21,22,0,0,0,0,0,0,8 DefData 7,0,29,23,23,23,23,28,27,23,23,30,0,21,22,0,29,23,23,28,27,23,23,23,23,30,0,8 DefData 7,0,31,24,24,24,24,24,24,24,24,32,0,31,32,0,31,24,24,24,24,24,24,24,24,32,0,8 DefData 7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8 DefData 3,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,4 Wäre das in etwa so in Ordnung oder ist das Bullshit ? Gruss Oxcom |
||
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF |
![]() |
poet |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich versteh nicht warum du die Kollision auf Grafikebene machen willst.
Du kannst doch einfach in den Leveldaten checken ob das nächste Feld frei oder blockiert ist. Und die Kollision mit dem Spieler kannst du auch einfacher mathematisch testen. Solange sich deine Figuren nur im Raster gewegen kannst du dir ne pixel-genau Abfrage sparen ... |
||
![]() |
Oxcom |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich denke ich werde wohl nochmal ganz von vorne anfangen und mich mit den einfacheren elementaren Dingen befassen. Pacman ist wohl für den Einstieg doch ein bisschen gewagt.
Gruss Oxcom |
||
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group