Collisions - Macros und Procs
Verfasst: 02.07.2006 16:44
es wird immer wieder so viel über Kollisionen geredet, da hab ich mich mal hingesetzt und ein paar Macros und Procs geschrieben.
die Proceduren haben das Präfix P_ vor dem Macronamen gleicher funktion.
folgendes ist hier enthalten:
AbsEx(Wert)
berechnung des absoluten Wertes einer Zahl.
wird benötigt für die Bounding-Box-Collision.
vielen Dank an Remi für die eliminierung eines unerklärlichen fehlers.
StdColl(x1,y1,a1,b1,x2,y2,a2,b2)
die Standard-Collision, funktioniert genauso wie SpriteCollision(), nur dass hier keine SpriteNummer angegeben wird, sondern Höhe und Breite des Objekts.
dadurch spart sie funktionsaufrufe, und ist außerdem auch für mittels DirectDraw gezeichnete Objekte verwendbar (z.b. Box() )
BoundBoxColl(x1,y1,a1,b1,x2,y2,a2,b2)
Bounding-Box-Collision
hier sind die Koordinaten der Mittelpunkt der Box, die Dimensionen sind der abstand zum Rand, also die Hälfte der Breite bzw. Höhe.
BoundCircleColl(x1,y1,r1,x2,y2,r2)
Bounding-Circle-Collision
auch hier wird der mittelpunkt angegeben, und der jeweilige radius.
für viele spielelemente (raumschiffe etc.) entspricht ein Umkreis eher den ausmaßen des objekts als ein Kasten.
ich musste hier leider SQR() verwenden, auf die schnelle hab ich kein workaround erdenken können, was diese zweifellos langwierige funktion überflüssig macht.
Achtung:
aber NTQ hat es gelöst.
thnx, Nic
ich habe seine verbesserungen ins Listing übernommen.
natürlich hätte ich bei den beiden letzten Procs die formeln direkt ins If setzen können, ich habe aber mal die zwischenvariablen beibehalten, wie in der ersten auch, wo sie notwendig sind.
!!HINWEIS!!
bei verwendung der Macros bitte nur einzelwerte/einzelvariablen übergeben, keine ausdrücke. besonders bei den ersten beiden kann es sonst zu einem fehler kommen: "Expression too complex, out of CPU-registers"
die Prozeduren sind wahrscheinlich etwas langsamer (hab jetzt keinen performance-check durchgeführt) aber dafür können die Argumente auch komplexere ausdrücke sein.
außerdem sollten die Procs auch in PB 3.94 funktionieren, möglicherweise auch in 3.30 (nicht getestet)
und hier ist der code:
ergänzung: das Macro AbsEx() ist sau lahm, ich empfehle, auch im Bounding-Box-Macro die Procedure für AbsEx zu benutzen.
die Proceduren haben das Präfix P_ vor dem Macronamen gleicher funktion.
folgendes ist hier enthalten:
AbsEx(Wert)
berechnung des absoluten Wertes einer Zahl.
wird benötigt für die Bounding-Box-Collision.
vielen Dank an Remi für die eliminierung eines unerklärlichen fehlers.
StdColl(x1,y1,a1,b1,x2,y2,a2,b2)
die Standard-Collision, funktioniert genauso wie SpriteCollision(), nur dass hier keine SpriteNummer angegeben wird, sondern Höhe und Breite des Objekts.
dadurch spart sie funktionsaufrufe, und ist außerdem auch für mittels DirectDraw gezeichnete Objekte verwendbar (z.b. Box() )
BoundBoxColl(x1,y1,a1,b1,x2,y2,a2,b2)
Bounding-Box-Collision
hier sind die Koordinaten der Mittelpunkt der Box, die Dimensionen sind der abstand zum Rand, also die Hälfte der Breite bzw. Höhe.
BoundCircleColl(x1,y1,r1,x2,y2,r2)
Bounding-Circle-Collision
auch hier wird der mittelpunkt angegeben, und der jeweilige radius.
für viele spielelemente (raumschiffe etc.) entspricht ein Umkreis eher den ausmaßen des objekts als ein Kasten.
ich musste hier leider SQR() verwenden, auf die schnelle hab ich kein workaround erdenken können, was diese zweifellos langwierige funktion überflüssig macht.
Achtung:
aber NTQ hat es gelöst.

ich habe seine verbesserungen ins Listing übernommen.
natürlich hätte ich bei den beiden letzten Procs die formeln direkt ins If setzen können, ich habe aber mal die zwischenvariablen beibehalten, wie in der ersten auch, wo sie notwendig sind.
!!HINWEIS!!
bei verwendung der Macros bitte nur einzelwerte/einzelvariablen übergeben, keine ausdrücke. besonders bei den ersten beiden kann es sonst zu einem fehler kommen: "Expression too complex, out of CPU-registers"
die Prozeduren sind wahrscheinlich etwas langsamer (hab jetzt keinen performance-check durchgeführt) aber dafür können die Argumente auch komplexere ausdrücke sein.
außerdem sollten die Procs auch in PB 3.94 funktionieren, möglicherweise auch in 3.30 (nicht getestet)
und hier ist der code:
Code: Alles auswählen
; ********************************************************
; ***
; *** Collision Macros / Procedures
; ***
; *** by Kaeru Gaman 2006-07-02
; ***
; *** PB Ver 4.0
; ***
; ********************************************************
; ***
; *** Absolute Value
; ***
Macro AbsEx(Expression)
( ( ((Expression) >= 0 Or 0) *2 - 1 ) * (Expression) )
EndMacro
Procedure P_AbsEx(Wert)
If Wert < 0
wert *-1
EndIf
ProcedureReturn Wert
EndProcedure
; ***
; *** Standard Collision, equal to SpriteCollision()
; ***
Macro StdColl(x1,y1,a1,b1,x2,y2,a2,b2)
(0 Or (0>=((0 Or (x1 < x2))*(x2 - (x1 + a1)))+((0 Or (x1 >= x2))*(x1 - (x2 + a2)))))And(0 Or (0>=((0 Or (y1 < y2))*(y2 - (y1 + b1)))+((0 Or (y1 >= y2))*(y1 - (y2 + b2)))))
EndMacro
Procedure P_StdColl(x1,y1,a1,b1,x2,y2,a2,b2)
Coll = #False
If x1 < x2
dx = x2 - (x1 + a1)
Else
dx = x1 - (x2 + a2)
EndIf
If y1 < y2
dy = y2 - (y1 + b1)
Else
dy = y1 - (y2 + b2)
EndIf
If dx < 0 And dy < 0
Coll = #True
EndIf
ProcedureReturn Coll
EndProcedure
; ***
; *** Bounding Box
; ***
Macro BoundBoxColl(x1,y1,a1,b1,x2,y2,a2,b2)
( ( 0 Or ((AbsEx(x1-x2) - a1 - a2)<0)) And ( 0 Or ((AbsEx(y1-y2) - b1 - b2)<0)) )
EndMacro
Procedure P_BoundBoxColl(x1,y1,a1,b1,x2,y2,a2,b2)
Coll = #False
dx = P_AbsEx(x1-x2) - a1 - a2
dy = P_AbsEx(y1-y2) - b1 - b2
If dx < 0 And dy < 0
Coll = #True
EndIf
ProcedureReturn Coll
EndProcedure
; ***
; *** Bounding Circle
; ***
Macro BoundCircleColl(x1,y1,r1,x2,y2,r2)
( 0 Or (( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) - (r1 + r2) * (r1 + r2) ) < 0) )
EndMacro
Procedure P_BoundCircleColl(x1,y1,r1,x2,y2,r2)
Coll = #False
dist = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) - (r1 + r2) * (r1 + r2)
If dist < 0
Coll = #True
EndIf
ProcedureReturn Coll
EndProcedure