[REGLE] Sprite3D & Rotation

Programmation avancée de jeux en PureBasic
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

J'en connais un qui va dire mais quel emmerdeur !!!!!
Suis vraiment désolé de tembeter !

Code : Tout sélectionner

Structure vertex
    sx.f
    sy.f
    sz.f
    rhw.f
    Color.l
    specular.l
    tu.f
    tv.f
EndStructure

Structure PB_Sprite3D
     Texture.l         
     Vertice.vertex[4]
     Width.w
     Height.w
EndStructure

Structure PB_Sprite3DEX
      No.l
      AA.f:AB.f:AC.f:AD.f
      DA.f:DB.f:DC.f:dd.f
      Pivot_x.f
      Pivot_y.f
EndStructure





Procedure Distance(x1,y1,x2,y2)
Protected Result.f
Result = Sqr(  Pow(x1-x2,2) + Pow(y1-y2,2) + Pow(z1-z2,2) )
ProcedureReturn Result
EndProcedure


Procedure.f ReturnAngle(x1.f,y1.f,x2.f,y2.f)
  A.f = x1-x2
  b.f = y1-y2
  c.f = -Sqr(A*A+b*b)
  angle.f = ACos(A/c)*180/#PI
  If y1 < y2 : angle=360-angle : EndIf
  ProcedureReturn Abs(angle - 360)
EndProcedure


Procedure Sprite3DModifyPivot(*SpriteID.PB_Sprite3DEX,X.f,Y.f)
Protected *VertexSprite.PB_Sprite3D = IsSprite3D(*SpriteID\No)

*SpriteID\AA = ReturnAngle(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,X,Y)
*SpriteID\AB = ReturnAngle(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,X,Y)
*SpriteID\AC = ReturnAngle(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,X,Y)
*SpriteID\AD = ReturnAngle(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,X,Y)

*SpriteID\DA = Distance(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,X,Y)
*SpriteID\DB = Distance(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,X,Y)
*SpriteID\DC = Distance(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,X,Y)
*SpriteID\dd = Distance(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,X,Y)

*SpriteID\Pivot_x=X
*SpriteID\Pivot_y=Y
EndProcedure

Procedure CreateSprite3DEX(Sprite3D)
Protected *VertexSprite.PB_Sprite3D = IsSprite3D(Sprite3D)
Protected *VertexSpriteEX.PB_Sprite3DEX = AllocateMemory(SizeOf(PB_Sprite3DEX))

*VertexSpriteEX\No = Sprite3D



SizeW.f = *VertexSprite\Width/2
SizeH.f = *VertexSprite\Height/2

               
*VertexSpriteEX\AA = ReturnAngle(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,SizeW,SizeH)
*VertexSpriteEX\AB = ReturnAngle(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,SizeW,SizeH)
*VertexSpriteEX\AC = ReturnAngle(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,SizeW,SizeH)
*VertexSpriteEX\AD = ReturnAngle(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,SizeW,SizeH)

*VertexSpriteEX\DA = Distance(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,SizeW,SizeH)
*VertexSpriteEX\DB = Distance(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,SizeW,SizeH)
*VertexSpriteEX\DC = Distance(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,SizeW,SizeH)
*VertexSpriteEX\dd = Distance(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,SizeW,SizeH)

ProcedureReturn *VertexSpriteEX
EndProcedure


