Récupérer un sprite tourné dans un autre sprite

Sujets variés concernant le développement en PureBasic
Avatar de l’utilisateur
DjPoke
Messages : 121
Inscription : mar. 02/nov./2010 13:53
Localisation : Corte, Corse, France
Contact :

Récupérer un sprite tourné dans un autre sprite

Message par DjPoke »

Bonjour à tous

Est-il possible de récupérer l'image d'un sprite (png, avec transparence) ayant subi une rotation et/ou un zoom, et de la copier dans un nouveau sprite vierge n'ayant subi, lui, aucune transformation ?

Merci.
Avatar de l’utilisateur
TazNormand
Messages : 1294
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Re: Récupérer un sprite tourné dans un autre sprite

Message par TazNormand »

Comme ça je dirai tout simplement avec CopySprite()
Image
Image
Avatar de l’utilisateur
DjPoke
Messages : 121
Inscription : mar. 02/nov./2010 13:53
Localisation : Corte, Corse, France
Contact :

Re: Récupérer un sprite tourné dans un autre sprite

Message par DjPoke »

Hélas, CopySprite copie un sprite dans un autre, pas un sprite dans une image. :/
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Récupérer un sprite tourné dans un autre sprite

Message par falsam »

TazNormand a écrit :Comme ça je dirai tout simplement avec CopySprite()
Hum, je ne le crois pas. Le sprite reprendra sa forme d'origine :wink:

Code : Tout sélectionner

InitSprite()
InitKeyboard()
InitMouse()

OpenWindow(0, 0, 0, 0, 0, "FullScreen", #PB_Window_BorderLess | #PB_Window_Maximize)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0))

;Dessin sprite d'origine
Sprite0 = CreateSprite(#PB_Any, 100, 100)
StartDrawing(SpriteOutput(Sprite0))
  Box(0, 0, 100, 100, #Red)
StopDrawing()

;Rotation du sprite d'origine
RotateSprite(Sprite0, 45, #PB_Absolute)

;Copy du sprite d'origine dans un nouveau sprite
Sprite1 = CopySprite(Sprite0, #PB_Any)

Repeat
  Repeat : Until WindowEvent() = 0
  
  ClearScreen(RGB(75, 0, 130))
  
  ;Affichage du sprite d'origine avec sa rotation
  DisplaySprite(Sprite0, 100, 100)
  
  ;Affichage de la copie et Ooops ! Fonctionne pas
  DisplaySprite(Sprite1, 250, 100)
  
  ExamineKeyboard()
  FlipBuffers()
  
Until KeyboardReleased(#PB_Key_Escape)
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
DjPoke
Messages : 121
Inscription : mar. 02/nov./2010 13:53
Localisation : Corte, Corse, France
Contact :

Re: Récupérer un sprite tourné dans un autre sprite

Message par DjPoke »

J'a essayé ça, mais j'obtiens un fond noir au lieu d'un fond avec transparence Alpha :

Code : Tout sélectionner

  ClearScreen(0)
  StartDrawing(ScreenOutput())
  DrawingMode(#PB_2DDrawing_AllChannels)
  Box(0, 0, SpriteWidth(TempSprite), SpriteHeight(TempSprite), RGBA(0, 0, 0, 0))
  StopDrawing()
  
  DisplayTransparentSprite(TempSprite, 0, 0)
  
  StartDrawing(ScreenOutput())
  DrawingMode(#PB_2DDrawing_AllChannels)
  GrabDrawingImage(id, 0, 0, SpriteWidth(TempSprite), SpriteHeight(TempSprite))
  StopDrawing()
Avatar de l’utilisateur
TazNormand
Messages : 1294
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Re: Récupérer un sprite tourné dans un autre sprite

Message par TazNormand »

En reprenant le code de Falsam à l'arrache, j'ai juste utilisé GrabSprite(), bien sur il faut adapter le code, car la transformation par rotation change la taille du sprite :

Code : Tout sélectionner

InitSprite()
InitKeyboard()
InitMouse()

OpenWindow(0, 0, 0, 0, 0, "FullScreen", #PB_Window_BorderLess | #PB_Window_Maximize)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0))

;Dessin sprite d'origine
Sprite0 = CreateSprite(#PB_Any, 100, 100)
StartDrawing(SpriteOutput(Sprite0))
  Box(0, 0, 100, 100, #Red)
StopDrawing()

;Rotation du sprite d'origine
RotateSprite(Sprite0, 45, #PB_Absolute)

;Copy du sprite d'origine dans un nouveau sprite
Sprite1 = CopySprite(Sprite0, #PB_Any)

Repeat
  Repeat : Until WindowEvent() = 0
 
  ClearScreen(RGB(75, 0, 130))
 
  ;Affichage du sprite d'origine avec sa rotation
  DisplaySprite(Sprite0, 100, 100)
 
  ;Affichage de la copie et Ooops ! Fonctionne pas
  DisplaySprite(Sprite1, 250, 100)
  
  Sprite2 = GrabSprite(5,100,100,100,100,#PB_Sprite_AlphaBlending)
  
  ;Affichage de la copie via GrabSprite
  DisplaySprite(5, 450, 100)
 
  ExamineKeyboard()
  FlipBuffers()
 
Until KeyboardReleased(#PB_Key_Escape)
Image
Image
Avatar de l’utilisateur
DjPoke
Messages : 121
Inscription : mar. 02/nov./2010 13:53
Localisation : Corte, Corse, France
Contact :

Re: Récupérer un sprite tourné dans un autre sprite

Message par DjPoke »

@TazNormand
Merci de ton aide, mais j'ai besoin de garder la transparence alpha.
Dernière modification par DjPoke le lun. 03/juil./2017 14:38, modifié 1 fois.
Avatar de l’utilisateur
TazNormand
Messages : 1294
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Re: Récupérer un sprite tourné dans un autre sprite

Message par TazNormand »

D'où le #PB_Sprite_Alphablending du GrabSprite()
Image
Image
Mesa
Messages : 1098
Inscription : mer. 14/sept./2011 16:59

Re: Récupérer un sprite tourné dans un autre sprite

Message par Mesa »

Il faut tout refaire à la main, tu peux t'inspirer du code de demivec:

Code : Tout sélectionner

;Program description: Sprite transformation effects
;Author: Demivec
;Written for: Originally for PB 4.61, with Windows OS, may not function correctly for other OS.
;             It does not function correctly with the OpenGL subsystem.
;Date Written: 2 July 2012
;Last Updated: 4 October 2015 for PB 5.40b8 and added some additional features.
;

EnableExplicit
; Structure Point
;   x.i
;   y.i
; EndStructure

Structure Point_f
  x.f
  y.f
EndStructure

Enumeration sprites
  #spr_pb
  #spr_corner
  #spr_text_1
  #spr_text_2
  #spr_text_3
  #spr_text_4
  #spr_mousePointer
EndEnumeration

Enumeration fonts
  #font_large
  #font_small
EndEnumeration

Enumeration windows
  #win_main  
EndEnumeration

Procedure handleError(value, text.s = "Unknown Error.")
  If value = 0
    MessageRequester("Error", text)
    End
  EndIf
EndProcedure

;Sprite info: (width, height) = original dimensions, (newWidth, newHeight) = zoom dimensions,
; degree = rotation amount, (cx,cy) = center point for rotation
Procedure MakeSpriteTransformation(spriteID, width, height, cx, cy, degree, newWidth, newHeight)
  Protected.Point_f p1, p2, p3, p4
  Protected.f wf = width / newWidth, hf = height / newHeight
  
  If degree = 0
    ;simple transformation: no rotation, only zooming and translation movements possible 
    p1\x = ((       -cx) / wf) - 0.5: p1\y = ((        -cy) / hf) - 0.5
    p2\x = ((width - cx) / wf) - 0.5: p2\y = ((        -cy) / hf) - 0.5
    p3\x = ((width - cx) / wf) - 0.5: p3\y = ((height - cy) / hf) - 0.5
    p4\x = ((       -cx) / wf) - 0.5: p4\y = ((height - cy) / hf) - 0.5
    
  Else
    ;more complex transformation: rotation (around point cx,cy) and zooming possible 
    Protected.f angCos = Cos(Radian(degree)), angSin = Sin(Radian(degree))
    Protected.f v1, v2, v3, v4, v5, v6, v7, v8
    
    v1 = -cx * angCos: v3 = -cy * angSin
    v2 = -cx * angSin: v4 = -cy * angCos
    
    v6 = (width - cx) * angCos: v7 = (height - cy) * angSin
    v5 = (width - cx) * angSin: v8 = (height - cy) * angCos
    
    p1\x = ((v1 - v3) / wf) - 0.5: p1\y = ((v4 + v2) / hf) - 0.5
    p2\x = ((v6 - v3) / wf) - 0.5: p2\y = ((v4 + v5) / hf) - 0.5
    p3\x = ((v6 - v7) / wf) - 0.5: p3\y = ((v8 + v5) / hf) - 0.5
    p4\x = ((v1 - v7) / wf) - 0.5: p4\y = ((v8 + v2) / hf) - 0.5
  EndIf  
  
  TransformSprite(spriteID, p1\x, p1\y, p2\x, p2\y,  p3\x, p3\y,  p4\x, p4\y)
EndProcedure

;iso (squish) rotated clockwise degrees
Procedure MakeSpriteIsoClockwise(spriteID, width, height, cx, cy, degree, newWidth, newHeight)
  MakeSpriteTransformation(spriteID, width, height, cx, cy, degree, newWidth, newHeight)
EndProcedure

;iso (squish) rotated counter-clockwise degrees
Procedure  MakeSpriteIsoCounterClockwise(spriteID, width, height, cx, cy, degree, newWidth, newHeight)
  MakeSpriteTransformation(spriteID, width, height, cx, cy, 360 - degree, newWidth, newHeight)
EndProcedure  

Procedure MakeSpriteRotate(SpriteID, cx, cy, degree)
  Protected width = SpriteWidth(SpriteID), height = SpriteHeight(SpriteID)
  ZoomSprite(SpriteID, #PB_Default, #PB_Default)
  MakeSpriteTransformation(spriteID, width, height, cx, cy, degree, width, height)
EndProcedure

Procedure MakeSpriteZoomHorizontal(SpriteID, cx, cy, newWidth)
  Protected width = SpriteWidth(SpriteID), height = SpriteHeight(SpriteID)
  ZoomSprite(SpriteID, #PB_Default, #PB_Default)
  MakeSpriteTransformation(spriteID, width, height, cx, cy, 0, newWidth, height)
EndProcedure

Procedure MakeSpriteZoomVertical(SpriteID, cx, cy, newHeight)
  Protected width = SpriteWidth(SpriteID), height = SpriteHeight(SpriteID)
  ZoomSprite(SpriteID, #PB_Default, #PB_Default)
  MakeSpriteTransformation(spriteID, width, height, cx, cy, 0, width, newHeight)
EndProcedure

Procedure MakeSpriteNormal(SpriteID, cx = 0, cy = 0)
  Protected width = SpriteWidth(SpriteID), height = SpriteHeight(SpriteID)
  ZoomSprite(SpriteID, #PB_Default, #PB_Default)
  MakeSpriteTransformation(spriteID, width, height, cx, cy, 0, width, height)
EndProcedure


handleError(InitSprite(), "Can't open screen & sprite enviroment.")
handleError(InitMouse(), "Can't initialize mouse handler.")
handleError(InitKeyboard(), "Can't initialize keyboard handler.")
handleError(OpenWindow(#win_main, 0, 0, 800, 600, "Sprite Transformations, drag numbered corners to transform",
                       #PB_Window_SystemMenu | #PB_Window_ScreenCentered), "Can't open window.")
handleError(OpenWindowedScreen(WindowID(#win_main), 0, 0, 800, 600, 0, 0, 0), "Can't open windowed screen.")

handleError(LoadFont(#font_large, "Arial", 36), "Unable to load font.")
handleError(LoadFont(#font_small, "Arial", 8), "Unable to load font.")
handleError(CreateSprite(#spr_pb, 64, 64), "Sprite creation failed.")
handleError(StartDrawing(SpriteOutput(#spr_pb)), "Can't draw on sprite.")
Box(0,0,64,64,RGB($FF,$FF,$00))
DrawingMode(#PB_2DDrawing_Outlined)
DrawingFont(FontID(#font_large))
DrawText(0,0,"PB",RGB($FF,$00,$00))
Box(0,0,64,64,RGB($00,$00,$FF))
LineXY( 0,0,64,64,RGB($00,$00,$FF))
LineXY(64,0, 0,64,RGB($00,$00,$FF))
StopDrawing()

handleError(CreateSprite(#spr_mousePointer, 8, 8, #PB_Sprite_AlphaBlending), "Sprite creation failed.")
handleError(StartDrawing(SpriteOutput(#spr_mousePointer)), "Can't draw on sprite.")
FrontColor(RGB($00,$FF,$FF))
LineXY(0,0, OutputWidth() - 1,OutputHeight() - 1)
LineXY(0,0, 0,OutputHeight() - 3)
LineXY(0,0, OutputWidth() - 3,0)
StopDrawing()
TransparentSpriteColor(#spr_mousePointer, RGB($00,$00,$00))


handleError(CreateSprite(#spr_corner, 8, 8, #PB_Sprite_AlphaBlending), "Sprite creation failed.")
handleError(StartDrawing(SpriteOutput(#spr_corner)), "Can't draw on sprite.")
Box(0, 0, OutputWidth(), OutputHeight(), RGB($00, $FF, $00))
StopDrawing()

DataSection
  cornerCoordinates:
  Data.i 0,0, 64,0, 64,64, 0,64
EndDataSection

Dim corner.Point(3)
Define customSpritePosX = 400, customSpritePosY = 400, i
Restore cornerCoordinates
For i = 0 To 3
  handleError(CreateSprite(#spr_text_1 + i, 8, 16, #PB_Sprite_AlphaBlending), "Sprite creation failed.")
  handleError(StartDrawing(SpriteOutput(#spr_text_1 + i)), "Can't draw on sprite.")
  DrawingMode(#PB_2DDrawing_Outlined)
  DrawingFont(FontID(#font_small))
  DrawText(0, 0, Str(i + 1),RGB($FF,$FF,$FF),RGB($00,$00,$00))
  StopDrawing()
  TransparentSpriteColor(#spr_text_1 + i, RGB($00,$00,$00))
  Read.i corner(i)\x: corner(i)\x + customSpritePosX
  Read.i corner(i)\y: corner(i)\y + customSpritePosY
Next

Define direction = 2
Define zoomX     = 64
Define zoomY     = 64
Define angle, newWidth, newHeight, displayRow, event, i

ReleaseMouse(1)
Define mouseIsReleased = #True, dragCorner = -1
Repeat
  Repeat
    event = WindowEvent()
    Select event 
      Case #PB_Event_CloseWindow
        End 
    EndSelect
  Until event = 0
  
  FlipBuffers() 
  ClearScreen(RGB($40, $40, $40))
  
  displayRow = 70
  MakeSpriteNormal(#spr_pb, 32, 32) ;normal appearance
  DisplaySprite(#spr_pb, 100, displayRow) ;location is needed because display location was not part of transformation
  
  MakeSpriteRotate(#spr_pb, 32, 32, angle) ;rotate around center
  DisplaySprite(#spr_pb, 200, displayRow)
  MakeSpriteRotate(#spr_pb, 16, 16, angle) ;rotate around non-center point
  DisplaySprite(#spr_pb, 350, displayRow)
  newWidth = zoomX: newHeight = zoomX
  MakeSpriteZoomHorizontal(#spr_pb, 32, 32, newWidth) ;zoom horizontally
  DisplaySprite(#spr_pb, 500, displayRow)
  MakeSpriteZoomVertical(#spr_pb, 32, 32, newHeight) ;zoom vertically
  DisplaySprite(#spr_pb, 600, displayRow)
  
  displayRow = 280
  MakeSpriteIsoCounterClockwise(#spr_pb, 64, 64, 32, 32, angle, 64, 32) ;squished vertically
  DisplaySprite(#spr_pb, 200 - zoomX * 0.5, displayRow - zoomY * 0.5)
  MakeSpriteIsoCounterClockwise(#spr_pb, 64, 64, 32, 32, angle, 32, 64) ;squished horizontally
  DisplaySprite(#spr_pb, 300 - zoomX * 0.5, displayRow - zoomY * 0.5)
  
  MakeSpriteIsoClockwise(#spr_pb, 64, 64, 32, 32, angle, 2 * zoomX, 1 * zoomX) ;squished vertically and zoomed
  DisplaySprite(#spr_pb, 700 - zoomX * 0.5, displayRow - zoomY * 0.5)
  MakeSpriteIsoClockwise(#spr_pb, 64, 64, 32, 32, angle, 1 * zoomX, 2 * zoomX) ;squished horizontally and zoomed
  DisplaySprite(#spr_pb, 500 - zoomX * 0.5, displayRow - zoomY * 0.5)
  
  displayRow = 400
  MakeSpriteIsoCounterClockwise(#spr_pb, 64, 64, 32, 32, angle, 64, 20 + zoomX / 2) ;squishiness varying vertically
  DisplaySprite(#spr_pb, 100, displayRow)
  MakeSpriteIsoCounterClockwise(#spr_pb, 64, 64, 32, 32, angle, 20 + zoomX / 2, 64) ;squishiness varying horizontally
  DisplaySprite(#spr_pb, 200, displayRow)
  
  
  ExamineMouse()
  
  ;handle screen mouse activation/deactivation
  If MouseX() < 2 Or MouseX() > ScreenWidth() - 3 Or MouseY() < 2 Or MouseY() > ScreenHeight() -3
    ReleaseMouse(1): mouseIsReleased = #True
  EndIf
  
  If WindowMouseX(#win_main) >= 2 And
     WindowMouseX(#win_main) < WindowWidth(#win_main, #PB_Window_InnerCoordinate) - 2 And
     WindowMouseY(#win_main) >= 2 And
     WindowMouseY(#win_main) < WindowHeight(#win_main, #PB_Window_InnerCoordinate) - 2
    ReleaseMouse(0): mouseIsReleased = #False
    MouseLocate(WindowMouseX(#win_main), WindowMouseY(#win_main))
  EndIf
  
  ;handle corner dragging for deformable sprite
  If Not mouseIsReleased
    If MouseButton(#PB_MouseButton_Left)
      If dragCorner = -1
        For i = 0 To 3
          If SpriteCollision(#spr_corner, corner(i)\x, corner(i)\y, #spr_mousePointer, MouseX(), MouseY())
            dragCorner = i
            MouseDeltaX(): MouseDeltaY() ;reset these values for further reads
            Break
          EndIf
        Next
      Else
        corner(dragCorner)\x + MouseDeltaX(): corner(dragCorner)\y + MouseDeltaY()  
      EndIf
    ElseIf dragCorner <> -1
      corner(dragCorner)\x + MouseDeltaX(): corner(dragCorner)\y + MouseDeltaY()  
      dragCorner = -1 ;signal that no corner is being dragged      
    EndIf
  EndIf
  TransformSprite(#spr_pb, corner(0)\x,corner(0)\y, corner(1)\x,corner(1)\y, corner(2)\x,corner(2)\y, corner(3)\x,corner(3)\y)
  DisplaySprite(#spr_pb, 0, 0)  ;drawn at location 0,0 because sprite location is part of transformation
  
  ;display corners for dragging
  For i = 0 To 3
    DisplayTransparentSprite(#spr_corner, corner(i)\x, corner(i)\y, 128)
    DisplayTransparentSprite(#spr_text_1 + i, corner(i)\x + 8, corner(i)\y)
  Next
  If Not mouseIsReleased: DisplayTransparentSprite(#spr_mousePointer, MouseX(), MouseY()): EndIf
  
  ;update animation attributes
  angle + 1: If angle > 360: angle = 0: EndIf
  zoomX + direction
  
  If zoomX > 100  : direction = -2 : EndIf
  If zoomX < 20   : direction =  2 : EndIf
  
  ExamineKeyboard()
  If KeyboardPushed(#PB_Key_Escape): Break: EndIf
  Delay(1)
ForEver
M.
Avatar de l’utilisateur
TazNormand
Messages : 1294
Inscription : ven. 27/oct./2006 12:19
Localisation : Calvados (14)

Re: Récupérer un sprite tourné dans un autre sprite

Message par TazNormand »

Et comme ça ?

Code : Tout sélectionner

InitSprite()
InitKeyboard()
InitMouse()

OpenWindow(0, 0, 0, 0, 0, "FullScreen", #PB_Window_BorderLess | #PB_Window_Maximize)
OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0))

;Dessin sprite d'origine
Sprite0 = CreateSprite(#PB_Any, 100, 100)
StartDrawing(SpriteOutput(Sprite0))
Box(0, 0, 100, 100, #Red)
Box(20,20,60,60, RGB(0, 0, 0))
StopDrawing()

;Rotation du sprite d'origine
RotateSprite(Sprite0, 45, #PB_Absolute)

;Copy du sprite d'origine dans un nouveau sprite
Sprite1 = CopySprite(Sprite0, #PB_Any)

Repeat
  Repeat : Until WindowEvent() = 0

  ClearScreen(RGB(75, 0, 130))

  ;Affichage du sprite d'origine avec sa rotation
  TransparentSpriteColor(sprite0,RGB(0,0,0))
  DisplayTransparentSprite(Sprite0, 100, 100)

  ;Affichage de la copie et Ooops ! Fonctionne pas
  TransparentSpriteColor(sprite1,RGB(0,0,0))
  DisplayTransparentSprite(Sprite1, 250, 100)
 
  Sprite2 = GrabSprite(5,100,100,100,100,#PB_Sprite_AlphaBlending)
 
  ;Affichage de la copie via GrabSprite
  TransparentSpriteColor(5,RGB(0,0,0))
  DisplayTransparentSprite(5, 450, 100)

  ExamineKeyboard()
  FlipBuffers()

Until KeyboardReleased(#PB_Key_Escape)
Image
Image
Avatar de l’utilisateur
DjPoke
Messages : 121
Inscription : mar. 02/nov./2010 13:53
Localisation : Corte, Corse, France
Contact :

Re: Récupérer un sprite tourné dans un autre sprite

Message par DjPoke »

Merci TazNormand, et merci à tous.
Ca y est, j'ai enfin compris, ça marche ! :)


EDIT:
Voilà, j'en ai fait une petite procedure pour faire tourner les images, mais je rencontre un petit probleme avec la couleur noire, qui devient parfois transparente.
Si quelqu'un a une idée...

Image

Code : Tout sélectionner

; Rotation d'image (pour l'instant, il faut faire ses rotations avant le reste, je crois)
Procedure.l RotateImage(id.l, angle.d)
  
  Protected.l x, y, w, h, TempSprite, TempSprite2, id1, id2, safeScreen
  
  ; On sauvegarde le buffer écran tel qu'il est
  ; 
  ; GrabDrawingImage envoie un message d'erreur s'il n'est pas dans une boucle startdrawing/stopdrawing
  ; et si on l'y met, on a des problemes après pour capturer les sprites
  ;StartDrawing(ScreenOutput())
  ;DrawingMode(#PB_2DDrawing_AllChannels)
  ;GrabDrawingImage(safeScreen, 0, 0, ScreenWidth(), ScreenHeight())
  ;StopDrawing()
  
  ; On récupère la taille de l'image que l'on veut tourner
  w = ImageWidth(id)
  h = ImageHeight(id)
  
  ; Transformer l'image en sprite
  TempSprite = CreateSprite(#PB_Any, w, h, #PB_Sprite_AlphaBlending)
  
  StartDrawing(SpriteOutput(TempSprite))
  DrawingMode(#PB_2DDrawing_AllChannels)
  DrawImage(ImageID(id), 0, 0)
  StopDrawing()
  
  ; Supprimer temporairement l'image
  FreeImage(id)
  
  ; Effacer l'écran avec alpha à 0
  ClearScreen(0)
  StartDrawing(ScreenOutput())
  DrawingMode(#PB_2DDrawing_AllChannels)
  Box(0, 0, ScreenWidth(), ScreenHeight(), RGBA(0, 0, 0, 0))
  StopDrawing()
  
  ; Faire tourner le sprite
  RotateSprite(TempSprite, angle, #PB_Absolute)
  
  ; Et l'afficher à l'écran (avec une bordure de 2 pixels)
  DisplayTransparentSprite(TempSprite, 2, 2)
  
  w = SpriteWidth(TempSprite) + 4
  h = SpriteHeight(TempSprite) + 4
  
  ; Récupérer le sprite tourné dans l'écran
  TempSprite2 = GrabSprite(#PB_Any, 0, 0, w, h, #PB_Sprite_AlphaBlending)

  ; On en crée une nouvelle, transparente aussi
  CreateImage(id, w, h, 32, #PB_Image_Transparent)
  
  ; Et on récupère le sprite dans l'image
  StartDrawing(SpriteOutput(TempSprite2))
  DrawingMode(#PB_2DDrawing_AllChannels)
  GrabDrawingImage(id, 0, 0, w, h)
  StopDrawing()
  
  ; Version de PB 5.60 : Il semble y avoir un bug dans GrabDrawingImage
  ; qui fait que l'image est en symetrie verticale, donc, on rectifie
  For y = 0 To Int(h/2) - 1
    id1 = GrabImage(id, #PB_Any, 0, y, w, 1)
    id2 = GrabImage(id, #PB_Any, 0, (h-1)-y, w, 1)
    StartDrawing(ImageOutput(id))
    DrawingMode(#PB_2DDrawing_AllChannels)
    DrawImage(ImageID(id1), 0, (h-1)-y)
    DrawImage(ImageID(id2), 0, y)
    StopDrawing()
  Next
  
  FreeSprite(TempSprite)
  FreeSprite(TempSprite2)
  
  ; Et on restaure l'état du buffer écran
  ;StartDrawing(ScreenOutput())
  ;DrawingMode(#PB_2DDrawing_Default)
  ;DrawImage(ImageID(safeScreen), 0, 0)
  ;StopDrawing()
  
EndProcedure
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Récupérer un sprite tourné dans un autre sprite

Message par blendman »

Mesa : ton code est excellent !

@DJpoke :
ici, sur ton code :

Code : Tout sélectionner

; Effacer l'écran avec alpha à 0
  ClearScreen(0)
  StartDrawing(ScreenOutput())
  DrawingMode(#PB_2DDrawing_AllChannels)
  Box(0, 0, ScreenWidth(), ScreenHeight(), RGBA(0, 0, 0, 0))
  StopDrawing()

Tu as essayé ça :
Box(0, 0, ScreenWidth(), ScreenHeight(), RGBA(1, 1, 1, 0))

Je ne sais pas si le screen gère la transparence d'ailleurs (le A du rgba()).
Répondre