[BM V. 1.16] 2D Circle / Circle Kollision
Übersicht

![]() |
FetzeBetreff: [BM V. 1.16] 2D Circle / Circle Kollision |
![]() Antworten mit Zitat ![]() |
---|---|---|
Code: [AUSKLAPPEN] 'Notationskürzel "csp" Type ColShape Global iCount :Int Global sID :String[] Global iCircleNum :Int[] Global iCircleX :Int[][] '[ColShapeNum][CircleNum] Global iCircleY :Int[][] '[ColShapeNum][CircleNum] Global iCircleRadius :Int[][] '[ColShapeNum][CircleNum] Field iType :Int Field fX :Float Field fY :Float Field fAngle :Float 'Temporär: Field fCircleXTemp :Float[] Field fCircleYTemp :Float[] Method New() End Method 'fParXCam und fParYCam werden zur Position beim Zeichnen dazuaddiert Method Draw:Byte(fParXCam:Float = 0.0, fParYCam:Float = 0.0) Local iLoop:Int SetBlend ALPHABLEND SetAlpha 0.3 SetColor 255, 0, 0 For iLoop = 0 To iCircleNum[iType] - 1 DrawOval fX + fCircleXTemp[iLoop] - iCircleRadius[iType][iLoop] + fParXCam, fY + fCircleYTemp[iLoop] - iCircleRadius[iType][iLoop] + fParYCam, 2 * iCircleRadius[iType][iLoop], 2 * iCircleRadius[iType][iLoop] Next SetAlpha 1.0 SetColor 255, 255, 255 SetBlend MASKBLEND Return True End Method Method Update:Byte(fParX:Float, fParY:Float, fParAngle:Float) If fAngle <> fParAngle Then For Local iLoop:Int = 0 To iCircleNum[iType] - 1 fCircleXTemp[iLoop] = iCircleX[iType][iLoop] fCircleYTemp[iLoop] = iCircleY[iType][iLoop] If fCircleXTemp[iLoop] <> 0.0 Or fCircleYTemp[iLoop] <> 0.0 Then TransformCoord(fCircleXTemp[iLoop], fCircleYTemp[iLoop], fParAngle) End If Next fAngle = fParAngle End If fX = fParX fY = fParY Return True End Method Method CollidedWith:Byte(cspParShape:ColShape) Local iLoop:Int Local iLoop2:Int Local iMaxDistTemp:Int For iLoop = 0 To iCircleNum[iType] - 1 For iLoop2 = 0 To iCircleNum[cspParShape.iType] - 1 iMaxDistTemp = (iCircleRadius[iType][iLoop] + iCircleRadius[cspParShape.iType][iLoop2]) If Abs((fX + fCircleXTemp[iLoop]) - (cspParShape.fX + cspParShape.fCircleXTemp[iLoop2])) < iMaxDistTemp And Abs((fY + fCircleYTemp[iLoop]) - (cspParShape.fY + cspParShape.fCircleYTemp[iLoop2])) < iMaxDistTemp Then If DistanceQuad((fX + fCircleXTemp[iLoop]), (fY + fCircleYTemp[iLoop]), (cspParShape.fX + cspParShape.fCircleXTemp[iLoop2]), (cspParShape.fY + cspParShape.fCircleYTemp[iLoop2])) < (iMaxDistTemp * iMaxDistTemp) Then Return True End If End If Next Next Return False End Method 'Wie CollidedWith, liefert aber im Fall einer Kollision noch Kollisionspunkt und resultierenden Vektor zurück. Method CollidedWith2:Byte(cspParShape:ColShape, fVarColX:Float[] Var, fVarColY:Float[] Var, fVarResXVec:Float Var, fVarResYVec:Float Var) Local iLoop:Int Local iLoop2:Int Local iMaxDistTemp:Int Local fDistTemp:Float Local bCollision:Byte Local fXDif:Float Local fYDif:Float fVarResXVec = 0.0 fVarResYVec = 0.0 fVarColX = New Float[0] fVarColY = New Float[0] For iLoop = 0 To iCircleNum[iType] - 1 For iLoop2 = 0 To iCircleNum[cspParShape.iType] - 1 iMaxDistTemp = (iCircleRadius[iType][iLoop] + iCircleRadius[cspParShape.iType][iLoop2]) fXDif = ((cspParShape.fX + cspParShape.fCircleXTemp[iLoop2]) - (fX + fCircleXTemp[iLoop])) fYDif = ((cspParShape.fY + cspParShape.fCircleYTemp[iLoop2]) - (fY + fCircleYTemp[iLoop])) If Abs(fXDif) < iMaxDistTemp And Abs(fYDif) < iMaxDistTemp Then fDistTemp = (fXDif * fXDif) + (fYDif * fYDif) If fDistTemp < (iMaxDistTemp * iMaxDistTemp) Then fDistTemp = Sqr(fDistTemp) fVarResXVec:+ (fXDif / fDistTemp) * -(iMaxDistTemp - fDistTemp) fVarResYVec:+ (fYDif / fDistTemp) * -(iMaxDistTemp - fDistTemp) fVarColX = fVarColX[..fVarColX.length + 1] fVarColY = fVarColY[..fVarColY.length + 1] fVarColX[fVarColX.length - 1] = fCircleXTemp[iLoop] + (fXDif / fDistTemp) * (Float(iCircleRadius[iType][iLoop]) - ((iMaxDistTemp - fDistTemp) / 2.0)) fVarColY[fVarColY.length - 1] = fCircleYTemp[iLoop] + (fYDif / fDistTemp) * (Float(iCircleRadius[iType][iLoop]) - ((iMaxDistTemp - fDistTemp) / 2.0)) bCollision = True End If End If Next Next Return bCollision End Method Function Create:ColShape(iParType:Int) Local cspTemp:ColShape = New ColShape cspTemp.iType = iParType cspTemp.fCircleXTemp = cspTemp.fCircleXTemp[..iCircleNum[iParType]] cspTemp.fCircleYTemp = cspTemp.fCircleYTemp[..iCircleNum[iParType]] Return cspTemp End Function 'Setzt die Anzahl der CollisionShapes auf den angegebenen Wert. Bei einer Erhöhung bleiben die vorherigen erhalten, wenn bParClear = False Function RedefineTypes:Byte(iParNewTypeNum:Int, bParClear:Byte = False) If bParClear = True Then RedefineTypes(0) End If iCount = iParNewTypeNum sID = sID[..iParNewTypeNum] iCircleNum = iCircleNum[..iParNewTypeNum] iCircleX = iCircleX[..iParNewTypeNum] iCircleY = iCircleY[..iParNewTypeNum] iCircleRadius = iCircleRadius[..iParNewTypeNum] Return True End Function Function RedefineCircleTypes:Byte(iParType:Int, iParNewNum:Int) Local iLoop:Int Local iLoop2:Int Local iOldNum:Int = iCircleX[iParType].length iCircleX[iParType] = iCircleX[iParType][..iParNewNum] iCircleY[iParType] = iCircleY[iParType][..iParNewNum] iCircleRadius[iParType] = iCircleRadius[iParType][..iParNewNum] For iLoop = iOldNum To iParNewNum - 1 'Hier eventuelle Standartwerte festlegen Next Return True End Function Function ID2Type:Int(sParID:String) If iCount = 0 Then Return 0 Local iLoop:Int For iLoop = 0 To (iCount - 1) If sID[iLoop] = sParID Then Return iLoop Next Return Int(sParID) End Function Function ValidID:Byte(sParID:String) If iCount = 0 Then Return False Local iLoop:Int For iLoop = 0 To (iCount - 1) If sID[iLoop] = sParID Then Return True Next Return False End Function End Type 'Gibt die Entfernung zwischen den beiden angegebenen Punkten zurück, ohne vorher die Wurzel zu ziehen. Ein bischen schneller, dafür nicht für alles geeignet. Function DistanceQuad:Float(fParX1:Float, fParY1:Float, fParX2:Float = 0, fParY2:Float = 0) Return ((fParX1 - fParX2) * (fParX1 - fParX2) + (fParY1 - fParY2) * (fParY1 - fParY2)) End Function 'Dreht und Skaliert die angegebenen Koordinaten im angegebenen Winkel um eine Mitte. Function TransformCoord:Byte(fVarX:Float Var, fVarY:Float Var, fAngle:Float, fParCenterX:Float = 0.0, fParCenterY:Float = 0.0, fScale:Float = 1.0) Local fTempAngle:Float = Angle(fParCenterX, fParCenterY, fVarX, fVarY) + fAngle Local fTempDist:Float = Distance(fVarX, fVarY, fParCenterX, fParCenterY) * fScale fVarX = fParCenterX + Sin(fTempAngle) * fTempDist fVarY = fParCenterY - Cos(fTempAngle) * fTempDist Return True End Function 'Liefert den Winkel von Punkt 2 zu Punkt 1 zurück. 'Beispiel: Punkt 1 liegt bei 0,0, Punkt 2 bei 10,0 'Dann wird der Winkel 90 zurückgeliefert. Function Angle:Float(fX1:Float, fY1:Float, fX2:Float, fY2:Float) Return (ATan2(fY2 - fY1, fX2 - fX1) + 450.0) Mod 360.0 End Function 'Gibt die Entfernung zwischen den beiden angegebenen Punkten zurück. Function Distance:Float(fParX1:Float, fParY1:Float, fParX2:Float = 0, fParY2:Float = 0) Return Sqr((fParX1 - fParX2) * (fParX1 - fParX2) + (fParY1 - fParY2) * (fParY1 - fParY2)) End Function Hier mal ein Verwedungsbeispiel: Code: [AUSKLAPPEN] '#### ColShap-Typ erstellen: #### 'Gesamte Typanzahl auf 1 erhöhen. Bei Erhöhung bleiben vorherige ColShapes erhalten. ColShape.RedefineTypes(1) 'Maximalanzahl der Radien für Typ 0 (Typennummerierung beginnt bei 0) auf 2 setzen ColShape.RedefineCircleTypes(0, 2) 'Werte für Kollisionsform Typ 0 festlegen: ColShape.sID[0] = "TESTCOLLISION" 'ID des ColShape-Typs 0 ColShape.iCircleNum[0] = 2 'Anzahl der Radien auf 2 setzen. 'RADIUS 0 ColShape.iCircleX[0][0] = -3 'X-Position des Radienmittelpunkts relativ zum Mittelpunkt des ColShapes ColShape.iCircleY[0][0] = 0 'Y-Position " " " ColShape.iCircleRadius[0][0] = 5 'Radius 'RADIUS 1 ColShape.iCircleX[0][1] = 3 'X-Position des Radienmittelpunkts relativ zum Mittelpunkt des ColShapes ColShape.iCircleY[0][1] = 0 'Y-Position " " " ColShape.iCircleRadius[0][1] = 7 'Radius '#### ColShape des Typs 0 erstellen #### Global cspTemp:ColShape = ColShape.Create(ColShape.ID2Type("TESTCOLLISION")) 'Oder alternativ statt ID2Type direkt die Typnummer eingeben '#### ColShape benutzen #### 'cspTemp.Update(fXPos, fYPos, fAngle) '<- Setzt Position und Winkel des ColShapes neu. 'cspTemp.Draw(fXCam, fYCam) '<- fXCam und fYCam sind optional. Sie werden beim zeichnen zur Position des ColShapes dazuaddiert. 'cspTemp.CollidedWith(cspAnotherColShape) '<- True oder False. Kollidiert oder nicht. 'cspTemp.CollidedWith2(cspAnotherColShape, fVarColX[], fVarColY[], fVarResVecX, fVarResVecY) '<- Genau wie CollidedWith, liefert aber Kollisionspunkte und resultierenden Vektor zurück. Hoffe, das hilft vielleicht dem ein oder anderen ^^ |
||
![]() |
Fetze |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hatte eine Function vergessen, ist aber nun hinzugefügt. Sollte also jetzt funktionieren ^^ | ||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group