Procedure RotateSprite3DEX(*SpriteID.PB_Sprite3DEX,angle.f)
Protected *VertexSprite.PB_Sprite3D = IsSprite3D(*SpriteID\No)
Protected SizeW2.l,SizeH2.l
     *VertexSprite\Vertice[0]\sx = *SpriteID\Pivot_x  - *SpriteID\DA  * Cos((angle+*SpriteID\AA)*#PI/180)
     *VertexSprite\Vertice[0]\sy = *SpriteID\Pivot_y  - *SpriteID\DA  * Sin((angle+*SpriteID\AA)*#PI/180)
                                                                       
     *VertexSprite\Vertice[1]\sx = *SpriteID\Pivot_x  - *SpriteID\DB  * Cos((angle+*SpriteID\AB)*#PI/180)
     *VertexSprite\Vertice[1]\sy = *SpriteID\Pivot_y  - *SpriteID\DB  * Sin((angle+*SpriteID\AB)*#PI/180)
                           ; ;                                         
     *VertexSprite\Vertice[3]\sx = *SpriteID\Pivot_x  - *SpriteID\dd  * Cos((angle+*SpriteID\AD)*#PI/180)
     *VertexSprite\Vertice[3]\sy = *SpriteID\Pivot_y  - *SpriteID\dd  * Sin((angle+*SpriteID\AD)*#PI/180)
                                                                       
     *VertexSprite\Vertice[2]\sx = *SpriteID\Pivot_x  - *SpriteID\DC  * Cos((angle+*SpriteID\AC)*#PI/180)     
     *VertexSprite\Vertice[2]\sy = *SpriteID\Pivot_y  - *SpriteID\DC  * Sin((angle+*SpriteID\AC)*#PI/180)
                                                                     
EndProcedure



InitSprite() : InitSprite3D() : InitKeyboard()
If OpenWindow(0, 0, 0, 800, 600, "Un écran dans une fenêtre...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    If OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 0, 0, 0)
    Else
      MessageRequester("Erreur", "Impossible d'ouvrir un écran dans la fenêtre!", 0)
      End
    EndIf
  EndIf

;{ A
CreateSprite(0,128,64,#PB_Sprite_Texture)
 StartDrawing(SpriteOutput(0))
  Box(0,0,64,64,RGB(255,0,0))
  Box(64,0,64,64,RGB(255,255,0))
  Box(0,0,10,10, $FF0000)
  StopDrawing()
CreateSprite3D(0,0)
A = CreateSprite3DEX(0)
;}
;{ B
CreateSprite(1,128,64,#PB_Sprite_Texture)
 StartDrawing(SpriteOutput(1))
  Box(0,0,64,64,RGB(255,0,0))
  Box(64,0,64,64,RGB(255,255,0))
  Box(0,54,10,10, $FF0000)
  StopDrawing()
CreateSprite3D(1,1)
b = CreateSprite3DEX(1)
;}
;{ C
CreateSprite(2,128,64,#PB_Sprite_Texture)
 StartDrawing(SpriteOutput(2))
  Box(0,0,64,64,RGB(255,0,0))
  Box(64,0,64,64,RGB(255,255,0))
  Box(118,54,10,10, $FF0000)
  StopDrawing()
CreateSprite3D(2,2)
c = CreateSprite3DEX(2)
;}
;{ D
CreateSprite(3,128,64,#PB_Sprite_Texture)
 StartDrawing(SpriteOutput(3))
  Box(0,0,64,64,RGB(255,0,0))
  Box(64,0,64,64,RGB(255,255,0))
  Box(118,0,10,10, $FF0000)
  StopDrawing()
CreateSprite3D(3,3)
d = CreateSprite3DEX(3)
;}
e = CreateSprite3DEX(0)
f = CreateSprite3DEX(0)



Sprite3DModifyPivot(e,0,32)
Sprite3DModifyPivot(f,64,0)


Repeat
  r.f = 90 + 45 * Cos(ElapsedMilliseconds()/500)
  ExamineKeyboard()
  ClearScreen(0)
  Start3D()
    RotateSprite3DEX(A,0)
    DisplaySprite3D(0,100,100)
    
    RotateSprite3DEX(b,90)
    DisplaySprite3D(1,300,100)
    
    RotateSprite3DEX(c,180)
    DisplaySprite3D(2,100,300)
    
    RotateSprite3DEX(d,270)
    DisplaySprite3D(3,300,300)
    
    RotateSprite3DEX(e,r)
    DisplaySprite3D(0,500,200)
    
    
    RotateSprite3DEX(f,-r)
    DisplaySprite3D(0,500,400)
  Stop3D()

  StartDrawing(ScreenOutput())
    DrawText(100,100,"0 DEG")
    DrawText(300,100,"90 DEG")
    DrawText(100,300,"180 DEG")
    DrawText(300,300,"270 DEG")
    Circle(500,232,4,RGB(0,0,255))
    Circle(564,400,4,RGB(0,0,255))
    Box(100,100,10,10, $00FF00)
    Box(300,100,10,10, $00FF00)
    Box(100,300,10,10, $00FF00)
    Box(300,300,10,10, $00FF00)
  StopDrawing()
 FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) 
Donc normalement il faudrait que les petits carrés bleus soit sur ou sous les carrés verts ! et je viens de réussir :

Code : Tout sélectionner

Structure vertex
    sx.f
    sy.f
    sz.f
    rhw.f
    Color.l
    specular.l
    tu.f
    tv.f
EndStructure

Structure PB_Sprite3D
     Texture.l         
     Vertice.vertex[4]
     Width.w
     Height.w
EndStructure

Structure PB_Sprite3DEX
      No.l
      AA.f:AB.f:AC.f:AD.f
      DA.f:DB.f:DC.f:dd.f
      Pivot_x.f
      Pivot_y.f
EndStructure





Procedure Distance(x1,y1,x2,y2)
Protected Result.f
Result = Sqr(  Pow(x1-x2,2) + Pow(y1-y2,2) + Pow(z1-z2,2) )
ProcedureReturn Result
EndProcedure


Procedure.f ReturnAngle(x1.f,y1.f,x2.f,y2.f)
  A.f = x1-x2
  b.f = y1-y2
  c.f = -Sqr(A*A+b*b)
  angle.f = ACos(A/c)*180/#PI
  If y1 < y2 : angle=360-angle : EndIf
  ProcedureReturn Abs(angle - 360)
EndProcedure


Procedure Sprite3DModifyPivot(*SpriteID.PB_Sprite3DEX,X.f,Y.f)
Protected *VertexSprite.PB_Sprite3D = IsSprite3D(*SpriteID\No)

*SpriteID\AA = ReturnAngle(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,X,Y)
*SpriteID\AB = ReturnAngle(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,X,Y)
*SpriteID\AC = ReturnAngle(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,X,Y)
*SpriteID\AD = ReturnAngle(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,X,Y)

*SpriteID\DA = Distance(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,X,Y)
*SpriteID\DB = Distance(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,X,Y)
*SpriteID\DC = Distance(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,X,Y)
*SpriteID\dd = Distance(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,X,Y)

*SpriteID\Pivot_x=X
*SpriteID\Pivot_y=Y
EndProcedure

Procedure CreateSprite3DEX(Sprite3D)
Protected *VertexSprite.PB_Sprite3D = IsSprite3D(Sprite3D)
Protected *VertexSpriteEX.PB_Sprite3DEX = AllocateMemory(SizeOf(PB_Sprite3DEX))

*VertexSpriteEX\No = Sprite3D



SizeW.f = *VertexSprite\Width/2
SizeH.f = *VertexSprite\Height/2

               
*VertexSpriteEX\AA = ReturnAngle(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,SizeW,SizeH)
*VertexSpriteEX\AB = ReturnAngle(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,SizeW,SizeH)
*VertexSpriteEX\AC = ReturnAngle(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,SizeW,SizeH)
*VertexSpriteEX\AD = ReturnAngle(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,SizeW,SizeH)

*VertexSpriteEX\DA = Distance(*VertexSprite\Vertice[0]\sx,*VertexSprite\Vertice[0]\sy,SizeW,SizeH)
*VertexSpriteEX\DB = Distance(*VertexSprite\Vertice[1]\sx,*VertexSprite\Vertice[1]\sy,SizeW,SizeH)
*VertexSpriteEX\DC = Distance(*VertexSprite\Vertice[2]\sx,*VertexSprite\Vertice[2]\sy,SizeW,SizeH)
*VertexSpriteEX\dd = Distance(*VertexSprite\Vertice[3]\sx,*VertexSprite\Vertice[3]\sy,SizeW,SizeH)

ProcedureReturn *VertexSpriteEX
EndProcedure


Procedure RotateSprite3DEX(*SpriteID.PB_Sprite3DEX,angle.f)
Protected *VertexSprite.PB_Sprite3D = IsSprite3D(*SpriteID\No)
Protected SizeW2.l,SizeH2.l
    If angle = 0 Or angle = 180
      *SpriteID\Pivot_x = *VertexSprite\Width/2
      *SpriteID\Pivot_y = *VertexSprite\Height/2
    Else
      *SpriteID\Pivot_x = *VertexSprite\Height/2
      *SpriteID\Pivot_y = *VertexSprite\Width/2
    EndIf
     *VertexSprite\Vertice[0]\sx = *SpriteID\Pivot_x  - *SpriteID\DA  * Cos((angle+*SpriteID\AA)*#PI/180)
     *VertexSprite\Vertice[0]\sy = *SpriteID\Pivot_y  - *SpriteID\DA  * Sin((angle+*SpriteID\AA)*#PI/180)
                                                                       
     *VertexSprite\Vertice[1]\sx = *SpriteID\Pivot_x  - *SpriteID\DB  * Cos((angle+*SpriteID\AB)*#PI/180)
     *VertexSprite\Vertice[1]\sy = *SpriteID\Pivot_y  - *SpriteID\DB  * Sin((angle+*SpriteID\AB)*#PI/180)
                           ; ;                                         
     *VertexSprite\Vertice[3]\sx = *SpriteID\Pivot_x  - *SpriteID\dd  * Cos((angle+*SpriteID\AD)*#PI/180)
     *VertexSprite\Vertice[3]\sy = *SpriteID\Pivot_y  - *SpriteID\dd  * Sin((angle+*SpriteID\AD)*#PI/180)
                                                                       
     *VertexSprite\Vertice[2]\sx = *SpriteID\Pivot_x  - *SpriteID\DC  * Cos((angle+*SpriteID\AC)*#PI/180)     
     *VertexSprite\Vertice[2]\sy = *SpriteID\Pivot_y  - *SpriteID\DC  * Sin((angle+*SpriteID\AC)*#PI/180)
                                                                     
EndProcedure



InitSprite() : InitSprite3D() : InitKeyboard()
If OpenWindow(0, 0, 0, 800, 600, "Un écran dans une fenêtre...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    If OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 0, 0, 0)
    Else
      MessageRequester("Erreur", "Impossible d'ouvrir un écran dans la fenêtre!", 0)
      End
    EndIf
  EndIf

;{ A
CreateSprite(0,128,64,#PB_Sprite_Texture)
 StartDrawing(SpriteOutput(0))
  Box(0,0,64,64,RGB(255,0,0))
  Box(64,0,64,64,RGB(255,255,0))
  Box(0,0,10,10, $FF0000)
  StopDrawing()
CreateSprite3D(0,0)
A = CreateSprite3DEX(0)
;}
;{ B
CreateSprite(1,128,64,#PB_Sprite_Texture)
 StartDrawing(SpriteOutput(1))
  Box(0,0,64,64,RGB(255,0,0))
  Box(64,0,64,64,RGB(255,255,0))
  Box(0,54,10,10, $FF0000)
  StopDrawing()
CreateSprite3D(1,1)
b = CreateSprite3DEX(1)
;}
;{ C
CreateSprite(2,128,64,#PB_Sprite_Texture)
 StartDrawing(SpriteOutput(2))
  Box(0,0,64,64,RGB(255,0,0))
  Box(64,0,64,64,RGB(255,255,0))
  Box(118,54,10,10, $FF0000)
  StopDrawing()
CreateSprite3D(2,2)
c = CreateSprite3DEX(2)
;}
;{ D
CreateSprite(3,128,64,#PB_Sprite_Texture)
 StartDrawing(SpriteOutput(3))
  Box(0,0,64,64,RGB(255,0,0))
  Box(64,0,64,64,RGB(255,255,0))
  Box(118,0,10,10, $FF0000)
  StopDrawing()
CreateSprite3D(3,3)
d = CreateSprite3DEX(3)
;}
e = CreateSprite3DEX(0)
f = CreateSprite3DEX(0)



Sprite3DModifyPivot(e,0,32)
Sprite3DModifyPivot(f,64,0)


Repeat
  r.f = 90 + 45 * Cos(ElapsedMilliseconds()/500)
  ExamineKeyboard()
  ClearScreen(0)
  Start3D()
    RotateSprite3DEX(A,0)
    DisplaySprite3D(0,100,100)
    
    RotateSprite3DEX(b,90)
    DisplaySprite3D(1,300,100)
    
    RotateSprite3DEX(c,180)
    DisplaySprite3D(2,100,300)
    
    RotateSprite3DEX(d,270)
    DisplaySprite3D(3,300,300)
    
    RotateSprite3DEX(e,r)
    DisplaySprite3D(0,500,200)
    
    
    RotateSprite3DEX(f,-r)
    DisplaySprite3D(0,500,400)
  Stop3D()

  StartDrawing(ScreenOutput())
    DrawText(100,100,"0 DEG")
    DrawText(300,100,"90 DEG")
    DrawText(100,300,"180 DEG")
    DrawText(300,300,"270 DEG")
    Circle(500,232,4,RGB(0,0,255))
    Circle(564,400,4,RGB(0,0,255))
    Box(100,100,10,10, $00FF00)
    Box(300,100,10,10, $00FF00)
    Box(100,300,10,10, $00FF00)
    Box(300,300,10,10, $00FF00)
  StopDrawing()
 FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) 
Merci CplBator de ton aide immense :) :) :) :) :) :) :)

Si je peux te rendre la pareil, hésite pas :)
Répondre