Bei gedrehtem Sprite3D eine Kollision?

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

DarkDragon hat geschrieben:Eine BoundingBox kollision ist genauso fein wie BoundingSphere. Wenn du eine auf quadratische Tiles basierte map hast, dann nimmt man logischerweise BoundingBox.
da die meisten formen in der realität dazu neigen, sich gleichmässig um einen mittelpunkt anzuodnen,
und nicht jedes viertel in einer raumdimension um den faktor wurzel zwei heraussteht,
ist BoundingCircle in sofern feiner, dass es sich etwas mehr dieser natürlichen form annähert,
als BoundingBox.

Bild

dazu kommt noch, das im vorliegenden fall ein sprite gedreht werden soll,
damit zeitigt BoundingCircle gleichmässige ergebnisse,
während BoundingBox stehts unterschiedliche abweichungen hervorbrächte.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Stefan
Beiträge: 125
Registriert: 29.08.2004 10:51
Kontaktdaten:

Beitrag von Stefan »

Hallo

Hier noch ein Beispiel für eine pixelgenaue Kollisionsüberprüfung von mir: :mrgreen:

Code: Alles auswählen

Structure DDPIXELFORMAT 
  dwSize.l 
  dwFlags.l 
  dwFourCC.l 
  dwRGBBitCount.l 
  dwRBitMask.l 
  dwGBitMask.l 
  dwBBitMask.l 
  dwRGBAlphaBitMask.l 
EndStructure 

Structure DDCOLORKEY 
  dwColorSpaceLowValue.l 
  dwColorSpaceHighValue.l 
EndStructure 

Structure DDSCAPS2 
  dwCaps.l 
  dwCaps2.l 
  dwCaps3.l 
  dwCaps4.l 
EndStructure 

Structure DDSURFACEDESC2 
  dwSize.l 
  dwFlags.l 
  dwHeight.l 
  dwWidth.l 
  lPitch.l 
  dwBackBufferCount.l 
  dwRefreshRate.l 
  dwAlphaBitDepth.l 
  dwReserved.l 
  lpSurface.l 
  ddckCKDestOverlay.DDCOLORKEY 
  ddckCKDestBlt.DDCOLORKEY 
  ddckCKSrcOverlay.DDCOLORKEY 
  ddckCKSrcBlt.DDCOLORKEY 
  ddpfPixelFormat.DDPIXELFORMAT 
  ddsCaps.DDSCAPS2 
  dwTextureStage.l 
EndStructure 

Structure PB_Sprite 
  Sprite.l 
  Width.w 
  Height.w 
  Depth.w 
  Mode.w 
  FileName.l 
  RealWidth.w 
  RealHeight.w 
  ClipX.w 
  ClipY.w 
EndStructure 

#DDSD_WIDTH=4 
#DDSD_HEIGHT=2 
#DDSD_CAPS=1 
#DDSCAPS_3DDEVICE=8192 
#DDSCAPS_OFFSCREENPLAIN=64 

Global *D3DDevice.IDirect3DDevice7 
Global *BackBuffer.IDirectDrawSurface7 

Procedure CreateRenderSprite(Sprite,Width,Height) 
  Result=CreateSprite(Sprite,Width,Height) 
  If Result=0:ProcedureReturn 0:EndIf 
  *PBSprite.PB_Sprite=IsSprite(Sprite) 
  *DDS.IDirectDrawSurface7=*PBSprite\Sprite 
  *DDS\GetDDInterface(@*DD.IDirectDraw7) 
  *DDS\Release() 
  DDSD.DDSURFACEDESC2 
  DDSD\dwSize=SizeOf(DDSURFACEDESC2) 
  DDSD\dwFlags=#DDSD_WIDTH|#DDSD_HEIGHT|#DDSD_CAPS 
  DDSD\dwWidth=Width 
  DDSD\dwHeight=Height 
  DDSD\ddsCaps\dwCaps=#DDSCAPS_3DDEVICE|#DDSCAPS_OFFSCREENPLAIN 
  Result=*DD\CreateSurface(DDSD,*PBSprite,0) 
  If Result:ProcedureReturn 0:EndIf 
  ProcedureReturn *PBSprite\Sprite 
EndProcedure 

Procedure SelectRenderSprite(Sprite) 
  !extrn _PB_Direct3D_Device 
  !MOV Eax,[_PB_Direct3D_Device] 
  !MOV [p_D3DDevice],Eax 
  !extrn _PB_DirectX_BackBuffer 
  !MOV Eax,[_PB_DirectX_BackBuffer] 
  !MOV [p_BackBuffer],Eax 
  *D3DDevice\EndScene() 
  Select Sprite 
    Case -1 
      *D3DDevice\SetRenderTarget(*BackBuffer,2) 
    Default 
      *D3DDevice\SetRenderTarget(PeekL(IsSprite(Sprite)),2) 
  EndSelect 
  *D3DDevice\BeginScene() 
EndProcedure 






;Example: 

InitSprite() 
InitSprite3D() 


InitKeyboard() 
InitMouse() 
OpenScreen(640,480,16,"Collision detection with 3D-Sprites") 

CreateRenderSprite(0,181,181) 
CreateRenderSprite(1,181,181) 

TransparentSpriteColor(0,255,0,255) 
TransparentSpriteColor(1,255,0,255) 

LoadSprite(5,"C:\PureBASIC2\Examples\Sources\Data\GeeBee2.bmp",#PB_Sprite_Texture) ;Pfad anpassen !
CreateSprite3D(5,5) 


Repeat 
  ExamineKeyboard() 
  ExamineMouse() 
  
  ClearScreen(0,0,0) 
  
  UseBuffer(0) 
  ClearScreen(255,0,255);Clear Sprite 0 
  UseBuffer(1) 
  ClearScreen(255,0,255);Clear Sprite 1 
  UseBuffer(-1) 
  
  
  Start3D() 
  
  SelectRenderSprite(0);Draw the 3D-Sprite on Sprite 0 
  Angle1+2 
  RotateSprite3D(5,Angle1,0) 
  DisplaySprite3D(5,27,27) 
  
  
  SelectRenderSprite(1);Draw the 3D-Sprite on Sprite 1 
  Angle2-2 
  RotateSprite3D(5,Angle2,0) 
  DisplaySprite3D(5,27,27) 
  
  SelectRenderSprite(-1);Draw on Backbuffer 
  Stop3D() 
  
  
  DisplayTransparentSprite(0,MouseX(),MouseY()) 
  DisplayTransparentSprite(1,200,100) 
  
  If SpritePixelCollision(0,MouseX(),MouseY(),1,200,100) 
    StartDrawing(ScreenOutput()) 
    FrontColor(255,255,0) 
    DrawingMode(1) 
    DrawingFont(GetStockObject_(#ANSI_FIXED_FONT)) 
    DrawText("Collision !") 
    StopDrawing() 
  EndIf 
  
  FlipBuffers() 
  
Until KeyboardPushed(#PB_Key_Escape) 

Gruß
Stefan
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Kaeru Gaman hat geschrieben:
DarkDragon hat geschrieben:Eine BoundingBox kollision ist genauso fein wie BoundingSphere. Wenn du eine auf quadratische Tiles basierte map hast, dann nimmt man logischerweise BoundingBox.
da die meisten formen in der realität dazu neigen, sich gleichmässig um einen mittelpunkt anzuodnen,
und nicht jedes viertel in einer raumdimension um den faktor wurzel zwei heraussteht,
ist BoundingCircle in sofern feiner, dass es sich etwas mehr dieser natürlichen form annähert,
als BoundingBox.

Bild

dazu kommt noch, das im vorliegenden fall ein sprite gedreht werden soll,
damit zeitigt BoundingCircle gleichmässige ergebnisse,
während BoundingBox stehts unterschiedliche abweichungen hervorbrächte.
Was ich eigentlich auch sagen wollte, was anscheinend aber nicht verständlich genug war(kein wunder, waren auch nur 1-2 Sätze wenn ich mich recht erinnere) ;) . Aber sagen wir mal du hast nen Spieler, der soll sich auf einer Quadratischen Fläche bewegen. Dann ist für das Quadrat zumindest eine BoundingBox angemessener ;) , sonst läuft der Spieler Hügel.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

DarkDragon hat geschrieben:Aber sagen wir mal du hast nen Spieler, der soll sich auf einer Quadratischen Fläche bewegen. Dann ist für das Quadrat zumindest eine BoundingBox angemessener ;)
da hast du natürlich recht :wink:
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten