Page 1 sur 1

(résolu)sprite orienté: rejoindre un point A à un point B

Publié : dim. 08/févr./2009 22:11
par beauregard
Bonsoir
l'objectif de ce soir est de rejoindre un point A( départ: X=512 Y=128, d'un disque rouge menaçant) à un point B( une innocente raquette). Et oui, j'ai un peu honte de faire une telle demande :oops:
Et voici le joyeux code, avec listes chainées, où j'ai essayé de débrousailler le terrain: la raquette peut être déplacé avec les touche fléchés gauche ou droite.
Pour les disques rouge, ils descendent simplement, car ils ne sont pas orientés correctement en direction de la raquette lors de leur création:

Code : Tout sélectionner

; sprite d'un point A à un point B 

If InitMouse ()=0 Or InitKeyboard ()=0 Or InitSprite ()=0  Or InitSprite3D ()=0 
     MessageRequester ( "Error" , "Can't open DirectX 7 or later" , 0)
     End
EndIf
If InitSound()=0 Or InitMovie()=0
  MessageRequester("Error", "Can't open DirectX 7 Or Sound Card is not present", 0)
  End
EndIf

UsePNGImageDecoder()

; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°

Enumeration ; ici, on donne un petit nom à nos sprites( non, chuis pas un numéro !):

#raquette
#vilaintir
       
EndEnumeration

