Collisions - Macros und Procs

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

> Da es sich nur um ein größer-oder-kleiner Null handelt

ok, dann stimmts. war mir nicht mehr momentan.
ist schon ne ganze weile her, dass ich den code gepostet hatte,
hatte nur vorher etwas wenig beachtung gefunden....

danke fürs beschleunigen. :D :allright:
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Rubiko
Beiträge: 943
Registriert: 25.02.2005 19:43
Computerausstattung: Intel i7 2600k
8GB Ram
GeForce GTX 560 Ti
Wohnort: Schwabach

Beitrag von Rubiko »

Sorry, die Frage mag jetzt etwas blöd sein, aber ich rätsel schon ewig dran rum, naja wer nicht fragt bleibt dumm...
für was stehen bei der P_BoundBoxColl procedure die Parameter a1, a2 und b1, b2 ? Und dx und dy sind anscheinend die Eckpunkte der Bounding Box, oder?

Würde mich auf jeden Fall auf eine Antwort freuen :)
Ich wollte die Welt verändern, doch Gott gab mir nicht den Quelltext.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

nein.
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.
x1/y1 und x2/y2 sind die Mittelpunkte der Objekte.
a1/b1 und a2/b2 sind die entfernungen der bounding box zum jew. mittelpunkt.

innerhalb der rechnung sind dx und dy die abstände zwischen den rändern der bounding boxes.
nach mathematischer konvention dx für DeltaX, also Differenz.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Rubiko
Beiträge: 943
Registriert: 25.02.2005 19:43
Computerausstattung: Intel i7 2600k
8GB Ram
GeForce GTX 560 Ti
Wohnort: Schwabach

Beitrag von Rubiko »

ah, natürlich...

Danke für die Erläuterung :allright:
Ich wollte die Welt verändern, doch Gott gab mir nicht den Quelltext.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

aus aktuellem Anlass eine Ergänzung:
Kollision eines Kreises mit einem Rechteck

Code: Alles auswählen

; ***
; *** Circle - Box - Collision
; ***
; *** by Kaeru Gaman Dec.14th, 2006
; ***
; *** PB 4.00
; *** should work in every version > 3.0
; *** except the swap-command
; ****************************************
; *** collCircBox( Cx.l, Cy.l, Cr.l, x1.l, y1.l, x2.l, y2.l )
; ***
; *** Cx, Cy  - Center of the Circle
; *** Cr      - Radius of the Circle
; *** x1, y1  - Upper Left Corner of the Box
; *** x2, y2  - Lower Right Corner of the Box
; ***
; *** Procedure Returns:
; ***  #True if Collision occurs
; ***

Procedure collCircBox( Cx.l, Cy.l, Cr.l, x1.l, y1.l, x2.l, y2.l )
  If x1 > x2
    Swap x1, x2
  EndIf
  If y1 > y2
    Swap y1, y2
  EndIf

  Segment = 5 
  If Cx < x1 
    Segment -1 
  ElseIf Cx > x2 
    Segment +1 
  EndIf 
  If Cy < y1 
    Segment -3 
  ElseIf Cy > y2 
    Segment +3 
  EndIf

  Select Segment
    Case 1
      dx = Cx - x1
      dy = Cy - y1
      If Cr*Cr > dx*dx + dy*dy
        ProcedureReturn #True
      Else
        ProcedureReturn #False
      EndIf

    Case 2
      If Cy + Cr > y1
        ProcedureReturn #True
      Else
        ProcedureReturn #False
      EndIf

    Case 3
      dx = Cx - x2
      dy = Cy - y1
      If Cr*Cr > dx*dx + dy*dy
        ProcedureReturn #True
      Else
        ProcedureReturn #False
      EndIf

    Case 4
      If Cx + Cr > x1
        ProcedureReturn #True
      Else
        ProcedureReturn #False
      EndIf

    Case 5
        ProcedureReturn #True

    Case 6
      If Cx - Cr < x2
        ProcedureReturn #True
      Else
        ProcedureReturn #False
      EndIf

    Case 7
      dx = Cx - x1
      dy = Cy - y2
      If Cr*Cr > dx*dx + dy*dy
        ProcedureReturn #True
      Else
        ProcedureReturn #False
      EndIf

    Case 8
      If Cy - Cr < y2
        ProcedureReturn #True
      Else
        ProcedureReturn #False
      EndIf

    Case 9
      dx = Cx - x2
      dy = Cy - y2
      If Cr*Cr > dx*dx + dy*dy
        ProcedureReturn #True
      Else
        ProcedureReturn #False
      EndIf

  EndSelect
EndProcedure
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

und noch eine Ergänzung:

Kollision eines Kreises mit einem Punkt (ein Radius entfällt)

