Page 1 of 1

Sprite Rotation and bounding box

Posted: Wed Mar 16, 2016 11:41 am
by [blendman]
Hi

Some code to have a sprite rotation bounding box :

sprite rotation centered :

Code: Select all

If InitSprite() = 0 Or InitKeyboard()=0 Or UsePNGImageDecoder() = 0 Or UseJPEGImageDecoder() = 0
    MessageRequester("Error","DirectX 7+ is needed.",0)
    End
EndIf

OpenWindow(0,0,0,800,600,"Sprite bounding box",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0),0,0, 800, 600, 0, 0, 0)

file$ = OpenFileRequester("Load image to sprite","","PNG (*.png)|*.png|JPG(.jpg,.jpeg)|*.jpg;*.jpeg)",0)
If file$ <> ""
    If LoadSprite(0,File$,#PB_Sprite_AlphaBlending)
        w = SpriteWidth(0)
        h = SpriteHeight(0)
    Else
        MessageRequester("Error","Unable to load the image "+file$)
        End
    EndIf
   
EndIf
x = 100
y = 100
#DEG = #PI/180

Repeat
   
   
    Repeat
       
        event = WaitWindowEvent(1)
        If event = #PB_Event_CloseWindow
            End
        EndIf
       
    Until event =0
   
   
   
    angle +1
    If angle > 360
        angle = 0
    EndIf
   
    R = Sqr(w*w+h*h)/2 ; demi diagonal in center
   
    u.f = Degree(ATan(h/w))
   
    X1=X+w/2+R*Cos((Angle-u)*#DEG)
    Y1=Y+h/2+R*Sin((Angle-u)*#DEG)
    X2=X+w/2+R*Cos((Angle+u)*#DEG)
    Y2=Y+h/2+R*Sin((Angle+u)*#DEG)
    X3=X+w/2+R*Cos((Angle-180+u)*#DEG)
    Y3=Y+h/2+R*Sin((Angle-180+u)*#DEG)
    X4=X+w/2+R*Cos((Angle+180-u)*#DEG)
    Y4=Y+h/2+R*Sin((Angle+180-u)*#DEG)
   
   
    ClearScreen(RGB(120,120,120))
    RotateSprite(0,angle,0)
    DisplayTransparentSprite(0,x,y)
   
    StartDrawing(ScreenOutput())
       
    LineXY(X1,Y1,X2,Y2)
    LineXY(X2,Y2,X4,Y4)
    LineXY(X3,Y3,X1,Y1)
    LineXY(X3,Y3,X4,Y4)
       
   
    StopDrawing()
   
    Delay(1)
   
    FlipBuffers()
       
    If ExamineKeyboard()
    EndIf
       
Until KeyboardPushed(#PB_Key_Escape) 

And a code from Stargate and Mesa (for bounding box) :
Sprite rotation not centered :

Code: Select all

Procedure SpriteTransformation(Sprite.i, X.f, Y.f, Width.f, Height.f, Angle.f)
  Protected Cos.f = Cos(Radian(Angle))
  Protected Sin.f = Sin(Radian(Angle))
  TransformSprite(Sprite, X*Cos-Y*Sin, X*Sin+Y*Cos, (X+Width)*Cos-Y*Sin, (X+Width)*Sin+Y*Cos, (X+Width)*Cos-(Y+Height)*Sin, (X+Width)*Sin+(Y+Height)*Cos, X*Cos-(Y+Height)*Sin, X*Sin+(Y+Height)*Cos)
EndProcedure

Procedure CalculCoin(X.f, Y.f, Width.f, Height.f, Angle.f, ScreenX.f, ScreenY.f)
  Protected Cos.f = Cos(Radian(Angle))
  Protected Sin.f = Sin(Radian(Angle))
  Protected.f x1,y1, x2,y2, x3,y3, x4,y4
  x1=(X*Cos-Y*Sin) + ScreenX
  y1=(X*Sin+Y*Cos) + ScreenY
  x2=((X+Width)*Cos-Y*Sin )+ ScreenX
  y2=((X+Width)*Sin+Y*Cos) + ScreenY
  x3=((X+Width)*Cos-(Y+Height)*Sin ) + ScreenX
  y3=((X+Width)*Sin+(Y+Height)*Cos ) + ScreenY
  x4=(X*Cos-(Y+Height)*Sin ) + ScreenX
  y4=(X*Sin+(Y+Height)*Cos) + ScreenY
 
  If StartDrawing(ScreenOutput())
    Circle(x1, y1, 2,  $0000ff)
    Circle(x2, y2, 2,  $0000ff)
    Circle(x3, y3, 2,  $0000ff)
    Circle(x4, y4, 2,  $0000ff)
    LineXY(x1, y1,x2, y2, $00ffff)
    LineXY(x2, y2,x3, y3, $00ffff)
    LineXY(x3, y3,x4, y4, $00ffff)
    LineXY(x1, y1,x4, y4, $00ffff)
    StopDrawing()
  EndIf
 
EndProcedure

InitSprite()

Enumeration
  #Window
  #Sprite
  #Font
EndEnumeration

LoadFont(#Font, "Arial", 24)

OpenWindow(#Window, 0, 0, 800, 600, "ScreenTitle", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)

CreateSprite(#Sprite, 200, 50)
If StartDrawing(SpriteOutput(#Sprite))
  DrawingFont(FontID(#Font))
  Box(0, 0, OutputWidth(), OutputHeight(), $808080)
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(0, 0, "Pure Basic", $FFFFFF)
  StopDrawing()
EndIf

ClearScreen(0)

SpriteTransformation(#Sprite, 0, 0, 200, 50, 0)
DisplaySprite(#Sprite, 200, 100)
CalculCoin(0, 0, 200, 50, 0, 200, 100)


SpriteTransformation(#Sprite, 0, 0, 200, 50, 45)
DisplaySprite(#Sprite, 400, 200)
CalculCoin(0, 0, 200, 50, 45, 400, 200)

SpriteTransformation(#Sprite, 50, 20, 100, 25, -45)
DisplaySprite(#Sprite, 600, 300)
CalculCoin(50, 20, 100, 25, -45, 600, 300)


FlipBuffers()

Repeat
 
  Repeat
   
    Select WindowEvent()
      Case #PB_Event_CloseWindow
        End
      Case #Null
        Break
    EndSelect
   
  ForEver
 
 
 
ForEver