Kollisionsabfrage mittels imagescollide !

Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Neue Antwort erstellen

Oxcom

Betreff: Kollisionsabfrage mittels imagescollide !

BeitragSo, Nov 06, 2005 19:25
Antworten mit Zitat
Benutzer-Profile anzeigen
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 ? Shocked

Gruss Oxcom
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF

Justus

BeitragSo, Nov 06, 2005 19:44
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Nov 14, 2005 13:52
Antworten mit Zitat
Benutzer-Profile anzeigen
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. Sad

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. Sad

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 ! Mr. Green
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF

Oxcom

BeitragDi, Nov 15, 2005 13:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Wirklich keine Idee ? Sad
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF

rema

BeitragDi, Nov 15, 2005 15:44
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDi, Nov 15, 2005 16:41
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDi, Nov 15, 2005 21:53
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDo, Nov 17, 2005 15:17
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragDo, Nov 17, 2005 17:44
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragFr, Nov 18, 2005 10:01
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragFr, Nov 18, 2005 18:42
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSa, Nov 19, 2005 0:01
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSa, Nov 19, 2005 11:21
Antworten mit Zitat
Benutzer-Profile anzeigen
So ... heute ist wieder Wochenende und der brave Oxcom wird wieder fleissig lernen und ausprobieren ! Mr. Green

Gruss Oxcom
Apple Mac Mini 1.42 Ghz / 1 GB Ram / Samsung Syncmaster 930 BF

Oxcom

BeitragSo, Nov 20, 2005 19:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Da bin ich wieder ! Mr. Green

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:

user posted image
user posted image


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

BeitragSo, Nov 20, 2005 20:38
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragMo, Nov 21, 2005 18:51
Antworten mit Zitat
Benutzer-Profile anzeigen
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

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group