und:
Kollision eines vorbestimmten Kreises mit einem punkt.
praktisch zum testen des mauspunktes mit vielen identischen objekten.

Code: Alles auswählen

; *** 
; ***   Point to Circle Collision
; *** 

Macro PointCircleColl(x1,y1,r1,x2,y2) 
 ( 0 Or (( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) - r1 * r1 ) < 0) ) 
EndMacro 

Procedure P_PointCircleColl(x1,y1,r1,x2,y2) 
  Coll = #False 

  dist = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) - r1 * r1 
  
  If dist < 0 
    Coll = #True 
  EndIf 

  ProcedureReturn Coll 

EndProcedure

; *** 
; ***   Point to Fix Circle Collision
; *** 

#Coll_FixRad = 7    ; set to your Radiuses
#Coll_FRSq = #Coll_FixRad * #Coll_FixRad

Macro PointFixCircleColl(x1,y1,x2,y2) 
 ( 0 Or (( (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) - #Coll_FRSq ) < 0) ) 
EndMacro 

Procedure P_PointFixCircleColl(x1,y1,x2,y2) 
  Coll = #False 

  dist = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) - #Coll_FRSq 
  
  If dist < 0 
    Coll = #True 
  EndIf 

  ProcedureReturn Coll 

EndProcedure
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

und mal wieder was neues:

eine Standard-Kollision, die zurückgibt, an welcher seite die kollision stattfindet.

Code: Alles auswählen

EnableExplicit

; ******************************************************************************
; **
; ** SectorCollision( x1.l, y1.l, a1.l, b1.l, x2.l, y2.l, a2.l, b2.l )
; **
; ** by Kaeru Gaman ; Jan.2009 ; PB 4.3 
; **
; ******************************************************************************
; **
; ** Checks if Boxes 1 and 2 collide
; **
; ** Returns 0 if no Collision
; ** Returns Sector relative to Box 2 if Collision
; ** Order of Sectors:
; **
; ** \ 1 /
; ** 2 # 4
; ** / 3 \
; **

Procedure.l SectorCollision( x1.l, y1.l, a1.l, b1.l, x2.l, y2.l, a2.l, b2.l )
  Protected dx.l, dy.l
  Protected sx.l, sy.l
  Protected Coll.l = 0
 
  dx = (x1 + a1/2) - (x2 + a2/2)
  If dx < 0
    dx = -dx
    sx = -1
  ElseIf dx > 0
    sx = 1
  EndIf

  dy = (y1 + b1/2) - (y2 + b2/2)
  If dy < 0
    dy = - dy
    sy = -1
  ElseIf dy > 0
    sy = 1
  EndIf
  
  If dx < (a1+a2)/2 And dy < (b1+b2)/2
    If dx < dy
      Coll = 2 + sy
    Else
      Coll = 3 + sx
    EndIf
  EndIf
 
  ProcedureReturn Coll

EndProcedure 

; ***
; *** Demo for SectorCollision
; ***

; *** Change if your display needs other values
#Screen_Width  = 1024
#Screen_Height =  768
#Screen_Depth  =   32

#SW1 =  64
#SH1 =  32

#SW2 = 128
#SH2 =  64

InitSprite()
InitKeyboard()
InitMouse()
OpenScreen( #Screen_Width, #Screen_Height, #Screen_Depth, "test")

CreateSprite( 0,  #SW1, #SH1 )
  StartDrawing( SpriteOutput( 0 ) )
    DrawingMode(#PB_2DDrawing_Transparent)
    Box( 0,0,  #SW1, #SH1, $0080FF )
    DrawText( 8,8,"A", $FFFFFF )
  StopDrawing()

CreateSprite( 1, #SW2, #SH2 )
  StartDrawing( SpriteOutput( 1 ) )
    DrawingMode(#PB_2DDrawing_Transparent)
    Box( 0,0, #SW2, #SH2, $004040 )
    DrawText( 8,8,"B", $FFFFFF )
  StopDrawing()

Define MX.l
Define MY.l
Define SX.l = #Screen_Width / 2 - #SW1 / 2
Define SY.l = #Screen_Height / 2 - #SH1 / 2

Define Colli.l

Repeat
  ExamineKeyboard()
  ExamineMouse()
  MX = MouseX() : MY = MouseY()

  ClearScreen( $302010 )
  DisplaySprite( 1, SX, SY )
  DisplaySprite( 0, MX, MY )

  Colli = SectorCollision( MX, MY, #SW1, #SH1, SX, SY, #SW2, #SH2 )

  StartDrawing( ScreenOutput() )
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText( 8,8, "Collision Sector: "+Str(Colli), $20C0FF )
  StopDrawing()

  FlipBuffers( #PB_Screen_SmartSynchronization )

Until KeyboardPushed( #PB_Key_Escape )
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten