Page 1 sur 2

[ok] Sprite selection (ou collision)

Publié : dim. 24/avr./2016 7:20
par blendman
salut

J'aimerai savoir s'il existe une technique pour savoir si deux sprites entrent en collision après une rotation ou transformation ?

J'ai essayé avec la méthode spritepixelcollision(), spritecollision(), mais rien ne marche avec les transformations :(
En fait, j'aimerai juste savoir qd la souris se trouve au dessus d'un sprite (pour pouvoir le sélectionner par exemple) :

Code : Tout sélectionner

#Window_main = 0


If InitSprite() =0 Or InitKeyboard()  =0
    End
EndIf

Procedure SpriteTransformation(Sprite.i, X.f, Y.f, Width.f, Height.f, Angle.f)
   
    ; by stargate
   
   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


flag = #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget
WinW =1024
WinH =768

If OpenWindow(#Window_main,0,0,WinW,WinH, "Sprite selection", Flag) = 0
    End
EndIf
If OpenWindowedScreen(WindowID(0), 0,0,WinW,WinH) = 0
    End
EndIf

LoadSprite(0,#PB_Compiler_Home+"Examples\Sources\Data\PurebasicLogo.bmp",#PB_Sprite_PixelCollision)
CopySprite(0,1,#PB_Sprite_PixelCollision)
W =SpriteWidth(0)
H =SpriteHeight(0)
r.d = 1
x = 150
y = 150
x1 = 450
y1 = 400

CreateSprite(2,200,40,#PB_Sprite_PixelCollision)

cursor = 3
CreateSprite(cursor,4,4,#PB_Sprite_PixelCollision)
 
If StartDrawing(SpriteOutput(3))
    Box(0,0,OutputWidth(),OutputHeight(),RGBA(255,255,255,255))        
    StopDrawing()
EndIf
    
Repeat
   
    Repeat       
        EventID  = WindowEvent()
       
        Select EventID               
            Case #PB_Event_CloseWindow
                End               
        EndSelect       
    Until event = 0
   
    ClearScreen(RGB(50,50,50))
    
    mx = WindowMouseX(0)
    my = WindowMouseY(0)
    DisplayTransparentSprite(cursor,mx,my,255,RGBA(255,255,255,255))
    
    txt$ = ""
    ;If (mx>=x And mx<=x+w And my>=y And my<=y+h) Or SpritePixelCollision(0,mx,my,cursor,mx,my)
    If SpritePixelCollision(0,x,y,cursor,mx,my) <> 0
        txt$ = "mouse over sprite0"
    EndIf
    
    txt1$=""
    ;If (mx>=x1 And mx<=x1+w And my>=y1 And my<=y1+h) Or SpritePixelCollision(1,mx,my,cursor,mx,my)
    If SpritePixelCollision(1,x1,y1,cursor,mx,my) <> 0
        txt1$ = "mouse over sprite1"
    EndIf
    
    If StartDrawing(SpriteOutput(2))
        Box(0,0,OutputWidth(),OutputHeight(),0)
        DrawText(0,0,txt$+" | " +txt1$)
        StopDrawing()
    EndIf
    
    DisplayTransparentSprite(0,x,y,255,#Red)
    SpriteTransformation(1, -10,-(h*r)/2, w*r, h*r ,60)
    DisplaySprite(1,x1,y1)
    
    DisplaySprite(2,0,0) 
    
    FlipBuffers()
   
Until Quit = 1
J'ai pensé utilisé une technique avec cos-sin pour x et sin+cos pour y, en vérifiant si la souris (mx,my) se trouve entre tous les pixels de chaque sprite, mais j'ai peur que ce soit super lourd.

Si vous avez une technique ou une piste, ça m'intéresse grandement :)

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 10:59
par Ar-S
C'est vrai que si pixel collision ne prend pas en charge les transformations, des fonctions comme

Code : Tout sélectionner

SpriteX1(#sprite), SpriteX2(#sprite), SpriteY1(#sprite), SpriteY2(#sprite)
seraient appréciées.

Dans ton exemple PixelColision marche mais ne prend pas en compte les nouvelles coordonnées de la transformation.

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 11:26
par blendman
A quoi servirait spriteX1(), SPriteX2() , spriteY1() et spriteY2() pour les collisions ?

Car moi, j'ai les coordonnées X1, Y1 et peut -être x2 et y2 ^^ (mais je ne peux pas tester comme si le psrite était encore un rectangle (sprite sans rotation), car avec une rotation c'est différent.

Un truc qu'on m'a suggéré (si j'ai bien saisi), ce serait de créer un autre sprite contenant le sprite original avec rotation et tester sur celui les collisions. Mais j'ai l'impression car ça risque d'être gourmand en ressources si je fais ça sur tous les sprites ^^.

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 11:46
par falsam
blendman a écrit :Mais j'ai l'impression car ça risque d'être gourmand en ressources si je fais ça sur tous les sprites ^^.
Et peut être une usine à gaz.

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 14:23
par Ar-S
Et en utilisant un Point() qui comparerait la couleur des pixel du sprite survolé à celle du fond ?

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 14:36
par blendman
Ar-S a écrit :Et en utilisant un Point() qui comparerait la couleur des pixel du sprite survolé à celle du fond ?
avec plusieurs sprites qui se chevauchent, je ne pense pas que ça fonctionnerait ^^.

Pour le moment, ce que j'ai fait, c'est ajouter un "centre" sous forme de sprite circulaire et je tester la distance à ce centre pour savoir si on clique sur le sprite par exemple.
Ce n'est pas super, mais ça me permet de sélectionner les sprites (ou les bones) en attendant de trouver mieux ^^ :

Image

Mais bon, si vous avez d'autres idées, je suis toujours preneur ^^.

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 15:45
par comtois
Pour un éditeur tu n'as pas besoin d'être au pixel près, tu peux utiliser la bounding box, cherche des trucs sur point dans OBB 'Oriented Bounding Box'. C'est le même genre de transformation que tu fais pour ton sprite. ou des trucs sur changement de repère, après tu fais un simple test point dans une box.

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 16:56
par blendman
comtois a écrit :Pour un éditeur tu n'as pas besoin d'être au pixel près, tu peux utiliser la bounding box, cherche des trucs sur point dans OBB 'Oriented Bounding Box'. C'est le même genre de transformation que tu fais pour ton sprite. ou des trucs sur changement de repère, après tu fais un simple test point dans une box.
oui, ça m'intéresse tout ça :)

J'ai cherché mais je n'ai rien trouvé qui puisse m'aider, c'est souvent du code (c++) que je ne sais pas convertir.

Pour le changement de repère, c'est que je pensais faire. Mais comment procéder à ça ?

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 17:05
par Fig
Si tu connais l'angle de rotation de ton sprite et son point de pivot (et forcément tu les connais), tu peux faire tourner la coordonnée de la souris le long du cercle ayant pour centre ton point de pivot et de l'angle de ton sprite.
Tu fais alors le test entre la nouvelle coordonnée calculée de ta souris et le sprite dans sa position non tournée.

Ca devrait marcher en théorie... :wink:

Image

Pour rappel les coordonnées d'un point sur un cercle sont:
X=rayon*Cos(angle)
Y=rayon*Sin(angle)

les coordonnées de ta souris:
Xs et Ys
Asprite est l'angle de rotation de ton sprite
Xp et Yp sont les coordonnées de ton point de pivot
As est l'angle de souris

On change le repère en mettant le pivot aux coordonnées (0,0), on ajuste les coordonnées de la souris au nouveau repere:
Xs'=Xs-Xp
Ys'=Ys-Yp
Le rayon entre le pivot et la souris est donc:
R=racine carrée(Xs'²+Ys'²)
On a donc:
Xs'=R*cos(As)
on cherche As
As=invCos(Xs'/R)

On soustrait notre angle de rotation à celui de la souris et on calcul ses nouvelles coordonnées:
Xs"=R*cos(As-Asprite)
Ys"=R*sin(As-Asprite)
On repasse dans le repère de l'écran
Xs'''=Xs"+Xp
Ys'''=Ys"+Yp

Tu peux alors comparer ces coordonnées à ton sprite sans rotation.
Démonstration à vérifier et simplifier par qqu'un de bon en trigo, moi, la trigo... heu... :oops:

Je vais essayer de te pondre un code.

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 18:46
par blendman
j'ai testé ça, mais ça ne marche pas (pas encore) :

Code : Tout sélectionner

#Window_main = 0


If InitSprite() =0 Or InitKeyboard()  =0
    End
EndIf

Procedure SpriteTransformation(Sprite.i, X.f, Y.f, Width.f, Height.f, Angle.f)
   
    ; by stargate
   
   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


flag = #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget
WinW =1200
WinH =768

If OpenWindow(#Window_main,0,0,WinW,WinH, "Sprite selection", Flag) = 0
    End
EndIf
If OpenWindowedScreen(WindowID(0), 0,0,WinW,WinH) = 0
    End
EndIf

LoadSprite(0,#PB_Compiler_Home+"Examples\Sources\Data\PurebasicLogo.bmp",#PB_Sprite_PixelCollision)
CopySprite(0,1,#PB_Sprite_PixelCollision)
W =SpriteWidth(0)
H =SpriteHeight(0)
r.d = 1
x = 150
y = 150
x1 = 450
y1 = 400

CreateSprite(2,200,40,#PB_Sprite_PixelCollision)

cursor = 3
CreateSprite(cursor,4,4,#PB_Sprite_PixelCollision)

CreateSprite(4,5,5)

If StartDrawing(SpriteOutput(3))
    Box(0,0,OutputWidth(),OutputHeight(),RGBA(255,255,255,255))       
    StopDrawing()
EndIf

If StartDrawing(SpriteOutput(4))
    Box(0,0,OutputWidth(),OutputHeight(),RGBA(255,255,255,255))       
    StopDrawing()
EndIf
   
Repeat
   
    Repeat       
        EventID  = WindowEvent()
       
        Select EventID               
            Case #PB_Event_CloseWindow
                End               
        EndSelect       
    Until event = 0
   
    ClearScreen(RGB(50,50,50))
   
    mx = WindowMouseX(0)
    my = WindowMouseY(0)
    DisplayTransparentSprite(cursor,mx,my,255,RGBA(255,255,255,255))
   
    txt$ = ""
    
    txt1$=""

    If (mx>=x And mx<=x+w And my>=y And my<=y+h) 
        txt$ = "mouse over sprite0"
    EndIf
   
    
    Cos.f= Cos(Radian(60))
    Sin.f= Sin(Radian(60))
    
    
    ; transformation : X*Cos-Y*Sin, X*Sin+Y*Cos
    xa = x1;-10
    ya = y1;-(h*r)/2
    x_1 = xa*Cos-ya*Sin
    y_1 = ya*Sin+xa*Cos
    w_1 = (xa+w)*Cos-ya*Sin
    h_1 = (xa+w)*Sin+(ya+h)*Cos
    
    oldx = mx
    centerx = x1+ 10
    oldy = my
    centerY = y1-(h*r)/2
    
    
    newx = Cos * (oldx - centerx) - Sin * (oldy - centery);
    newy = Sin * (oldx - centerx) + Cos * (oldy - centery);
    ; if (newy >= centery) && (newy <= centery + height ) 
    ; && (newx >= centerx) && (newx <= centerx + width );
    
    
    m_x = mx*Cos-my*Sin
    m_y = mx*Sin+my*Cos
    
    If m_x>=x_1 And m_x<=w_1 And m_y>=y_1 And m_y<=h_1
    ;If newx>=X1 And newx<=X1+w And newy>=Y1 And newy<=Y1+h ; ok, si on v en haut, à droite = si le cursor jaune est sur le sprite semi-transparent
        txt1$ = "mouse over sprite1"
    EndIf
    
    DisplayTransparentSprite(cursor,newx,newy,255,RGBA(255,0,0,255))
    
    If StartDrawing(SpriteOutput(2))
        Box(0,0,OutputWidth(),OutputHeight(),0)
        DrawText(0,0,txt$+" | " +txt1$)
        DrawText(0,20,""+m_x+"/"+m_y+" | "+x_1+"/"+y_1+"|"+w_1+"/"+h_1)
        StopDrawing()
    EndIf
   
    DisplayTransparentSprite(0,x,y,255,#Red)
    SpriteTransformation(1, -10,-(h*r)/2, w*r, h*r ,60)
    DisplaySprite(1,x1,y1)
    
    DisplayTransparentSprite(0,x1,y1,50)
   
    DisplaySprite(2,0,0)
    
    
    
    ; pour afficher les nouvelles coordonnées du sprite
    DisplayTransparentSprite(4,x1*Cos-y1*Sin,x1*sin+y1*cos,255,RGBA(255,0,0,255))
    DisplayTransparentSprite(4,x_1,y_1,255,RGBA(255,0,0,255))
    ;DisplayTransparentSprite(4,w_1,y_1,255,RGBA(255,0,0,255))
    ;DisplayTransparentSprite(4,x_1,h_1,255,RGBA(255,0,0,255))
    ;DisplayTransparentSprite(4,w_1,h_1,255,RGBA(255,0,0,255))
    
    ; original
;     DisplayTransparentSprite(4,x1,y1,255,RGBA(255,0,0,255))
;     DisplayTransparentSprite(4,x1+w,y1,255,RGBA(255,0,0,255))
;     DisplayTransparentSprite(4,x1+w,y1+h,255,RGBA(255,0,0,255))
;     DisplayTransparentSprite(4,x1,y1+h,255,RGBA(255,0,0,255))
        
    FlipBuffers()
   
Until Quit = 1

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 19:08
par comtois
une variante, en testant un point dans un triangle.
Et ici différentes façons de déterminer si un point se trouve dans un triangle :
http://www.forums.purebasic.com/english ... 13&t=27895

Code : Tout sélectionner

Structure Vector2
  x.f
  y.f
EndStructure

Structure Box
  p1.Vector2
  p2.Vector2
  p3.Vector2
  P4.Vector2
EndStructure

Declare IsPointInsideTriangle2D(x, y, *p0.Vector2, *p1.Vector2, *p2.Vector2, *p.Vector2)
Declare SpriteTransformation(Sprite.i, *Box.Box)

#Window_main = 0

If InitSprite() =0 Or InitKeyboard()  =0
  End
EndIf

flag = #PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered|#PB_Window_MaximizeGadget|#PB_Window_SizeGadget
WinW =1024
WinH =768

If OpenWindow(#Window_main,0,0,WinW,WinH, "Sprite selection", Flag) = 0
  End
EndIf
If OpenWindowedScreen(WindowID(0), 0,0,WinW,WinH) = 0
  End
EndIf

LoadSprite(0,#PB_Compiler_Home+"Examples\Sources\Data\PurebasicLogo.bmp",#PB_Sprite_PixelCollision)
CopySprite(0,1,#PB_Sprite_PixelCollision)
W =SpriteWidth(0)
H =SpriteHeight(0)
r.d = 1
x = 150
y = 150
x1 = 450
y1 = 400

CreateSprite(2,200,40,#PB_Sprite_PixelCollision)

cursor = 3
CreateSprite(cursor,4,4,#PB_Sprite_PixelCollision)

If StartDrawing(SpriteOutput(3))
  Box(0,0,OutputWidth(),OutputHeight(),RGBA(255,255,255,255))       
  StopDrawing()
EndIf

CreateSprite(4,4,4,#PB_Sprite_PixelCollision)

If StartDrawing(SpriteOutput(4))
  Box(0,0,OutputWidth(),OutputHeight(),RGBA(255,0,0,255))       
  StopDrawing()
EndIf

Repeat
  
  Repeat       
    EventID  = WindowEvent()
    
    Select EventID               
      Case #PB_Event_CloseWindow
        End               
    EndSelect       
  Until event = 0
  
  ClearScreen(RGB(50,50,50))
  
  mx = WindowMouseX(0)
  my = WindowMouseY(0)
  DisplayTransparentSprite(cursor,mx,my,255,RGBA(255,255,255,255))
  
  If StartDrawing(SpriteOutput(2))
    Box(0,0,OutputWidth(),OutputHeight(),0)
    DrawText(0,0,txt$+" | " +txt1$)
    StopDrawing()
  EndIf
  
  DisplayTransparentSprite(0,x,y,255,#Red)
  
  
  Define Box.Box
  X_.f =  -10
  Y_.f =  -(h*r)/2
  Width.f = w*r
  Height.f =  h*r
  Angle.f = 60
  Cos.f = Cos(Radian(Angle))
  Sin.f = Sin(Radian(Angle))
  Box\p1\x = X_*Cos-Y_*Sin
  Box\p1\y = X_*Sin+Y_*Cos
  Box\p2\x = (X_+Width)*Cos-Y_*Sin
  Box\p2\y = (X_+Width)*Sin+Y_*Cos
  Box\p3\x = (X_+Width)*Cos-(Y_+Height)*Sin
  Box\p3\y = (X_+Width)*Sin+(Y_+Height)*Cos
  Box\p4\x = X_*Cos-(Y_+Height)*Sin
  Box\p4\y = X_*Sin+(Y_+Height)*Cos
  
  
  Define.Vector2 Mouse
  Mouse\x = mx
  Mouse\y = my
  
  txt$ = ""
  If IsPointInsideTriangle2D(x1, y1, @box\p1, @box\p2, @box\p3, @Mouse) Or IsPointInsideTriangle2D(x1, y1, @box\p1, @box\p3, @box\p4, @Mouse)
    txt$ = "c'est dedans"
  Else
    txt$ = "c'est dehors"
  EndIf
  
  SpriteTransformation(1, @Box)
  DisplaySprite(1,x1, y1)
  
  DisplaySprite(2,0,0)
  
  FlipBuffers()
  
Until Quit = 1

Procedure SpriteTransformation(Sprite.i, *Box.Box)
  
  TransformSprite(Sprite, *Box\p1\x, *Box\p1\y, *Box\p2\x, *Box\p2\y, *Box\p3\x, *Box\p3\y, *Box\p4\x, *Box\p4\y)
  
EndProcedure

Procedure IsPointInsideTriangle2D(x, y, *p0.Vector2, *p1.Vector2, *p2.Vector2, *p.Vector2)
  Protected.Vector2 V1, V2, V3, pi0, pi1, pi2, p0, p1, p2
  p0\x = x + *p0\x
  p0\y = y + *p0\y
  p1\x = x + *p1\x
  p1\y = y + *p1\y
  p2\x = x + *p2\x
  p2\y = y + *p2\y
  
  V1\x=p1\x-p0\x
  V1\y=p1\y-p0\y
  V2\x=p2\x-p0\x
  V2\y=p2\y-p0\y
  V3\x=p1\x-p2\x
  V3\y=p1\y-p2\y
  
  
  pi0\x=*p\x-p0\x
  pi0\y=*p\y-p0\y
  pi1\x=*p\x-p1\x
  pi1\y=*p\y-p1\y
  pi2\x=*p\x-p2\x
  pi2\y=*p\y-p2\y
  
  
  If V1\y*V2\x>V1\x*V2\y
    V1\x=-V1\x
    V1\y=-V1\y
  Else
    V2\x=-V2\x
    V2\y=-V2\y
    V3\x=-V3\x
    V3\y=-V3\y
  EndIf
  If pi0\y*V2\x>pi0\x*V2\y And pi1\y*V1\x>pi1\x*V1\y And pi2\y*V3\x>pi2\x*V3\y
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 21:32
par Fig
C'est loin d'etre parfait niveau optimisation de la procedure mais ca fonctionne très bien :mrgreen:
Fleche haute et basse pour faire tourner le sprite, souris pour tester, escape pour quitter.
(bon j'ai chargé le sprite du logo de Pb, il faut tester avec un sprite qui a des parties transparentes évidemment...)

Pour le code, voir plus bas dans le fil...

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 22:24
par comtois
Bien vu :)

Re: Sprite selection (ou collision)

Publié : dim. 24/avr./2016 23:24
par Fig
Si le sprite est étiré de manière uniforme on devrait pouvoir y arriver aussi...

Re: Sprite selection (ou collision)

Publié : lun. 25/avr./2016 7:44
par blendman
Comtois : merci beaucoup pour ton exemple, je vais étudier ça ;)

Fig : merci beaucoup aussi pour ton exemple, pouvoir vérifier les pixelcollision c'est intéressant.

Par contre, j'ai l'impression que ça ne fonctionne pas avec les TransformSprite() et ça ne marche pas très bien avec les sprite avec transparence (ou alors, j'ai fait des boulettes quelque part ^^) :

Code : Tout sélectionner

; Fig pixeltest de sprite en rotation
If InitSprite() = 0 Or InitKeyboard() = 0 Or InitMouse() = 0 Or 
   OpenWindow(0,0,0,1024,768,"test collision",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)=0 Or 
   OpenWindowedScreen(WindowID(0),0,0,1024,768)=0
    MessageRequester("Error", "Can't open the sprite system", 0)
    End
EndIf

Enumeration
    
    #logo
    #logo2
    #souris
    #pixel
    #txt
    #Centre
    
EndEnumeration

;Sprite du logo Pb

UsePNGImageDecoder()


Procedure SpriteTransformation(Sprite.i, X.f, Y.f, Width.f, Height.f, Angle.f)
    
    ; by stargate
    
    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


;renvoie 0 si pas de collision sinon il y a une collision   
Procedure TestCollision(sprite1,sprite1X,sprite1Y,sprite2,sprite2X,sprite2Y,PivotX,PivotY,angle.f,width.f=1,height.f=1)
    
    ; by Fig, légère modification par blendman , ajout width et height : 
    ; width et height en pourcentage par rapport à la taille initiale
    
    angle = Radian(360-angle)
    
    ; position
    X = (sprite2X - PivotX) * width
    Y = (sprite2Y - PivotY) * height
    
    ; distance
    R.f=Sqr((X*X)+(Y*Y))
    
    Anglem.f=ACos(X/R)
    
    If Y>0
        anglem = 2*#PI - anglem
    EndIf
    
    sprite2X = R * Cos(Anglem-angle) + PivotX * width
    sprite2Y = R * Sin(Anglem-angle) + PivotY * height
    
    ProcedureReturn SpritePixelCollision(sprite1,sprite1X,sprite1Y,sprite2,sprite2X,sprite2Y)
EndProcedure

; LoadSprite(#logo, #PB_Compiler_Home + "examples/sources/Data/PureBasicLogo.bmp",#PB_Sprite_PixelCollision)
file$ = OpenFileRequester("Image",GetCurrentDirectory()+"\","png|*.png",0)
If file$ =""
    End
EndIf


LoadSprite(#logo, file$,#PB_Sprite_AlphaBlending|#PB_Sprite_PixelCollision)
CopySprite(#logo,#logo2,#PB_Sprite_AlphaBlending|#PB_Sprite_PixelCollision)

w = SpriteWidth(#logo)
h = SpriteHeight(#logo)
r1.d = 1 ; taille du sprite  (en %)

;Sprite de souris rouge
CreateSprite(#souris,5,5)
StartDrawing(SpriteOutput(#souris)):Box(0,0,5,5,#Red):Box(1,1,5,5,#Black):StopDrawing()
;Sprite pour tester la collision sur 1 pixel
CreateSprite(#pixel,1,1,#PB_Sprite_PixelCollision):StartDrawing(SpriteOutput(#pixel)):Box(0,0,5,5,#White):StopDrawing()

; pour afficher le centre
CreateSprite(#Centre,5,5)
StartDrawing(SpriteOutput(#Centre)):Box(0,0,5,5,#Red):StopDrawing()

; pour afficher les informations
CreateSprite(#Txt,200,40)

If StartDrawing(SpriteOutput(#Txt))
    Box(0,0,OutputWidth(),OutputHeight(),RGBA(100,100,100,255))       
    StopDrawing()
EndIf

angle = 60
x1 = 300
y1 = 250

Repeat
    
    
    
    Repeat      
        event = WaitWindowEvent(1)
    Until event = 0 Or event = #PB_Event_CloseWindow
    
    
    X=WindowMouseX(0):y=WindowMouseY(0)
    
    
    If ExamineKeyboard()        
        If KeyboardPushed(#PB_Key_Up):angle+10:EndIf
        If KeyboardPushed(#PB_Key_Down):angle-10:EndIf
    EndIf
    
    ClearScreen(RGB(50,50,50))
    
    
    SpriteTransformation(#logo, -(w*r1)/2, -(h*r1-10), w*r1, h*r1, Angle)
    DisplayTransparentSprite(#logo,x1,y1)
    
    RotateSprite(#logo2,angle,#PB_Absolute)
    DisplayTransparentSprite(#logo2,x1,y1,50)
    
    DisplayTransparentSprite(#souris,X,Y)
    
    DisplayTransparentSprite(#centre,X1,Y1)
    
    If TestCollision(#logo,x1,y1,#pixel,X,Y,x-(w*r1)/2,y1+(h*r1-10),angle,r1,r1) 
        txt$ = "logo détecté !"  
    Else
        txt$ = "rien"
    EndIf 
    
    If TestCollision(#logo2,x1,y1,#pixel,X,Y,x1+w/2,y1+h/2,angle)       
        txt$ + "logo2 détecté !"
    EndIf
    
    
    If StartDrawing(SpriteOutput(#txt))
        Box(0,0,OutputWidth(),OutputHeight(),RGB(0,0,0))
        DrawText(0,0,txt$)      
        StopDrawing()
    EndIf
    
    DisplaySprite(#txt,0,0)
    
    FlipBuffers()
    
    
Until KeyboardReleased(#PB_Key_Escape) Or event = #PB_Event_CloseWindow
J'ai testé avec ce sprite (mon image pour les bones de mon application) :
Image