If OpenWindow ( 0 , 0, 0, 1024, 768, "tir orienté" , #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar| #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_ScreenCentered ) 
 OpenWindowedScreen ( WindowID ( 0 ), 0, 0, 1024, 768, 0, 1, 1) ; un ecran graphique dans la fenêtre.

  SetWindowColor(0, RGB (236,216,234))  
EndIf
KeyboardMode(#PB_Keyboard_International)

 CreateSprite ( #raquette , 64, 16, 0 ) 
 StartDrawing ( SpriteOutput ( #raquette )) ; image pour la raquette
  BackColor ( RGB (0,0,0))
  Box (0,0, 64, 16, RGB (255, 255, 255))
 StopDrawing ()
 
 CreateSprite ( #vilaintir , 32, 32, 0 ) 
 StartDrawing ( SpriteOutput ( #vilaintir )) ; image pour le tir
  BackColor ( RGB (0,0,0))
  Circle(16, 16, 16 , RGB (255, 0, 0)) 
 StopDrawing () 
 
Structure objet

objetetat.b
objetx.l 
objety.f 
objetdirY.l 
objetdirX.l 



Tempo1.w
Tempo2.w

EndStructure
Global NewList trait.objet() ; -> #raquette 
Global NewList tir.objet() ; -> #vilaintir  


Global etape.b, tempoA.w=100

; ******************************************************************************************************
Repeat ; Boucle principale
; ******************************************************************************************************
 Event= WindowEvent ()
 Start3D() ; on place cette commande dès le début de la boucle principale.

 ExamineMouse()
 ExamineKeyboard ()
 
 
If etape=0

  ;- fabrication de la raquette
  LastElement(trait())
  AddElement(trait())
  trait()\objetetat=1
  trait()\objetx=512
  trait()\objety=640 
  
  
  
  etape=1
EndIf

If etape=1 
  
  ForEach trait()
    If trait()\objetetat=1;- raquette
      
      

      DisplayTransparentSprite ( #raquette , trait()\objetx, trait()\objety)
      
      If KeyboardPushed ( #PB_Key_Right ):trait()\objetx+5:EndIf ; droite.	
      If KeyboardPushed ( #PB_Key_Left ):trait()\objetx-5:EndIf ; gauche.     
      
      
      
      
      
    EndIf     
  Next  



;-  
  tempoA+1
  If tempoA>150:tempoA=0 ;- fabrication tir
    
    LastElement(tir())
    AddElement(tir())
    tir()\objetetat=1
    tir()\objetx=512
    tir()\objety=128   
    
    ;- là, il faut placer la formule mathématique qui manque:
    ; tir()\objetdirY= 
    ; tir()\objetdirX= 
    
  EndIf
  
  ForEach tir()
    If tir()\objetetat=1;- tir
      
      

      DisplayTransparentSprite ( #vilaintir , tir()\objetx, tir()\objety)
      
   
      tir()\objety+1
      
      
      
      
    EndIf     
  Next   
   
EndIf 
 
 
 
 
 
 
  Stop3D(); on place cette commande à la fin de la boucle principale.
 FlipBuffers()
 ClearScreen(RGB(0, 42, 255)) 
; ******************************************************************************************************   
 If Event= #PB_Event_CloseWindow Or KeyboardPushed ( #PB_Key_Escape ):End:EndIf; si clique coin haut droit ou touche Esc, alors ferme fenêtre.
ForEver








Publié : dim. 08/févr./2009 22:27
par Anonyme
une voie :D

Code : Tout sélectionner

; Cpl.Bator
; PureBasic 4.10

#SW=800
#SH=600

InitSprite() : InitKeyboard() : InitMouse()
OpenScreen(#SW,#SH,32,"")

  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
   Structure point
   x.f
   y.f
   EndStructure
  CompilerEndIf


;-Structures
Structure VECTOR2
  x.f
  y.f
EndStructure

Structure ENTITY
  Position.VECTOR2
  Angle.f
EndStructure


;-Declarations des fonctions
Declare DrawArrow(Lenght.l , x.f , y.f , Angle.f)
Declare.f curveangle(newangle.f,oldangle.f,increments.f)
Declare.f ReturnDegAngle(x1.f,y1.f,x2.f,y2.f)
Declare track_SmoothPoint(*A.ENTITY,*B.ENTITY, turnspeed.f=1.0)



; ************************************************************************************
#NB_ARROW = 300
#ARROW_SPEED_MOTION     = 0.1
#ARROW_SPEED_ROTATION = 100


Dim Arrow.ENTITY(#NB_ARROW)

For i = 1 To #NB_ARROW
  Arrow(i)\Position\x = Random(#SW)
  Arrow(i)\Position\y = Random(#SH)
  Arrow(i)\Angle      = 0
Next
; ************************************************************************************


; Cible des "arrow" , coordonées de la souris pour la position
Target.ENTITY




Repeat
ClearScreen(0)
ExamineKeyboard()
ExamineMouse()


Target\Position\x = MouseX()
Target\Position\y = MouseY()

            StartDrawing(ScreenOutput())
                Circle(Target\Position\x,Target\Position\y,2,255)
            StopDrawing()


                For i = 1 To #NB_ARROW
                    DrawArrow(50 , Arrow(i)\Position\x , Arrow(i)\Position\y , Arrow(i)\Angle)
                    track_SmoothPoint(Arrow(i),Target,#ARROW_SPEED_ROTATION)
                   
                    Arrow(i)\Position\x + #ARROW_SPEED_MOTION *Cos(Arrow(i)\Angle*#PI/180)
                    Arrow(i)\Position\y + #ARROW_SPEED_MOTION *Sin(Arrow(i)\Angle*#PI/180)
                Next



If KeyboardPushed(#PB_Key_Escape)<>#Null : Quit=1 : EndIf
FlipBuffers(60)
Until Quit=1
End




Procedure.f curveangle(newangle.f,oldangle.f,increments.f)
  If increments>1
    If (oldangle+360)-newangle<newangle-oldangle
      oldangle=360+oldangle
    EndIf
    If (newangle+360)-oldangle<oldangle-newangle
      newangle=360+newangle
    EndIf
    oldangle=oldangle-(oldangle-newangle)/increments
  EndIf
 
  If increments<=1
    ProcedureReturn newangle
  EndIf
  ProcedureReturn oldangle
EndProcedure


Procedure.f ReturnDegAngle(x1.f,y1.f,x2.f,y2.f) ; DEGREE
  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 track_SmoothPoint(*A.ENTITY,*B.ENTITY, turnspeed.f=1.0)
    AngDif = ReturnDegAngle(*A\position\x,*A\position\y,*B\position\x,*B\position\y)
    temp_yaw.f = curveangle(AngDif,*A\Angle,turnspeed)
    *A\Angle = temp_yaw
EndProcedure



Procedure DrawArrow(Lenght.l , x.f , y.f , Angle.f)

          Protected ArrowA.Point,ArrowB.Point
          Protected ArrowBranchA.Point,ArrowBranchB.Point
         
         
         
          ArrowA\x = x + (Lenght/2) * Cos(Angle*#PI/180)
          ArrowA\y = y + (Lenght/2) * Sin(Angle*#PI/180)
         
          ArrowB\x = x - (Lenght/2) * Cos(Angle*#PI/180)
          ArrowB\y = y - (Lenght/2) * Sin(Angle*#PI/180)
         
         
          ArrowBranchA\x = ArrowA\x - (Lenght/3) * Cos((Angle+45)*#PI/180)
          ArrowBranchA\y = ArrowA\y - (Lenght/3) * Sin((Angle+45)*#PI/180)
         
          ArrowBranchB\x = ArrowA\x - (Lenght/3) * Cos((Angle-45)*#PI/180)
          ArrowBranchB\y = ArrowA\y - (Lenght/3) * Sin((Angle-45)*#PI/180)
         
         
            StartDrawing(ScreenOutput())
                LineXY(ArrowA\x,ArrowA\y,ArrowB\x,ArrowB\y,255)
                LineXY(ArrowA\x,ArrowA\y,ArrowBranchA\x,ArrowBranchA\y,255)
                LineXY(ArrowA\x,ArrowA\y,ArrowBranchB\x,ArrowBranchB\y,255)
                Circle(x+1,y+1,2,255)
            StopDrawing()
EndProcedure

Publié : dim. 08/févr./2009 23:41
par beauregard
c'est très impressionnant ! :) Seulement, je souhaite que l'objet( #vilaintir ) soit correctement orienté dès sa création, heu..., bien sûr, ton code fait cela, qui peut le plus peut le moins. Mais il est un peu complexe quand même...

Code : Tout sélectionner

FlipBuffers(60)
60, c'est rigolo, çà me rappelle mes débuts...

et la bibliothèque de sprite n'est toujours pas compatible linux, n'est ce pas ?

Publié : dim. 08/févr./2009 23:45
par Anonyme

Code : Tout sélectionner

Declare.f ReturnDegAngle(x1.f,y1.f,x2.f,y2.f) 
Ca devrais le faire non ? 8O



@++ :lol:

Publié : lun. 09/févr./2009 0:43
par beauregard
Cpl.Bator a écrit :

Code : Tout sélectionner

Declare.f ReturnDegAngle(x1.f,y1.f,x2.f,y2.f) 
Ca devrais le faire non ? 8O
heu, oui, mais c'est pas évident, bon là çà réagit, et c'est presque çà, mais pas tout à fait çà:
( appuis sur touche X pour fabriquer les disques rouges)

Code : Tout sélectionner

; sprite d'un point A à un point B 

If InitMouse ()=0 Or InitKeyboard ()=0 Or InitSprite ()=0  Or InitSprite3D ()=0 
     MessageRequester ( "Error" , "Can't open DirectX 7 or later" , 0)
     End
EndIf
If InitSound()=0 Or InitMovie()=0
  MessageRequester("Error", "Can't open DirectX 7 Or Sound Card is not present", 0)
  End
EndIf

UsePNGImageDecoder()

; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;LoadFont ( 0 , "Comic Sans Ms" ,16, #PB_Font_Bold)
;LoadFont ( 1 , "Comic Sans Ms" ,30, #PB_Font_Bold)
Enumeration ; ici, on donne un petit nom à nos sprites( non, chuis pas un numéro !):

#raquette
#vilaintir
       
EndEnumeration

If OpenWindow ( 0 , 0, 0, 1024, 768, "tir orienté" , #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar| #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_ScreenCentered ) 
 OpenWindowedScreen ( WindowID ( 0 ), 0, 0, 1024, 768, 0, 1, 1) ; un ecran graphique dans la fenêtre.

  SetWindowColor(0, RGB (236,216,234))  
EndIf
KeyboardMode(#PB_Keyboard_International)

 CreateSprite ( #raquette , 64, 16, 0 ) 
 StartDrawing ( SpriteOutput ( #raquette )) ; image pour la raquette
  BackColor ( RGB (0,0,0))
  Box (0,0, 64, 16, RGB (255, 255, 255))
 StopDrawing ()
 
 CreateSprite ( #vilaintir , 32, 32, 0 ) 
 StartDrawing ( SpriteOutput ( #vilaintir )) ; image pour le tir
  BackColor ( RGB (0,0,0))
  Circle(16, 16, 16 , RGB (255, 0, 0)) 
 StopDrawing () 
 
Structure objet ;- clone1

objetetat.b
objetx.l 
objety.f 
objetdirY.l 
objetdirX.l 

a.f
b.f
c.f
objetangle.f


Tempo1.w
Tempo2.w

EndStructure
Global NewList trait.objet() ; -> #raquette 
Global NewList tir.objet() ; -> #vilaintir  


Global etape.b, tempoA.b, nbrtir.w

; ******************************************************************************************************
Repeat ; Boucle principale
; ******************************************************************************************************
 Event= WindowEvent ()
 Start3D() ; on place cette commande dès le début de la boucle principale.

 ExamineMouse()
 ExamineKeyboard ()
 
 
If etape=0

  ;- fabrication de la raquette
  LastElement(trait())
  AddElement(trait())
  trait()\objetetat=1
  trait()\objetx=512
  trait()\objety=640 
  
  
  
  etape=1
EndIf

If etape=1 
  
  ForEach trait()
    If trait()\objetetat=1;- raquette
      
      

      DisplayTransparentSprite ( #raquette , trait()\objetx, trait()\objety)
      
      If KeyboardPushed ( #PB_Key_Right ):trait()\objetx+5:EndIf ; droite.	
      If KeyboardPushed ( #PB_Key_Left ):trait()\objetx-5:EndIf ; gauche.     
      
      ;- objet cible
      Xtarget.f=trait()\objetx ;- équivalent de x1
      Ytarget.f=trait()\objety ;- équivalent de y1
      
    EndIf     
  Next  



;-  
;  tempoA+1
  If KeyboardPushed(#PB_Key_X)=0 And tempoA=2:tempoA=0:EndIf
  If KeyboardPushed(#PB_Key_X) And tempoA=0:tempoA=1:EndIf
  If tempoA=1:tempoA=2 ;- fabrication tir
    
    LastElement(tir())
    AddElement(tir())
    tir()\objetetat=1
    tir()\objetx=512 ; équivalent de x2
    tir()\objety=128 ; équivalent de y2   
    
    ;- là, il faut placer la formule mathématique qui manque:
    ; tir()\objetdirY= 
    ; tir()\objetdirX= 

;  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)

;- travail de convertion:    
  tir()\a = Xtarget-tir()\objetx ; x1-x2
  tir()\b = Ytarget-tir()\objety ; y1-y2
  tir()\c = -Sqr(tir()\a*tir()\a+tir()\b*tir()\b)
  tir()\objetangle = ACos(tir()\a/tir()\c)*180/#PI    
    
;  ArrowA\x = x + (Lenght/2) * Cos(Angle*#PI/180)
;  ArrowA\y = y + (Lenght/2) * Sin(Angle*#PI/180)  

    ;tir()\objetx=tir()\objetx + (tir()\objetx/2) * Cos(tir()\objetangle*#PI/180)
    ;tir()\objety=tir()\objety + (tir()\objety/2) * Sin(tir()\objetangle*#PI/180)

    
    
        
  EndIf



nbrtir=0  
  ForEach tir()
    If tir()\objetetat=1;- tir
nbrtir+1      
      

      DisplayTransparentSprite ( #vilaintir , tir()\objetx, tir()\objety)
      
   
;- bizarre 
  ;If y1 < y2 : Angle=360-Angle : EndIf
  ;If tir()\objety < Ytarget : tir()\objetangle=360-tir()\objetangle : EndIf 
        
      tir()\objetx=tir()\objetx + (tir()\objetx/32) * Cos(tir()\objetangle*#PI/180)
      tir()\objety=tir()\objety + (tir()\objety/32) * Sin(tir()\objetangle*#PI/180)     



      
      If tir()\objety>700
        DeleteElement(tir()) 
        Continue
      EndIf
      
    EndIf     
  Next   
   
EndIf 
 
 
  StartDrawing ( ScreenOutput ())
    DrawingMode (1)
      ;DrawingFont ( FontID (0)) 
      FrontColor ( RGB (255,255,255))

      FrontColor ( RGB (154,154,154)) :DrawText (350+1,20+1, "push X")
      FrontColor ( RGB (234,234,234)) :DrawText (350,20, "push X")
 
      nbrtir$= Str (nbrtir) 
      FrontColor ( RGB (164,21,21)) :DrawText (42+1, 4+1, "  " +nbrtir$)
      FrontColor ( RGB (253,201,255)) :DrawText (42, 4, "  " +nbrtir$) 
 
  StopDrawing () 
 
 
 
  Stop3D(); on place cette commande à la fin de la boucle principale.
 FlipBuffers()
 ClearScreen(RGB(0, 42, 255)) 
; ******************************************************************************************************   
 If Event= #PB_Event_CloseWindow Or KeyboardPushed ( #PB_Key_Escape ):End:EndIf; si clique coin haut droit ou touche Esc, alors ferme fenêtre.
ForEver








Publié : lun. 09/févr./2009 11:13
par Anonyme
La position X de tes tirs n'était pas un float d'ou un bug avec les angles :

Code : Tout sélectionner

; sprite d'un point A à un point B

If InitMouse ()=0 Or InitKeyboard ()=0 Or InitSprite ()=0  Or InitSprite3D ()=0
     MessageRequester ( "Error" , "Can't open DirectX 7 or later" , 0)
     End
EndIf
If InitSound()=0 Or InitMovie()=0
  MessageRequester("Error", "Can't open DirectX 7 Or Sound Card is not present", 0)
  End
EndIf

UsePNGImageDecoder()


Procedure.f ReturnDegAngle(x1.f,y1.f,x2.f,y2.f) ; DEGREE
  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 




; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;LoadFont ( 0 , "Comic Sans Ms" ,16, #PB_Font_Bold)
;LoadFont ( 1 , "Comic Sans Ms" ,30, #PB_Font_Bold)
Enumeration ; ici, on donne un petit nom à nos sprites( non, chuis pas un numéro !):

#raquette
#vilaintir
       
EndEnumeration

If OpenWindow ( 0 , 0, 0, 1024, 768, "tir orienté" , #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar| #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_ScreenCentered )
 OpenWindowedScreen ( WindowID ( 0 ), 0, 0, 1024, 768, 0, 1, 1) ; un ecran graphique dans la fenêtre.

  SetWindowColor(0, RGB (236,216,234)) 
EndIf
KeyboardMode(#PB_Keyboard_International)

 CreateSprite ( #raquette , 64, 16, 0 )
 StartDrawing ( SpriteOutput ( #raquette )) ; image pour la raquette
  BackColor ( RGB (0,0,0))
  Box (0,0, 64, 16, RGB (255, 255, 255))
 StopDrawing ()
 
 CreateSprite ( #vilaintir , 32, 32, 0 )
 StartDrawing ( SpriteOutput ( #vilaintir )) ; image pour le tir
  BackColor ( RGB (0,0,0))
  Circle(16, 16, 16 , RGB (255, 0, 0))
 StopDrawing ()
 
Structure objet ;- clone1

objetetat.b
objetx.f
objety.f
objetdirY.l
objetdirX.l

a.f
b.f
c.f
objetangle.f


Tempo1.w
Tempo2.w

EndStructure
Global NewList trait.objet() ; -> #raquette
Global NewList tir.objet() ; -> #vilaintir 


Global etape.b, tempoA.b, nbrtir.w

; ******************************************************************************************************
Repeat ; Boucle principale
; ******************************************************************************************************
 Event= WindowEvent ()
 Start3D() ; on place cette commande dès le début de la boucle principale.

 ExamineMouse()
 ExamineKeyboard ()
 
 
If etape=0

  ;- fabrication de la raquette
  LastElement(trait())
  AddElement(trait())
  trait()\objetetat=1
  trait()\objetx=512
  trait()\objety=640
 
 
 
  etape=1
EndIf

If etape=1
 
  ForEach trait()
    If trait()\objetetat=1;- raquette
     
     

      DisplayTransparentSprite ( #raquette , trait()\objetx, trait()\objety)
     
      If KeyboardPushed ( #PB_Key_Right ):trait()\objetx+5:EndIf ; droite.   
      If KeyboardPushed ( #PB_Key_Left ):trait()\objetx-5:EndIf ; gauche.     
     
      ;- objet cible
      Xtarget.f=trait()\objetx ;- équivalent de x1
      Ytarget.f=trait()\objety ;- équivalent de y1
     
    EndIf     
  Next 


If ShootTimer < ElapsedMilliseconds()
ShootTimer = ElapsedMilliseconds() + 75

If tempoA=2:tempoA=0:EndIf 
If tempoA=0:tempoA=1:EndIf

EndIf 
;- 
;  tempoA+1
;   If KeyboardPushed(#PB_Key_X)=0 And tempoA=2:tempoA=0:EndIf
;   If KeyboardPushed(#PB_Key_X) And tempoA=0:tempoA=1:EndIf
  If tempoA=1:tempoA=2 ;- fabrication tir
   
    LastElement(tir())
    AddElement(tir())
    tir()\objetetat=1
    tir()\objetx=512 ; équivalent de x2
    tir()\objety=128 ; équivalent de y2   
   
    ;- là, il faut placer la formule mathématique qui manque:
    ; tir()\objetdirY=
    ; tir()\objetdirX=

;  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)

;- travail de convertion:   

  tir()\objetangle = ReturnDegAngle(512,128, trait()\objetx, trait()\objety)
   
;  ArrowA\x = x + (Lenght/2) * Cos(Angle*#PI/180)
;  ArrowA\y = y + (Lenght/2) * Sin(Angle*#PI/180) 

    ;tir()\objetx=tir()\objetx + (tir()\objetx/2) * Cos(tir()\objetangle*#PI/180)
    ;tir()\objety=tir()\objety + (tir()\objety/2) * Sin(tir()\objetangle*#PI/180)

   
   
       
  EndIf



nbrtir=0 
  ForEach tir()
    If tir()\objetetat=1;- tir
nbrtir+1     
     

      DisplayTransparentSprite ( #vilaintir , tir()\objetx, tir()\objety)
     
   
;- bizarre
  ;If y1 < y2 : Angle=360-Angle : EndIf
  ;If tir()\objety < Ytarget : tir()\objetangle=360-tir()\objetangle : EndIf
       
      tir()\objetx=tir()\objetx + (tir()\objetx/64)  * Cos(tir()\objetangle*#PI/180)
      tir()\objety=tir()\objety + (tir()\objety/64) * Sin(tir()\objetangle*#PI/180)     



     
      If tir()\objety>700
        DeleteElement(tir())
        Continue
      EndIf
     
    EndIf     
  Next   
   
EndIf
 
 
  StartDrawing ( ScreenOutput ())
    DrawingMode (1)
      ;DrawingFont ( FontID (0))
      FrontColor ( RGB (255,255,255))

      FrontColor ( RGB (154,154,154)) :DrawText (350+1,20+1, "push X")
      FrontColor ( RGB (234,234,234)) :DrawText (350,20, "push X")
 
      nbrtir$= Str (nbrtir)
      FrontColor ( RGB (164,21,21)) :DrawText (42+1, 4+1, "  " +nbrtir$)
      FrontColor ( RGB (253,201,255)) :DrawText (42, 4, "  " +nbrtir$)
 
  StopDrawing ()
 
 
 
  Stop3D(); on place cette commande à la fin de la boucle principale.
 FlipBuffers()
 ClearScreen(RGB(0, 42, 255))
; ******************************************************************************************************   
 If Event= #PB_Event_CloseWindow Or KeyboardPushed ( #PB_Key_Escape ):End:EndIf; si clique coin haut droit ou touche Esc, alors ferme fenêtre.
ForEver

Publié : lun. 09/févr./2009 11:29
par Anonyme
Avec mon code :


@++

Code : Tout sélectionner

; Cpl.Bator
; PureBasic 4.10

#SW=1680
#SH=1050

InitSprite() : InitKeyboard() : InitMouse()
OpenScreen(#SW,#SH,32,"")

  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
   Structure point
   x.f
   y.f
   EndStructure
  CompilerEndIf


;-Structures
Structure VECTOR2
  x.f
  y.f
EndStructure

Structure ENTITY
  Position.VECTOR2
  Speed.f
  Angle.f
EndStructure


;-Declarations des fonctions
Declare.f curveangle(newangle.f,oldangle.f,increments.f)
Declare.f ReturnDegAngle(x1.f,y1.f,x2.f,y2.f)
Declare track_SmoothPoint(*A.ENTITY,*B.ENTITY, turnspeed.f=1.0)



; ************************************************************************************
#TIR_SPEED_MOTION     = 4
#TIR_SPEED_ROTATION = 12
Global NewList Tirs.ENTITY()
; ************************************************************************************


; Cible des "arrow" , coordonées de la souris pour la position
Target.ENTITY

Target\Position\x = #SW/2
Target\Position\y = #SH - 64


Repeat
ClearScreen($FFFFFF)
ExamineKeyboard()
ExamineMouse()




If KeyboardPushed(#PB_Key_Right)
  Target\Position\x + 10
EndIf 

If KeyboardPushed(#PB_Key_Left)
  Target\Position\x - 10
EndIf 




        ; On tir tout les 250 ms
              If ShootTimer < ElapsedMilliseconds()
              ShootTimer = ElapsedMilliseconds() + 250
                AddElement(Tirs())
                Tirs()\Position\x = #SW/2
                  Tirs()\Position\y = 100
                Tirs()\Angle = -Random(180)
                Tirs()\Speed = #TIR_SPEED_MOTION * 4
              EndIf 





            StartDrawing(ScreenOutput())
                Box(Target\Position\x -64,Target\Position\y,128,16,$000000)
       
                 ForEach Tirs()
                 
                 
                    Circle(Tirs()\Position\x , Tirs()\Position\y,16,$000000)
                    
                    
                    Tirs()\Speed - 0.05
                    If Tirs()\Speed<#TIR_SPEED_MOTION
                      Tirs()\Speed=#TIR_SPEED_MOTION
                    EndIf 
                    
                    If Tirs()\Position\y < #SH/2
                        track_SmoothPoint(Tirs(),Target,#TIR_SPEED_ROTATION)
                    EndIf 
                    
                    If Tirs()\Position\y > #SH+32
                    DeleteElement(Tirs())
                    Continue
                    EndIf 
                    
                    
                    Tirs()\Position\x + Tirs()\Speed *Cos(Tirs()\Angle*#PI/180)
                    Tirs()\Position\y + Tirs()\Speed *Sin(Tirs()\Angle*#PI/180)
                    
                    
                    
                    
                Next

     StopDrawing()

If KeyboardPushed(#PB_Key_Escape)<>#Null : Quit=1 : EndIf
FlipBuffers()
Until Quit=1
End




Procedure.f curveangle(newangle.f,oldangle.f,increments.f)
  If increments>1
    If (oldangle+360)-newangle<newangle-oldangle
      oldangle=360+oldangle
    EndIf
    If (newangle+360)-oldangle<oldangle-newangle
      newangle=360+newangle
    EndIf
    oldangle=oldangle-(oldangle-newangle)/increments
  EndIf
 
  If increments<=1
    ProcedureReturn newangle
  EndIf
  ProcedureReturn oldangle
EndProcedure


Procedure.f ReturnDegAngle(x1.f,y1.f,x2.f,y2.f) ; DEGREE
  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 track_SmoothPoint(*A.ENTITY,*B.ENTITY, turnspeed.f=1.0)
    AngDif = ReturnDegAngle(*A\position\x,*A\position\y,*B\position\x,*B\position\y)
    temp_yaw.f = curveangle(AngDif,*A\Angle,turnspeed)
    *A\Angle = temp_yaw
EndProcedure


Publié : lun. 09/févr./2009 13:27
par Cool Dji
Great Cpl.Bator,

J'ai remplacé les coordonnées fixes (512,128) par les coordonnées de la souris (MouseX(),MouseY()) et ça donne. Je vais utiliser ton code dans mon jeu pour un tir aimanté...

Merci, c'est vraiment ce que je cherchais également.

Publié : lun. 09/févr./2009 14:35
par Anonyme
Avec des sprites et du son c'est mieux : :D

File:1->shooter.rar
Image

Publié : lun. 09/févr./2009 18:52
par Cool Dji
C'est un double merci : sprite + particle => je n'avais pas encore ça dans mes listings...

Publié : lun. 09/févr./2009 20:33
par beauregard
je veux pas troubler l'enthousiasme ambiant, mais cela manque de précision, vous trouvez pas ? J'ai vu un code de CodeArchiv, et je viens de l'appliquer... et la précision est redoutable.
Image

Code : Tout sélectionner

; pb 4.30
; sprite d'un point A à un point B
; 31/05/2009 - Toulouse

If InitMouse ()=0 Or InitKeyboard ()=0 Or InitSprite ()=0  Or InitSprite3D ()=0
     MessageRequester ( "Error" , "Can't open DirectX 7 or later" , 0)
     End
EndIf
If InitSound()=0 Or InitMovie()=0
  MessageRequester("Error", "Can't open DirectX 7 Or Sound Card is not present", 0)
  End
EndIf

UsePNGImageDecoder()

; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;LoadFont ( 0 , "Comic Sans Ms" ,16, #PB_Font_Bold)
;LoadFont ( 1 , "Comic Sans Ms" ,30, #PB_Font_Bold)
Enumeration ; ici, on donne un petit nom à nos sprites( non, chuis pas un numéro !):

#raquette
#vilaintir
       
EndEnumeration

If OpenWindow ( 0 , 0, 0, 1024, 768, "tir orienté 2" , #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar| #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_ScreenCentered | #PB_Window_ScreenCentered )
 OpenWindowedScreen ( WindowID ( 0 ), 0, 0, 1024, 768, 0, 1, 1) ; un ecran graphique dans la fenêtre.

  SetWindowColor(0, RGB (236,216,234)) 
EndIf
KeyboardMode(#PB_Keyboard_International)

 CreateSprite ( #raquette , 64, 16, 0 )
 StartDrawing ( SpriteOutput ( #raquette )) ;- image pour la raquette
  BackColor ( RGB (0,0,0))
  Box (0,0, 64, 16, RGB (255, 255, 255))
 StopDrawing ()
 
 CreateSprite ( #vilaintir , 32, 32, 0 )
 StartDrawing ( SpriteOutput ( #vilaintir )) ;- image pour le tir
  BackColor ( RGB (0,0,0))
  Circle(16, 16, 16 , RGB (255, 0, 0))
 StopDrawing ()
 
Structure objet ;- variables pour les clones.

objetetat.w

objetx.f
objety.f
objetxs.f
objetys.f
objetangle.f

objetspeed.w

EndStructure
Global NewList trait.objet() ; -> #raquette
Global NewList tir.objet() ; -> #vilaintir 


Global etape.b, tempoA.b, nbrtir.w


Procedure.f GetAngle(gx,gy, tx,ty) ; g comme go( départ de l'action) et t comme target( l'objet cible à toucher).
  a.f = tx-gx
  b.f = ty-gy
  c.f = Sqr(a*a+b*b)
  angle.f = -ACos(a/c)*57.29577
  If ty < gy : angle=360-angle : EndIf
  If ty > gy : angle=360+angle : EndIf
  ProcedureReturn angle+90
EndProcedure

; ******************************************************************************************************
Repeat ; Boucle principale
; ******************************************************************************************************
 Event= WindowEvent ()
 Start3D() ; on place cette commande dès le début de la boucle principale.

 ExamineMouse()
 ExamineKeyboard ()
 
 
If etape=0

  ;- fabrication de la raquette
  LastElement(trait())
  AddElement(trait())
  trait()\objetetat=1
  trait()\objetx=512
  trait()\objety=640
 
 
 
  etape=1
EndIf

If etape=1
 
  ForEach trait()
    If trait()\objetetat=1;- raquette

      DisplayTransparentSprite ( #raquette , trait()\objetx, trait()\objety)
     
      If KeyboardPushed ( #PB_Key_Right ) And trait()\objetx<1024-64:trait()\objetx+5:EndIf ; droite.   
      If KeyboardPushed ( #PB_Key_Left ) And trait()\objetx>0:trait()\objetx-5:EndIf ; gauche.     
      
      If KeyboardPushed ( #PB_Key_Up ) And trait()\objetx<1024-64:trait()\objety-5:EndIf ; droite.   
      If KeyboardPushed ( #PB_Key_Down ) And trait()\objetx>0:trait()\objety+5:EndIf ; gauche.
           
    EndIf     
  Next 



;- fabrication tir *************
  If KeyboardPushed(#PB_Key_X)=0 And tempoA=2:tempoA=0:EndIf
  If KeyboardPushed(#PB_Key_X) And tempoA=0:tempoA=1:EndIf
  If tempoA=1:tempoA=2
     
    LastElement(tir())
    AddElement(tir())
    tir()\objetetat=1
    tir()\objetx=512
    tir()\objety=384   
    tir()\objetspeed=16 ;- vitesse des boulettes

    ForEach trait()
      If trait()\objetetat=1;- raquette( ici la cible, car nous avons besoin de connaitre ses coordonnées X et Y)
        ; pense bête: GetAngle( bouletteX,bouletteY, cibleX,cibleY)
        tir()\objetangle = GetAngle(tir()\objetx,tir()\objety, trait()\objetx+16,trait()\objety)
       
        ; milieu de la raquette(taille:64*16) -> 64/2=32 puis 32-16( car disque rouge 16) et donc trait()\objetx+16
      EndIf
    Next
     
    tir()\objetxs = Sin(tir()\objetangle*(3.14/180))*tir()\objetspeed
    tir()\objetys = Cos(tir()\objetangle*(3.14/180))*tir()\objetspeed

  EndIf
; fin fabrication tir **********



nbrtir=0 
  ForEach tir()
    If tir()\objetetat=1;- clone tir
nbrtir+1     
     
      DisplayTransparentSprite ( #vilaintir , tir()\objetx, tir()\objety)
     
      tir()\objetx=tir()\objetx+tir()\objetxs
      tir()\objety=tir()\objety+tir()\objetys

     
      If tir()\objetx>1024 Or tir()\objetx<0 Or tir()\objety>700 Or tir()\objety<0
        DeleteElement(tir())
        Continue
      EndIf
     
    EndIf     
  Next   
   
EndIf
 
 
  StartDrawing ( ScreenOutput ())
    DrawingMode (1)
      ;DrawingFont ( FontID (0))
      FrontColor ( RGB (255,255,255))
     rezut1$= Str (rezut1)
     rezut2$= Str (rezut2)
     
     FrontColor ( RGB (154,154,154)) :DrawText (1+1,220+1, "rezut1: " +rezut1$)
     FrontColor ( RGB (234,234,234)) :DrawText (1,220, "rezut1: " +rezut1$)
     FrontColor ( RGB (154,154,154)) :DrawText (1+1,240+1, "rezut2: " +rezut2$)
     FrontColor ( RGB (234,234,234)) :DrawText (1,240, "rezut2: " +rezut2$)

      FrontColor ( RGB (154,154,154)) :DrawText (350+1,20+1, "push X")
      FrontColor ( RGB (234,234,234)) :DrawText (350,20, "push X")
 
      nbrtir$= Str (nbrtir)
      FrontColor ( RGB (164,21,21)) :DrawText (42+1, 4+1, "  " +nbrtir$)
      FrontColor ( RGB (253,201,255)) :DrawText (42, 4, "  " +nbrtir$)
 
  StopDrawing ()
 
 
 
  Stop3D(); on place cette commande à la fin de la boucle principale.
 FlipBuffers()
 ClearScreen(RGB(0, 42, 255))
; ******************************************************************************************************   
 If Event= #PB_Event_CloseWindow Or KeyboardPushed ( #PB_Key_Escape ):End:EndIf; si clique coin haut droit ou touche Esc, alors ferme fenêtre.
ForEver








Publié : lun. 09/févr./2009 21:40
par Anonyme
Je fait de mon mieux :/
As tu lu ce que j'ai écrit plus Haut ? Post de 11:13 8O

Tu changes la vitesse de la baballe par 16 , c'est exactement la même chose :?


J'ai ajouté des explosions animé sur la même Archive pour ceux que cela intéresse.

File:1->shooter.rar
Image

Publié : lun. 09/févr./2009 21:48
par beauregard
Cpl.Bator a écrit :Je fait de mon mieux :/
As tu lu ce que j'ai écrit plus Haut ? Post de 11:13 8O

Tu changes la vitesse de la baballe par 16 , c'est exactement la même chose :?


J'ai ajouté des explosions animé sur la même Archive pour ceux que cela intéresse.

File:1->shooter.rar
Image
heu... oui:
La position X de tes tirs n'était pas un float d'ou un bug avec les angles :

j'avais bien compris, relance ce code que tu as modifié et tu verras que le problème de précision est bien réel( dirige la raquette à droite, les boulettes ne touche même pas la raquette...).

Avec le dernier code que j'ai posté, je tiens enfin la solution. joie !

Publié : lun. 09/févr./2009 21:52
par Anonyme
modifie la ligne 184

Code : Tout sélectionner

      tir()\objetx=tir()\objetx +16  * Cos(tir()\objetangle*#PI/180)
      tir()\objety=tir()\objety + 16 * Sin(tir()\objetangle*#PI/180)     
tu verras que ca touche , l'erreur venait de ton premier code :D

Publié : lun. 09/févr./2009 22:00
par beauregard
Cpl.Bator a écrit :modifie la ligne 184

Code : Tout sélectionner

      tir()\objetx=tir()\objetx +16  * Cos(tir()\objetangle*#PI/180)
      tir()\objety=tir()\objety + 16 * Sin(tir()\objetangle*#PI/180)     
tu verras que ca touche , l'erreur venait de ton premier code :D
effectivement, çà touche maintenant ! me voilà bien embêté, j'ai 2 codes qui marche ! ;) joie deux fois !
Image
Image