Les phases de la Lune V1.0(ça marche mais c'est chelou!)l

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Les phases de la Lune V1.0(ça marche mais c'est chelou!)l

Message par Huitbit »

Ben voilà,
Dans le cadre de mon projet avec le lycée, je me suis dit, allons donc faire un petit algo tranquillou cool bill!
Hé ben y a plein de trucs louches dans mon prog, ça doit être l'effet vacances???!

Code : Tout sélectionner

;***************variables utilisées**********************
xs.f=0;   pour le soleil
ys.f=0

xt.f=0;   pour la terre
yt.f=0

xl.f=0;   pour la lune 
yl.f=0

rt.f=160; rayon de l'orbite terrestre
rl.f=50; rayon de l'orbite lunaire

theta.f=0; angle pour la rotation de la terre
phi.f=0; angle pour la rotation de la lune
psi.f=0; angle de rotation de la lune par rapport au soleil
pi.f=3.1415927
;*************initialisation**********************
InitSprite()
InitMouse () 
InitSprite3D () 

OpenWindow (1, 1,1, 600, 500, #PB_Window_SystemMenu , "test" ) ; on ouvre une fenetre 
OpenWindowedScreen ( WindowID (1) , 0, 0, 600, 500, 1, 1, 1) ; on met un ecran dedans !! 


;***********************sprite terre***************************************

CreateSprite (1,32,32) ;terre éclairée sprite 32*32
StartDrawing ( SpriteOutput (1)) 
Circle (16,16, 16, RGB(33, 218, 222))
StopDrawing () 

CreateSprite (2,32,32) ; terre non éclairée sprite 32*32
StartDrawing ( SpriteOutput (2)) 
Circle (16,16, 16, RGB(26, 17, 178))
StopDrawing ()

ClipSprite(1,0,0,16,32);découpage terre éclairée
ClipSprite(2,16,0,16,32); découpage terre non éclairée

DisplaySprite(1,100,100);affichage des deux sprites
DisplaySprite(2,116,100)
  
GrabSprite(3,100,100,32,32,#PB_Sprite_Texture) ;capture d'écran et création du sprite(3) terre
                                               ; moitié éclairée moitié sombre
  
CreateSprite3D(1,3)


;******************************sprite lune**************************************

CreateSprite (4,16,16) ;lune éclairée sprite 16*16
StartDrawing ( SpriteOutput (4)) 
Circle (8,8,8, RGB(235, 235, 235))
StopDrawing () 

CreateSprite (5,16,16) ; lune non éclairée sprite 16*16
StartDrawing ( SpriteOutput (5)) 
Circle (8,8, 8, RGB(115, 115, 115))
StopDrawing ()

ClipSprite(4,0,0,8,16);découpage lune éclairée
ClipSprite(5,8,0,8,16); découpage lune non éclairée

DisplaySprite(4,100,132);affichage des deux sprites
DisplaySprite(5,108,132)
  
GrabSprite(6,100,132,16,16,#PB_Sprite_Texture) ;capture d'écran et création du sprite(6) lune
  
  
CreateSprite3D(2,6)

;*********************************** sprite soleil******************************
CreateSprite (7,64,64) 
StartDrawing ( SpriteOutput (7)) 
Circle(32,32,32,RGB(249, 244, 89)) 
StopDrawing () 

;***************************programme principal****************************************



Repeat ; boucle principale 

Event= WaitWindowEvent () ; on regarde si quelqu'un a cliqué sur la croix pour quitter 
For i =0 To 360
ExamineMouse () 
If MouseButton (2) ; le bouton de souris droit fait quitter ! 
End 
EndIf
 
Start3D(); utilisation des effets de la 3D pour la rotation des sprites 

xs=260  ;position du soleil
ys=210

; ***********calcul des trajectoires*************
theta=pi*i/180 ;conversions en radians
phi=pi*i/15

xt=xs+rt*Cos(-theta)+16; coords de la terre
yt=ys+rt*Sin(-theta)+16
xl=xt+rl*Cos(-phi)+8; coords de la lune
yl=yt+rl*Sin(-phi)+8

If (xl-xs)>0    ;phénomènes mystiques avec l'arctangente!
psi=180*ATan((yl-ys)/(xl-xs))/pi
EndIf

If (xl-xs)<0
psi=180*(ATan((yl-ys)/(xl-xs))/pi-1); surtout ici! faut que je révise ma trigo!
EndIf


;****************affichage des sprites***************************

  RotateSprite3D(1,-theta*180/pi,0); rotation de la terre avec l'angle en degrés
  RotateSprite3D(2,psi,0)       ; rotation de la Lune
  DisplaySprite(7,xs,ys)         ; affichage soleil
  DisplaySprite3D(1,xt,yt)      ; affichage terre
  DisplaySprite3D(2,xl,yl)      ; affichage lune
  FlipBuffers () ; <---- ceci pour voir le dessin se faire +Lent !! 
  ClearScreen (0, 0, 0) ; <--- ceci efface l'ecran !! 
  Delay(50)
Next i
Stop3D()

 
Until Event= #PB_Event_CloseWindow 
Return 
A la base je veux le mouvement de la Lune par rapport au Soleil(ça c'est fait mais c'est suspect!) et sur le même écran un zoom sur la phase courante de la Lune: Pleine Lune, 1ier quartier...(ça c'est en cours et ça devrait aller...).

Le premier truc que j'ai oublié c'est que tout est à l'envers sur l'ordi (x,y,les angles...)



Pour le calcul des trajectoires j'ai utilisé le galilée style cad la relativité des mouvements (exemple:
légende T terre, L lune, S soleil, > vecteur
SL>=ST>+TL>
cad xsl=xst+xtl et ysl=yst+ytl)

Vu que l'objectif final est de voir et comprendre les phases de la Lune , j'ai considéré que toutes les trajectoires étaient circulaires, je n'ai respecté aucune échelle.

Ensuite je voulais créer les sprites dans le prog , j'ai tenu compte de l'éclairage du Soleil (j'ai fait comme j'ai pu avec le découpage/assemblage/rotation des sprites!)

Pour les trajectoires j'ai pris les relations classiques avec cos et sin
Cependant, ...pour l'éclairage de la Lune, il me fallait l'angle de rotation de la Lune par rapport au Soleil(psi) et Là... j'ai utilisé l'arctangente(il doit y avoir plus propre mais j'ai pas trouvé).
Bilan quand l'angle est égal à 270 et 90 degrés(même si j'interdis le calcul à l'ordi), si je rajoute pas des choses la Lune fait un double axel et un saut périlleux de 180°!

Si vous voyez des choses louches(il y en a) faites le moi savoir SVP
Au niveau des modifs j'accepte ttes propositions(mais je devrais simplifier car je dois expliquer tout ça à des élèves!!!)

Encore merci pour tous vos conseils!
Elevé au MSX !
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

geant !! :D
Fred
Site Admin
Messages : 2648
Inscription : mer. 21/janv./2004 11:03

Message par Fred »

Sympa !

Voici mes suggestions:

- N'utilise pas WaitWindowEvent() car si aucun evenement arrive, ton programme va se bloquer. Utilise WindowEvent() qui n'est pas bloquant. De plus, il faut vider tous les evènements qui sont dans la queue (tant que WindowEvent() retourne un resultat <> 0, on continue). ex:

Code : Tout sélectionner

  Repeat 
    Event = WindowEvent() ; on regarde si quelqu'un a cliqué sur la croix pour quitter
    
    If Event = #PB_Event_CloseWindow
      End
    EndIf
    
  Until Event = 0 ; Plus d'evenements 'Windows' a traiter, on continue.
Du coup tu peux remplacer ton 'Until' par 'ForEver'

- Je ferais un test sur la touche 'Escape' pour quitter aussi (ExamineKeyboard() + KeyboardReleased()).

- 'Return' sert uniquement a revenir apres un 'Gosub'. Je pense que tu voulais mettre 'End'.
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

C'est une question de goût , c'est pas une faute , ça n'influence pas les performances , mais personnellement , je préfère utiliser les structures.
Dans le cadre d'un programme pédagogique comme le tien , ce n'est peut-être pas indispensable ? j'imagine que tu cherches à l'épurer au maximum pour aller à l'essentiel c'est à dire la visualisation d'un mouvement circulaire ?

Il est préférable de choisir des noms de variables explicites

exemple

Code : Tout sélectionner

rt.f=160; rayon de l'orbite terrestre 
Tu peux te passer de commentaire avec une variable comme ça :)

Code : Tout sélectionner

RayonOrbiteTerrestre.f=160
Et surtout , si le listing est long, tu n'as pas à rechercher le commentaire au début du code pour savoir à quoi elle correspond.

Pour en revenir aux structures,je ferais un truc de ce genre

Code : Tout sélectionner

Structure PointF
   x.f
   y.f
EndStructure

;Ensuite tu déclares tes planètes et astre 
Global Soleil.PointF,Terre.PointF,Lune.PointF

;Et tu peux renseigner les coordonnées 

Soleil\x = 0
Soleil\y = 0

Terre\x = 0
Terre\y = 0
Soleil\x , c'est un peu plus parlant que xs , enfin je trouve .
Idem pour tes sprites , tu peux faire une liste énumérée.

Code : Tout sélectionner

Enumeration
#Terre
#Lune
#Soleil
EndEnumeration

DisplaySprite(#Terre,Terre\x,Terre\y)
Tu as mis le Start3D() dans la boucle For i=x to x
C'est mieux de le mettre juste avant , c'est pas la peine d'appeler la fonction à chaque fois.

Puisque le soleil ne bouge pas, tu peux sortir de la boucle l'affectation de sa position

A placer avant la boucle

Code : Tout sélectionner

xs=260  ;position du soleil
ys=210 
Tu peux aussi afficher les angles , prévoir une pause pour laisser le temps de relever les angles et observer .

Voici un exemple
J'ai supprimé la souris, et je l'ai remplacé par la touche [Echap] pour quitter le programme.
la touche [F1] permet de mettre en pause la rotation.
la touche [F2] permet de donner un angle de départ.Ensuite faire [F1] pour lancer l'animation.

Code : Tout sélectionner

;***************variables utilisées**********************
xs.f=260;   pour le soleil
ys.f=210

xt.f=0;   pour la terre
yt.f=0

xl.f=0;   pour la lune
yl.f=0

rt.f=160; rayon de l'orbite terrestre
rl.f=50; rayon de l'orbite lunaire

theta.f=0; angle pour la rotation de la terre
phi.f=0; angle pour la rotation de la lune
psi.f=0; angle de rotation de la lune par rapport au soleil
pi.f=3.1415927
;*************initialisation**********************
InitSprite()
InitKeyboard()
InitSprite3D ()

OpenWindow (1, 1,1, 600, 500, #PB_Window_SystemMenu , "test" ) ; on ouvre une fenetre
OpenWindowedScreen ( WindowID (1) , 0, 0, 600, 500, 1, 1, 1) ; on met un ecran dedans !!


;***********************sprite terre***************************************

CreateSprite (1,32,32) ;terre éclairée sprite 32*32
StartDrawing ( SpriteOutput (1))
Circle (16,16, 16, RGB(33, 218, 222))
StopDrawing ()

CreateSprite (2,32,32) ; terre non éclairée sprite 32*32
StartDrawing ( SpriteOutput (2))
Circle (16,16, 16, RGB(26, 17, 178))
StopDrawing ()

ClipSprite(1,0,0,16,32);découpage terre éclairée
ClipSprite(2,16,0,16,32); découpage terre non éclairée

DisplaySprite(1,100,100);affichage des deux sprites
DisplaySprite(2,116,100)
 
GrabSprite(3,100,100,32,32,#PB_Sprite_Texture) ;capture d'écran et création du sprite(3) terre
                                               ; moitié éclairée moitié sombre
 
CreateSprite3D(1,3)


;******************************sprite lune**************************************

CreateSprite (4,16,16) ;lune éclairée sprite 16*16
StartDrawing ( SpriteOutput (4))
Circle (8,8,8, RGB(235, 235, 235))
StopDrawing ()

CreateSprite (5,16,16) ; lune non éclairée sprite 16*16
StartDrawing ( SpriteOutput (5))
Circle (8,8, 8, RGB(115, 115, 115))
StopDrawing ()

ClipSprite(4,0,0,8,16);découpage lune éclairée
ClipSprite(5,8,0,8,16); découpage lune non éclairée

DisplaySprite(4,100,132);affichage des deux sprites
DisplaySprite(5,108,132)
 
GrabSprite(6,100,132,16,16,#PB_Sprite_Texture) ;capture d'écran et création du sprite(6) lune
 
 
CreateSprite3D(2,6)

;*********************************** sprite soleil******************************
CreateSprite (7,64,64)
StartDrawing ( SpriteOutput (7))
Circle(32,32,32,RGB(249, 244, 89))
StopDrawing ()

;***************************programme principal****************************************


Repeat ; boucle principale
	
	Event= WindowEvent () ; on regarde si quelqu'un a cliqué sur la croix pour quitter
	
	If Event= #PB_Event_CloseWindow
		End
	EndIf
	
	While WindowEvent () : Wend
	
	If ExamineKeyboard()
		If KeyboardPushed(#PB_Key_Escape)
			End
		EndIf
		If KeyboardReleased(#PB_Key_F1)
			Pause=1-Pause 
		EndIf
		If KeyboardReleased(#PB_Key_F2)
			Pause=1
			i=Val(InputRequester("Titre","Donnez l'angle en degré ",Str(i)))
		EndIf
	EndIf
	
	; ***********calcul des trajectoires*************
	
	If Pause=0 
		i + 1
		If i>=360 
		  i=0
		EndIf  
	EndIf
	
	theta=pi*i/180 ;conversions en radians
	phi=pi*i/15
	
	xt=xs+rt*Cos(-theta)+16; coords de la terre
	yt=ys+rt*Sin(-theta)+16
	xl=xt+rl*Cos(-phi)+8; coords de la lune
	yl=yt+rl*Sin(-phi)+8
	
	If (xl-xs)>0    ;phénomènes mystiques avec l'arctangente!
		psi=180*ATan((yl-ys)/(xl-xs))/pi
	EndIf
	
	If (xl-xs)<0
		psi=180*(ATan((yl-ys)/(xl-xs))/pi-1); surtout ici! faut que je révise ma trigo!
	EndIf
	
	
	;****************affichage des sprites***************************
	ClearScreen (0, 0, 0) ; <--- ceci efface l'ecran !!
	
	DisplaySprite(7,xs,ys)         ; affichage soleil
	
	Start3D(); utilisation des effets de la 3D pour la rotation des sprites
		RotateSprite3D(1,-theta*180/pi,0); rotation de la terre avec l'angle en degrés
		RotateSprite3D(2,psi,0)       ; rotation de la Lune
		DisplaySprite3D(1,xt,yt)      ; affichage terre
		DisplaySprite3D(2,xl,yl)      ; affichage lune
	Stop3D()
	
	;Affiche les angles
	StartDrawing(ScreenOutput())
		FrontColor(255,255,255)
		DrawingMode(1)
		Locate(xt,yt-16)
		DrawText(StrF(Theta,2))
		Locate(xl,yl-16)
		DrawText(StrF(phi,2))
	StopDrawing()
	
	FlipBuffers () ; 
	
	Delay(50)
	 
ForEver
[EDIT]
Prise en compte des remarques de Fred

tiens j'ai pris 5 minutes pour faire une autre version

Code : Tout sélectionner

;***************variables utilisées**********************
Enumeration 
	#Soleil
	#Terre
	#Lune
	#FaceEclairee
   #FaceNonEclairee
EndEnumeration
Structure PointF 
	x.f
	y.f
	RayonOrbital.f
EndStructure

Global Soleil.PointF,Terre.PointF,Lune.PointF

Soleil\x=260
Soleil\y=210
Soleil\RayonOrbital=0

Terre\x=0
Terre\y=0
Terre\RayonOrbital=160

Lune\x=0
Lune\y=0
Lune\RayonOrbital=50

theta.f=0; angle pour la rotation de la terre
phi.f=0; angle pour la rotation de la lune
psi.f=0; angle de rotation de la lune par rapport au soleil

#pi =3.1415927 

;*************initialisation**********************
InitSprite()
InitKeyboard()
InitSprite3D ()

OpenWindow (1, 1,1, 600, 500, #PB_Window_SystemMenu , "test" ) ; on ouvre une fenetre
OpenWindowedScreen ( WindowID (1) , 0, 0, 600, 500, 1, 1, 1) ; on met un ecran dedans !!


;***********************sprite terre***************************************

CreateSprite (#FaceEclairee,32,32) ;terre éclairée sprite 32*32
StartDrawing ( SpriteOutput (#FaceEclairee))
Circle (16,16, 16, RGB(33, 218, 222))
StopDrawing ()

CreateSprite (#FaceNonEclairee,32,32) ; terre non éclairée sprite 32*32
StartDrawing ( SpriteOutput (#FaceNonEclairee))
Circle (16,16, 16, RGB(26, 17, 178))
StopDrawing ()

ClipSprite(#FaceEclairee,0,0,16,32);découpage terre éclairée
ClipSprite(#FaceNonEclairee,16,0,16,32); découpage terre non éclairée

DisplaySprite(#FaceEclairee,100,100);affichage des deux sprites
DisplaySprite(#FaceNonEclairee,116,100)
 
GrabSprite(#Terre,100,100,32,32,#PB_Sprite_Texture) ;capture d'écran et création du sprite(#Terre) terre
                                               ; moitié éclairée moitié sombre
 
CreateSprite3D(#Terre,#Terre)


;******************************sprite lune**************************************

CreateSprite (#FaceEclairee,16,16) ;lune éclairée sprite 16*16
StartDrawing ( SpriteOutput (#FaceEclairee))
Circle (8,8,8, RGB(235, 235, 235))
StopDrawing ()

CreateSprite (#FaceNonEclairee,16,16) ; lune non éclairée sprite 16*16
StartDrawing ( SpriteOutput (#FaceNonEclairee))
Circle (8,8, 8, RGB(115, 115, 115))
StopDrawing ()

ClipSprite(#FaceEclairee,0,0,8,16);découpage lune éclairée
ClipSprite(#FaceNonEclairee,8,0,8,16); découpage lune non éclairée

DisplaySprite(#FaceEclairee,100,132);affichage des deux sprites
DisplaySprite(#FaceNonEclairee,108,132)
 
GrabSprite(#Lune,100,132,16,16,#PB_Sprite_Texture) ;capture d'écran et création du sprite(#Lune) lune
  
CreateSprite3D(#Lune,#Lune)

;*********************************** sprite soleil******************************
CreateSprite (#Soleil,64,64)
StartDrawing ( SpriteOutput (#Soleil))
Circle(32,32,32,RGB(249, 244, 89))
StopDrawing ()

;***************************programme principal****************************************


Repeat ; boucle principale
	
	Event= WindowEvent () ; on regarde si quelqu'un a cliqué sur la croix pour quitter
	
	If Event= #PB_Event_CloseWindow
		End
	EndIf
	
	While WindowEvent () : Wend
	
	If ExamineKeyboard()
		If KeyboardPushed(#PB_Key_Escape)
			End
		EndIf
		If KeyboardReleased(#PB_Key_F1)
			Pause=1-Pause 
		EndIf
		If KeyboardReleased(#PB_Key_F2)
			Pause=1
			i=Val(InputRequester("Titre","Donnez l'angle en degré ",Str(i)))
		EndIf
	EndIf
	
	; ***********calcul des trajectoires*************
	
	If Pause=0 
		i + 1
		If i>=360 
		  i=0
		EndIf  
	EndIf
	
	theta=#pi*i/180 ;conversions en radians
	phi=#pi*i/15
	
	Terre\x=Soleil\x + Terre\RayonOrbital * Cos(-theta)+16
	Terre\y=Soleil\y + Terre\RayonOrbital * Sin(-theta)+16
	Lune\x=Terre\x + Lune\RayonOrbital * Cos(-phi)+8
	Lune\y=Terre\y + Lune\RayonOrbital * Sin(-phi)+8
	
	If (Lune\x-Soleil\x)>0    ;phénomènes mystiques avec l'arctangente!
		psi=180*ATan((Lune\y-Soleil\y)/(Lune\x-Soleil\x))/#pi
	EndIf
	
	If (Lune\x-Soleil\x)<0
		psi=180*(ATan((Lune\y-Soleil\y)/(Lune\x-Soleil\x))/#pi-1); surtout ici! faut que je révise ma trigo!
	EndIf
	
	
	;****************affichage des sprites***************************
	ClearScreen (0, 0, 0) ; <--- ceci efface l'ecran !!
	
	DisplaySprite(#Soleil,Soleil\x,Soleil\y)         ; affichage soleil
	
	Start3D(); utilisation des effets de la 3D pour la rotation des sprites
		RotateSprite3D(#Terre,-theta*180/pi,0); rotation de la terre avec l'angle en degrés
		RotateSprite3D(#Lune,psi,0)       ; rotation de la Lune
		DisplaySprite3D(#Terre,Terre\x,Terre\y)      ; affichage terre
		DisplaySprite3D(#Lune,Lune\x,Lune\y)      ; affichage lune
	Stop3D()
	
	;Affiche les angles
	StartDrawing(ScreenOutput())
		FrontColor(255,255,255)
		DrawingMode(1)
		Locate(Terre\x,Terre\y-16)
		DrawText(StrF(Theta,2))
		Locate(Lune\x,Lune\y-16)
		DrawText(StrF(phi,2))
	StopDrawing()
	
	FlipBuffers () ; 
	
	Delay(50)
	 
ForEver

Autre remarque tu avais utilisé une variable pour pi , le mieux quand tu travailles avec des valeurs constantes c'est d'utiliser une constante.

#Pi=3.14 , le compilateur va remplacer #pi par sa valeur directement avant de compiler , par contre si tu utilises une variable il va utiliser son adresse , et le prog sera légèrement plus lent.

Exemple si tu as ça dans purebasic

Code : Tout sélectionner

;#Pi
#Pi=3.14

;a.f=#Pi/2.0
a.f=#pi/2.0

;Pi.f
pi.f=3.14

;b.f=Pi/2.0
b.f=pi/2.0
Voila comment le compilo l'interprète

Code : Tout sélectionner

;#Pi
; #Pi=3.14
; 
;a.f=#Pi/2.0
; a.f=#pi/2.0
  MOV    dword [v_a],1070134723
; 
;Pi.f
; pi.f=3.14
  MOV    dword [v_pi],1078523331
; 
;b.f=Pi/2.0
; b.f=pi/2.0
  FLD    dword [v_pi]
  MOV    dword [esp-4],1073741824
  FDIV   dword [esp-4]
  FSTP   dword [v_b]
Si tu utilises des constantes l'affectation dans "a" est directe , la division est même effectuée avant, du coup dans l'exe tu n'as plus qu'une instruction.
MOV dword [v_a],1070134723

Pour faire le même calcul dans "b" si tu utilises une variable pour pi

Code : Tout sélectionner

; b.f=pi/2.0
  FLD    dword [v_pi]
  MOV    dword [esp-4],1073741824
  FDIV   dword [esp-4]
  FSTP   dword [v_b]
tu vois tout de suite que c'est un peu plus long à exécuter :)
Dernière modification par comtois le jeu. 22/déc./2005 15:08, modifié 4 fois.
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Fred
Site Admin
Messages : 2648
Inscription : mer. 21/janv./2004 11:03

Message par Fred »

Comtois: la boucle WindowEvent() doit etre encadrée d'un Repeat/Until car il peut y avoir de nombreux evenements dans la queue et là tu en enleve seulement un a chaque frame.

Sinon le ClearScreen() se met en general avant de commencer l'affichage (donc ici juste avant le DisplaySprite(7,..)
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Message par Huitbit »

Mille PureMerci, Dobro, Fred et Comtois

Je vais essayer de comprendre et d'assimiler toutes les infos (c'est sympa de détailler ça me fait gagner beaucoup de temps car j'ai BEAUCOUP à apprendre !).

En ce moment je fais la deuxième partie, cad ce que voit un terrien placé à la verticale de la Lune(ce qu'on voit quoi!).

La troisième partie ça pourra être d'afficher le jour et l'heure puis de synchroniser ça avec le calendrier.

A propos de l'arctangente les bizarreries viennent seulement du domaine de définition de la fonction ]-pi/2;+pi/2[

Hasta la proxima...
Elevé au MSX !
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

Message par cederavic »

Pour la gestion des évement sur la fenètre, je procederais plutot comme ça :

Code : Tout sélectionner

   Repeat
     wEvent = WindowEvent()
     
     Select Event
       Case #PB_Event_CloseWindow
         End

     EndSelect
   Until wEvent = #Null
Ca te permet de gérer les evenement dans un Select / EndSelect sans avec des If/ElseIf/EndIf a répétition.
Et puis dans le code au dessus, WindowEvent() est appelé 2 fois!
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Psst....

Message par Huitbit »

Dans la deuxième version (celle avec les structures) la face éclairée de laTerre ne rote pas (heu) ne tourne pas!

kesskisspass?
Elevé au MSX !
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

j'ai pas fait gaffe , j'ai oublié de changer pi par #pi

Code : Tout sélectionner

RotateSprite3D(#Terre,-theta*180/#pi,0)
Cederavic oui tu as raison , c'est pas bien d'appeler deux fois WindowEvent()

Code : Tout sélectionner

;***************variables utilisées**********************
Enumeration
   #Soleil
   #Terre
   #Lune
   #FaceEclairee
   #FaceNonEclairee
EndEnumeration
Structure PointF
   x.f
   y.f
   RayonOrbital.f
EndStructure

Global Soleil.PointF,Terre.PointF,Lune.PointF

Soleil\x=260
Soleil\y=210
Soleil\RayonOrbital=0

Terre\x=0
Terre\y=0
Terre\RayonOrbital=160

Lune\x=0
Lune\y=0
Lune\RayonOrbital=50

theta.f=0; angle pour la rotation de la terre
phi.f=0; angle pour la rotation de la lune
psi.f=0; angle de rotation de la lune par rapport au soleil

#pi =3.1415927

;*************initialisation**********************
InitSprite()
InitKeyboard()
InitSprite3D ()

OpenWindow (1, 1,1, 600, 500, #PB_Window_SystemMenu , "test" ) ; on ouvre une fenetre
OpenWindowedScreen ( WindowID (1) , 0, 0, 600, 500, 1, 1, 1) ; on met un ecran dedans !!


;***********************sprite terre***************************************

CreateSprite (#FaceEclairee,32,32) ;terre éclairée sprite 32*32
StartDrawing ( SpriteOutput (#FaceEclairee))
Circle (16,16, 16, RGB(33, 218, 222))
StopDrawing ()

CreateSprite (#FaceNonEclairee,32,32) ; terre non éclairée sprite 32*32
StartDrawing ( SpriteOutput (#FaceNonEclairee))
Circle (16,16, 16, RGB(26, 17, 178))
StopDrawing ()

ClipSprite(#FaceEclairee,0,0,16,32);découpage terre éclairée
ClipSprite(#FaceNonEclairee,16,0,16,32); découpage terre non éclairée

DisplaySprite(#FaceEclairee,100,100);affichage des deux sprites
DisplaySprite(#FaceNonEclairee,116,100)
 
GrabSprite(#Terre,100,100,32,32,#PB_Sprite_Texture) ;capture d'écran et création du sprite(#Terre) terre
                                               ; moitié éclairée moitié sombre
 
CreateSprite3D(#Terre,#Terre)


;******************************sprite lune**************************************

CreateSprite (#FaceEclairee,16,16) ;lune éclairée sprite 16*16
StartDrawing ( SpriteOutput (#FaceEclairee))
Circle (8,8,8, RGB(235, 235, 235))
StopDrawing ()

CreateSprite (#FaceNonEclairee,16,16) ; lune non éclairée sprite 16*16
StartDrawing ( SpriteOutput (#FaceNonEclairee))
Circle (8,8, 8, RGB(115, 115, 115))
StopDrawing ()

ClipSprite(#FaceEclairee,0,0,8,16);découpage lune éclairée
ClipSprite(#FaceNonEclairee,8,0,8,16); découpage lune non éclairée

DisplaySprite(#FaceEclairee,100,132);affichage des deux sprites
DisplaySprite(#FaceNonEclairee,108,132)
 
GrabSprite(#Lune,100,132,16,16,#PB_Sprite_Texture) ;capture d'écran et création du sprite(#Lune) lune
 
CreateSprite3D(#Lune,#Lune)

;*********************************** sprite soleil******************************
CreateSprite (#Soleil,64,64)
StartDrawing ( SpriteOutput (#Soleil))
Circle(32,32,32,RGB(249, 244, 89))
StopDrawing ()

;***************************programme principal****************************************


Repeat ; boucle principale
  
	Repeat
     Event = WindowEvent()
     
     Select Event
       Case #PB_Event_CloseWindow
         End
     EndSelect
   Until Event = #Null 
   
   If ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Escape)
         End
      EndIf
      If KeyboardReleased(#PB_Key_F1)
         Pause=1-Pause
      EndIf
      If KeyboardReleased(#PB_Key_F2)
         Pause=1
         i=Val(InputRequester("Titre","Donnez l'angle en degré ",Str(i)))
      EndIf
   EndIf
   
   ; ***********calcul des trajectoires*************
   
   If Pause=0
      i + 1
      If i>=360
        i=0
      EndIf 
   EndIf
   
   theta=#pi*i/180 ;conversions en radians
   phi=#pi*i/15
   
   Terre\x=Soleil\x + Terre\RayonOrbital * Cos(-theta)+16
   Terre\y=Soleil\y + Terre\RayonOrbital * Sin(-theta)+16
   Lune\x=Terre\x + Lune\RayonOrbital * Cos(-phi)+8
   Lune\y=Terre\y + Lune\RayonOrbital * Sin(-phi)+8
   
   If (Lune\x-Soleil\x)>0    ;phénomènes mystiques avec l'arctangente!
      psi=180*ATan((Lune\y-Soleil\y)/(Lune\x-Soleil\x))/#pi
   EndIf
   
   If (Lune\x-Soleil\x)<0
      psi=180*(ATan((Lune\y-Soleil\y)/(Lune\x-Soleil\x))/#pi-1); surtout ici! faut que je révise ma trigo!
   EndIf
   
   
   ;****************affichage des sprites***************************
   ClearScreen (0, 0, 0) ; <--- ceci efface l'ecran !!
   
   DisplaySprite(#Soleil,Soleil\x,Soleil\y)         ; affichage soleil
   
   Start3D(); utilisation des effets de la 3D pour la rotation des sprites
      RotateSprite3D(#Terre,-theta*180/#pi,0); rotation de la terre avec l'angle en degrés
      RotateSprite3D(#Lune,psi,0)       ; rotation de la Lune
      DisplaySprite3D(#Terre,Terre\x,Terre\y)      ; affichage terre
      DisplaySprite3D(#Lune,Lune\x,Lune\y)      ; affichage lune
   Stop3D()
   
   ;Affiche les angles
   StartDrawing(ScreenOutput())
      FrontColor(255,255,255)
      DrawingMode(1)
      Locate(Terre\x,Terre\y-16)
      DrawText(StrF(Theta,2))
      Locate(Lune\x,Lune\y-16)
      DrawText(StrF(phi,2))
   StopDrawing()
   
   FlipBuffers () ;
   
   Delay(50)
   
ForEver
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
comtois
Messages : 5172
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

à titre d'info tu peux aussi faire un DisplaySprite() dans un sprite
C'est pas utile ici , mais ça peut servir dans d'autres situations :)

Code : Tout sélectionner

;***********************sprite terre***************************************

CreateSprite (#FaceEclairee,32,32) ;terre éclairée sprite 32*32
StartDrawing ( SpriteOutput (#FaceEclairee))
Circle (16,16, 16, RGB(33, 218, 222))
StopDrawing ()

CreateSprite (#FaceNonEclairee,32,32) ; terre non éclairée sprite 32*32
StartDrawing ( SpriteOutput (#FaceNonEclairee))
Circle (16,16, 16, RGB(26, 17, 178))
StopDrawing ()

ClipSprite(#FaceEclairee,0,0,16,32);découpage terre éclairée
ClipSprite(#FaceNonEclairee,16,0,16,32); découpage terre non éclairée

CreateSprite(#Terre,32,32,#PB_Sprite_Texture)
UseBuffer(#Terre)
DisplaySprite(#FaceEclairee,0,0);affichage des deux sprites
DisplaySprite(#FaceNonEclairee,16,0)
UseBuffer(-1)

 
;GrabSprite(#Terre,100,100,32,32,#PB_Sprite_Texture) ;capture d'écran et création du sprite(#Terre) terre
                                               ; moitié éclairée moitié sombre
 
CreateSprite3D(#Terre,#Terre)
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Message par Huitbit »

Merci M'sieurs Cederavic et Comtois!

Pour le #pi je l'ai vu au moment où je postais le message (la prochaine fois, je lirai le prog en entier avant de t'embêter(désolé!)!)

Pour le displaysprite() c'est ce que j'ai voulu faire mais j'ai pô réussi alors j'ai tenté avec grab!

A+
Elevé au MSX !
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Tadam!...Phases de la Lune v1.1

Message par Huitbit »

Hi, ev'rybady!
Grace à l'affichage des variables j'ai pu corriger pas mal de trucs (mauvais centrage des sprites,..etc)
Donc, maintenant on peut voir les phases de la Lune ainsi que les angles en degrés

Je me suis débrouillé pour que tous les angles soient positifs et compris entre 0 et 360 degré.

Pour la relation entre l'angle Lune/Terre( cad phi), l'angle Lune/Soleil(cad psi) et l'angle correspondant à l'éclairage de la Lune alpha:
alpha=psi-phi (+ou- k*180) pour la trouver c'était chaud bouillant (prenez un papier et n'essayez pas!!!)

Comme d'habitude j'ai fait la mule et il y a des trucs en trop mais comme PureBasic et indulgent (et puissant) ça tourne!

Je rappelle que l'un des objectifs et de faire comprendre une phénomène physique (les élèves du collège et du lycée ont beaucoup de mal à se mettre à la place de "l'observateur")

Bref voilà le code:

Code : Tout sélectionner

;***************variables utilisées********************** 
xs.f=260;   pour le soleil 
ys.f=220 

xt.f=0;   pour la terre 
yt.f=0 

xl.f=0;   pour la lune 
yl.f=0 

rt.f=160; rayon de l'orbite terrestre 
rl.f=50; rayon de l'orbite lunaire 

theta.f=0; angle pour la rotation de la terre 
phi.f=0; angle pour la rotation de la lune 
psi.f=0; angle de rotation de la lune par rapport au soleil 
psi1.f=0; variable qui permet de travailler avec 0<psi<360
alpha1.f=0  ; angles qui nous renseignent  sur les parties éclairées et sombres de la lune 
alpha2.f=0
alpha3.f=0
alpha4.f=0
#pi=3.1415927
;*************initialisation********************** 
InitSprite() 
InitKeyboard() 
InitSprite3D () 

OpenWindow (1, 1,1, 600, 500, #PB_Window_SystemMenu , "Les phases de la Lune" ) ; on ouvre une fenetre 
OpenWindowedScreen ( WindowID (1) , 0, 0, 600, 500, 1, 1, 1) ; on met un ecran dedans !! 


;***********************sprite terre*************************************** 

CreateSprite (1,32,32) ;terre éclairée sprite 32*32 
StartDrawing ( SpriteOutput (1)) 
Circle (16,16, 16, RGB(33, 218, 222)) 
StopDrawing () 

CreateSprite (2,32,32) ; terre non éclairée sprite 32*32 
StartDrawing ( SpriteOutput (2)) 
Circle (16,16, 16, RGB(26, 17, 178)) 
StopDrawing () 

ClipSprite(1,0,0,16,32);découpage terre éclairée 
ClipSprite(2,16,0,16,32); découpage terre non éclairée 

DisplaySprite(1,100,100);affichage des deux sprites 
DisplaySprite(2,116,100) 
  
GrabSprite(3,100,100,32,32,#PB_Sprite_Texture) ;capture d'écran et création du sprite(3) terre 
                                               ; moitié éclairée moitié sombre 
  
CreateSprite3D(1,3) 


;******************************sprite lune************************************** 

CreateSprite (4,16,16) ;lune éclairée sprite 16*16 
StartDrawing ( SpriteOutput (4)) 
Circle (8,8,8, RGB(235, 235, 235)) 
StopDrawing () 

CreateSprite (5,16,16) ; lune non éclairée sprite 16*16 
StartDrawing ( SpriteOutput (5)) 
Circle (8,8, 8, RGB(115, 115, 115)) 
StopDrawing () 

ClipSprite(4,0,0,8,16);découpage lune éclairée 
ClipSprite(5,8,0,8,16); découpage lune non éclairée 

DisplaySprite(4,100,132);affichage des deux sprites 
DisplaySprite(5,108,132) 
  
GrabSprite(6,100,132,16,16,#PB_Sprite_Texture) ;capture d'écran et création du sprite(6) lune 
  
  
CreateSprite3D(2,6) 

;*********************************** sprite soleil****************************** 
CreateSprite (7,64,64) 
StartDrawing ( SpriteOutput (7)) 
Circle(32,32,32,RGB(249, 244, 89)) 
StopDrawing () 

;***************************programme principal**************************************** 


Repeat ; boucle principale 
  
   Repeat 
     Event = WindowEvent() 
      
     Select Event 
       Case #PB_Event_CloseWindow 
         End 
     EndSelect 
   Until Event = #Null 
    
   If ExamineKeyboard() 
      If KeyboardPushed(#PB_Key_Escape) 
         End 
      EndIf 
      If KeyboardReleased(#PB_Key_F1) 
         Pause=1-Pause 
      EndIf 
      If KeyboardReleased(#PB_Key_F2) 
         Pause=1 
         i=Val(InputRequester("Titre","Donnez l'angle en degré ",Str(i))) 
      EndIf 
   EndIf 
    
   ; ***********calcul des trajectoires************* 
    
   If Pause=0 
      i + 1 
   
      If i>=360 
        i=0 
      EndIf  
   EndIf 
    
   theta=#pi*i/180 ;conversions en radians 
   phi=#pi*i/15 -Int(i/30)*2*#pi  ; calcul pour garder  0<phi<360  
   
    
   xt=xs+rt*Cos(-theta); coords de la terre 
   yt=ys+rt*Sin(-theta) 
   
   xl=xt+rl*Cos(-phi); coords de la lune 
   yl=yt+rl*Sin(-phi) 
    
   If (xl-xs)>0     ; calcul de psi, l'angle Lune/Soleil
      psi=180*ATan((yl-ys)/(xl-xs))/#pi ; psi directement en degrés!
   EndIf 
    
   If (xl-xs)<0 
      psi=180*(ATan((yl-ys)/(xl-xs))/#pi-1); psi en degrés
   EndIf 
    
    
   ;****************affichage des sprites*************************** 
   ClearScreen (0, 0, 0) ; <--- ceci efface l'ecran !! 
    
   DisplaySprite(7,xs-32,ys-32)         ; affichage soleil 
    
   Start3D(); utilisation des effets de la 3D pour la rotation des sprites 
      RotateSprite3D(1,-theta*180/#pi,0); rotation de la terre avec l'angle en degrés 
      RotateSprite3D(2,psi,0)       ; rotation de la Lune 
      DisplaySprite3D(1,xt-16,yt-16)      ; affichage terre 
      DisplaySprite3D(2,xl-8,yl-8)      ; affichage lune 
   Stop3D() 
    
   ;travail avec des angles positifs
   If psi<=0
 psi1=-psi
   EndIf
   If psi>0
  psi1=360-psi
   EndIf
   
      alpha1=180+psi1-phi*180/#pi  ; alpha=psi-phi modulo 180 
      alpha2=-180+psi1-phi*180/#pi  ; à cause de ça je teste tous les cas
      alpha3= psi1-phi*180/#pi
      alpha4= 360+psi1-phi*180/#pi
  
   StartDrawing(ScreenOutput()) 
   
      FrontColor(255,255,255) 
      
      DrawingMode(1) 
      Locate(15,480)
      DrawText("<F1 pause et visualisation de la phase de la Lune >   < F2 choix de l'angle Terre/Soleil>")  
      Locate(xt+20,yt+20) 
      DrawText(StrF(Theta*180/#pi,2)) 
      Locate(xl+12,yl+12) 
      DrawText(StrF(phi*180/#pi,2)) 
      
      
 LineXY(535,0,600,0)  ; cadre pour la Lune en haut à droite
 LineXY(535,0,535,64)   
 LineXY(600,0,600,64)  
 LineXY(535,64,600,64)       
  
 If pause=1
    

LineXY(xt,yt,xl,yl,RGB(255, 255, 255)); ligne qui relie la Terre  à la Lune pour préciser où se
;trouve l'observateur


;en fonction de l'alpha choisi, la manière de dessiner change

 ;********alpha1*****************   
If alpha1>=0 And alpha1<=180

Locate(10,0) 
DrawText("Partie éclairée de la Lune = "+StrF(alpha1*100/180,2)+"%") 
If Cos(alpha1*#pi/180)<0 And Sin(alpha1*#pi/180)>0
Circle(568,32,32,RGB(201, 201, 201))
Box(568,0,32,64,RGB(0, 0, 0))
Ellipse(568,32,32*Cos(alpha1*#pi/180),32,RGB(201, 201, 201))
EndIf



If Cos(alpha1*#pi/180)>0 And Sin(alpha1*#pi/180)>0
Circle(568,32,32,RGB(201, 201, 201))
Ellipse(568,32,32*Cos(alpha1*#pi/180),32,RGB(0,0,0))
Box(568,0,32,64,RGB(0, 0, 0))
EndIf
EndIf
;*******alpha2******************
If alpha2>0 And alpha2<180

Locate(10,0) 
DrawText("Partie éclairée de la Lune = "+StrF(alpha2*100/180,2)+"%") 

If Cos(alpha2*#pi/180)<0 And Sin(alpha2*#pi/180)>0
Circle(568,32,32,RGB(201, 201, 201))
Box(568,0,32,64,RGB(0, 0, 0))
Ellipse(568,32,32*Cos(alpha2*#pi/180),32,RGB(201, 201, 201))
EndIf

If Cos(alpha2*#pi/180)>0 And Sin(alpha2*#pi/180)>0
Circle(568,32,32,RGB(201, 201, 201))
Ellipse(568,32,32*Cos(alpha2*#pi/180),32,RGB(0,0,0))
Box(568,0,32,64,RGB(0, 0, 0))
EndIf

EndIf
;*********************alpha3************

If alpha3>0 And alpha3<180
Locate(10,0) 
DrawText("Partie éclairée de la Lune = "+StrF(100-alpha3*100/180,2)+"%") 

If Cos(alpha3*#pi/180)<0 And Sin(alpha3*#pi/180)>0
Circle(568,32,32,RGB(201, 201, 201))
Ellipse(568,32,32*Cos(alpha3*#pi/180),32,RGB(0,0,0))
Box(536,0,32,64,RGB(0, 0, 0))
EndIf


If Cos(alpha3*#pi/180)>0 And Sin(alpha3*#pi/180)>0
Circle(568,32,32,RGB(201, 201, 201))
Box(536,0,32,64,RGB(0, 0, 0))
Ellipse(568,32,32*Cos(alpha3*#pi/180),32,RGB(201, 201, 201))

EndIf
EndIf
;**************************alpha4**********    
If alpha4>0 And alpha4<180
Locate(10,0) 
DrawText("Partie éclairée de la Lune = "+StrF(100-alpha4*100/180,2)+"%") 

If Cos(alpha4*#pi/180)<0 And Sin(alpha4*#pi/180)>0
Circle(568,32,32,RGB(201, 201, 201))
Ellipse(568,32,32*Cos(alpha4*#pi/180),32,RGB(0,0,0))
Box(536,0,32,64,RGB(0, 0, 0))
EndIf


If Cos(alpha4*#pi/180)>0 And Sin(alpha4*#pi/180)>0
Circle(568,32,32,RGB(201, 201, 201))
Box(536,0,32,64,RGB(0, 0, 0))
Ellipse(568,32,32*Cos(alpha4*#pi/180),32,RGB(201, 201, 201))

EndIf
EndIf 
;*********************************************************     
    EndIf   
   StopDrawing() 
    
   FlipBuffers () ; 
    
   Delay(50) 
    
ForEver

Je vais essayer d'épurer un peu ce code, mais si vous pouviez jeter un coup d'oeil (vous en avez déjà fait BEAUCOUP!)

A part ça joyeux Noël!
Elevé au MSX !
Avatar de l’utilisateur
Droopy
Messages : 1151
Inscription : lun. 19/juil./2004 22:31

Message par Droopy »

Sympa, je vais montrer ça à ma fille de 9 ans pour qu'elle comprenne ce mouvement :D
Avatar de l’utilisateur
cederavic
Messages : 1338
Inscription : lun. 09/févr./2004 23:38
Localisation : Bordeaux

Message par cederavic »

Un ptite capture pour commencer :
Image

Voilas mes quelques modifs :
- Ajout d'image (c'est encor plus beau a voir :p)
- Ajout des constantes pour les sprites
- Ombrage de la lune en haut a droite en temps reel
- Mise en forme du code
- Utilisation de la police Lucida Console
- Possibilité de change le pas d'incrementation de l'angle (pour voir au ralentit ou accéléré)

Voila le code :

Code : Tout sélectionner

;***************variables utilisées**********************
xs.f=260;   pour le soleil
ys.f=220

xt.f=0;   pour la terre
yt.f=0

xl.f=0;   pour la lune
yl.f=0

rt.f=160; rayon de l'orbite terrestre
rl.f=50; rayon de l'orbite lunaire

theta.f=0; angle pour la rotation de la terre
phi.f=0; angle pour la rotation de la lune
psi.f=0; angle de rotation de la lune par rapport au soleil
psi1.f=0; variable qui permet de travailler avec 0<psi<360
alpha1.f=0  ; angles qui nous renseignent  sur les parties éclairées et sombres de la lune
alpha2.f=0
alpha3.f=0
alpha4.f=0
Angle.f = 0.0
IncAngle.f = 1.0
#Pi=3.1415927

; Enumeration des constantes pour les sprites (ça evite de s'embrouiller avec les nombres)
Enumeration
  #SPR_Background
  #SPR_Terre
  #SPR_OmbreTerre
  #SPR_Lune
  #SPR_LuneMini
  #SPR_OmbreLune
  #SPR_Soleil
  #SPR_RayonsSoleil
EndEnumeration

;*************initialisation**********************
InitSprite()
InitKeyboard()
InitSprite3D ()

OpenWindow (1, 1,1, 600, 500, #PB_Window_SystemMenu , "Les phases de la Lune" ) ; on ouvre une fenetre
  OpenWindowedScreen ( WindowID (1) , 0, 0, 600, 500, 1, 1, 1) ; on met un ecran dedans !!
  UsePNGImageDecoder()
  
  LoadFont(1, "Lucida Console", 8, #PB_Font_HighQuality | #PB_Font_Bold)

LoadSprite(#SPR_Background, "Background.png")

;***********************sprite terre***************************************

LoadSprite(#Spr_Terre, "Terre.png", #PB_Sprite_Texture)
  CreateSprite3D(#SPR_Terre, #SPR_Terre)

; Creation de 2 sprite temporaire pour faire le sprite d'ombrage de la terre
TempSpr1 = CreateSprite (#PB_Any,32,32) ;terre éclairée sprite 32*32
  StartDrawing ( SpriteOutput (TempSpr1))
    Circle (16,16, 16, RGB(196, 196, 196))
  StopDrawing ()

TempSpr2 = CreateSprite (#PB_Any,32,32) ; terre non éclairée sprite 32*32
  StartDrawing ( SpriteOutput (TempSpr2))
    Circle (16,16, 16, RGB(12,12, 12))
  StopDrawing ()

ClipSprite(TempSpr1,0,0,16,32);découpage terre éclairée
ClipSprite(TempSpr2,16,0,16,32); découpage terre non éclairée

DisplaySprite(TempSpr1,100,100);affichage des deux sprites
DisplaySprite(TempSpr2,116,100)
 
GrabSprite(#Spr_OmbreTerre,100,100,32,32,#PB_Sprite_Texture) ;capture d'écran et création du sprite(3) terre
                                               ; moitié éclairée moitié sombre
CreateSprite3D(#Spr_OmbreTerre,#Spr_OmbreTerre)
  
FreeSprite(TempSpr1)
FreeSprite(TempSpr2)

;******************************sprite lune**************************************

LoadSprite(#SPR_Lune, "Lune.png", #PB_Sprite_Texture)
  CreateSprite3D(#SPR_Lune, #SPR_Lune)
LoadSprite(#SPR_LuneMini, "Lune_mini.png", #PB_Sprite_Texture)
  CreateSprite3D(#SPR_LuneMini, #SPR_LuneMini)

; Creation de 2 sprite temporaire pour faire le sprite d'ombrage de la lune
TempSpr1 = CreateSprite (#PB_Any,16,16) ;lune éclairée sprite 16*16
  StartDrawing ( SpriteOutput (TempSpr1))
    Circle (8,8,8, RGB(235, 235, 235))
  StopDrawing ()

TempSpr2 = CreateSprite (#PB_Any,16,16) ; lune non éclairée sprite 16*16
  StartDrawing ( SpriteOutput (TempSpr2))
    Circle (8,8, 8, RGB(115, 115, 115))
  StopDrawing ()

ClipSprite(TempSpr1,0,0,8,16);découpage lune éclairée
ClipSprite(TempSpr2,8,0,8,16); découpage lune non éclairée

DisplaySprite(TempSpr1,100,132);affichage des deux sprites
DisplaySprite(TempSpr2,108,132)
 
GrabSprite(#SPR_OmbreLune,100,132,16,16,#PB_Sprite_Texture) ;capture d'écran et création du sprite(6) lune
CreateSprite3D(#SPR_OmbreLune,#SPR_OmbreLune)

FreeSprite(TempSpr1)
FreeSprite(TempSpr2)

;*********************************** sprite soleil******************************

LoadSprite(#SPR_Soleil, "Soleil.png", #PB_Sprite_Texture)
  CreateSprite3D(#SPR_Soleil, #SPR_Soleil)
LoadSprite(#SPR_RayonsSoleil, "RayonsSoleil.png", #PB_Sprite_Texture)
  CreateSprite3D(#SPR_RayonsSoleil, #SPR_RayonsSoleil)

;***************************programme principal****************************************


Repeat ; boucle principale
 
   Repeat
     Event = WindowEvent()
     
     Select Event
       Case #PB_Event_CloseWindow
         End
     EndSelect
   Until Event = #Null
   
   If ExamineKeyboard()
      If KeyboardPushed(#PB_Key_Escape)
         End
      EndIf
      If KeyboardReleased(#PB_Key_F1)
         Pause=1-Pause
      EndIf
      If KeyboardReleased(#PB_Key_F2)
         Pause=1
         Angle=ValF(InputRequester("Titre","Donnez l'angle en degré :",StrF(Angle)))
      EndIf
      If KeyboardReleased(#PB_Key_F3)
         IncAngle=ValF(InputRequester("Titre","Donnez le pas d'incrementation de l'angle :",StrF(IncAngle)))
      EndIf
   EndIf
   
   ; ***********calcul des trajectoires*************
   
   If Pause=0
      Angle + IncAngle
   
      If Angle>=360
        Angle=0
      EndIf 
   EndIf
   
   theta=#Pi*Angle/180 ;conversions en radians
   phi=#Pi*Angle/15 -Int(Angle/30)*2*#Pi  ; calcul pour garder  0<phi<360 
   
   
   xt=xs+rt*Cos(-theta); coords de la terre
   yt=ys+rt*Sin(-theta)
   
   xl=xt+rl*Cos(-phi); coords de la lune
   yl=yt+rl*Sin(-phi)
   
   If (xl-xs)>0     ; calcul de psi, l'angle Lune/Soleil
      psi=180*ATan((yl-ys)/(xl-xs))/#Pi ; psi directement en degrés!
   EndIf
   
   If (xl-xs)<0
      psi=180*(ATan((yl-ys)/(xl-xs))/#Pi-1); psi en degrés
   EndIf
   
   
   ;****************affichage des sprites***************************
   DisplaySprite(#SPR_Background, 0, 0) ; Pas de besoin de ClearScreen car le sprite recouvre tout l'écran
   
   ;travail avec des angles positifs
   If psi<=0
      psi1=-psi
   EndIf
   If psi>0
      psi1=360-psi
   EndIf
   
      alpha1=180+psi1-phi*180/#Pi  ; alpha=psi-phi modulo 180
      alpha2=-180+psi1-phi*180/#Pi  ; à cause de ça je teste tous les cas
      alpha3= psi1-phi*180/#Pi
      alpha4= 360+psi1-phi*180/#Pi
 
   StartDrawing(ScreenOutput())
     
     DrawingFont(FontID())
     FrontColor(255,255,255)
     
     DrawingMode(1)
     Locate(5,460)
     DrawText("F1 visualisation de la phase de la Lune | F2 choix de l'angle Terre/Soleil") 
     Locate(5,480)
     DrawText(" F3 choix du pas d'incrementation de l'angle | ESC quitter l'application")
     Locate(xt+20,yt+20)
     DrawText(StrF(Theta*180/#Pi,2))
     Locate(xl+12,yl+12)
     DrawText(StrF(phi*180/#Pi,2))    
     
     If Pause = 1
       LineXY(xt,yt,xl,yl,RGB(255, 255, 255)); ligne qui relie la Terre  à la Lune pour préciser où se
       ;trouve l'observateur
     EndIf
      
     ;en fonction de l'alpha choisi, la manière de dessiner change
     
     ;********alpha1*****************   
     If alpha1>=0 And alpha1<=180
     
       Locate(10,5)
       DrawText("Partie éclairée de la Lune = "+StrF(alpha1*100/180,2)+"%")
       
       If Cos(alpha1*#Pi/180)<0 And Sin(alpha1*#Pi/180)>0
         Circle(568,32,32,RGB(128, 128, 128))
         Box(568,0,32,64,RGB(0, 0, 0))
         Ellipse(568,32,32*Cos(alpha1*#Pi/180),32,RGB(128, 128, 128))
       EndIf
       
       If Cos(alpha1*#Pi/180)>0 And Sin(alpha1*#Pi/180)>0
         Circle(568,32,32,RGB(128, 128, 128))
         Ellipse(568,32,32*Cos(alpha1*#Pi/180),32,RGB(0,0,0))
         Box(568,0,32,64,RGB(0, 0, 0))
       EndIf
       
     EndIf
     ;*******alpha2******************
     If alpha2>0 And alpha2<180
     
       Locate(10,5)
       DrawText("Partie éclairée de la Lune = "+StrF(alpha2*100/180,2)+"%")
       
       If Cos(alpha2*#Pi/180)<0 And Sin(alpha2*#Pi/180)>0
         Circle(568,32,32,RGB(128, 128, 128))
         Box(568,0,32,64,RGB(0, 0, 0))
         Ellipse(568,32,32*Cos(alpha2*#Pi/180),32,RGB(128, 128, 128))
       EndIf
       
       If Cos(alpha2*#Pi/180)>0 And Sin(alpha2*#Pi/180)>0
         Circle(568,32,32,RGB(128, 128, 128))
         Ellipse(568,32,32*Cos(alpha2*#Pi/180),32,RGB(0,0,0))
         Box(568,0,32,64,RGB(0, 0, 0))
       EndIf
     
     EndIf
     ;*********************alpha3************
     
     If alpha3>0 And alpha3<180
       Locate(10,5)
       DrawText("Partie éclairée de la Lune = "+StrF(100-alpha3*100/180,2)+"%")
       
       If Cos(alpha3*#Pi/180)<0 And Sin(alpha3*#Pi/180)>0
         Circle(568,32,32,RGB(128, 128, 128))
         Ellipse(568,32,32*Cos(alpha3*#Pi/180),32,RGB(0,0,0))
         Box(536,0,32,64,RGB(0, 0, 0))
       EndIf
       
       
       If Cos(alpha3*#Pi/180)>0 And Sin(alpha3*#Pi/180)>0
         Circle(568,32,32,RGB(128, 128, 128))
         Box(536,0,32,64,RGB(0, 0, 0))
         Ellipse(568,32,32*Cos(alpha3*#Pi/180),32,RGB(128, 128, 128))
       EndIf
     EndIf
     ;**************************alpha4**********   
     If alpha4>0 And alpha4<180
       Locate(10,5)
       DrawText("Partie éclairée de la Lune = "+StrF(100-alpha4*100/180,2)+"%")
       
       If Cos(alpha4*#Pi/180)<0 And Sin(alpha4*#Pi/180)>0
         Circle(568,32,32,RGB(128, 128, 128))
         Ellipse(568,32,32*Cos(alpha4*#Pi/180),32,RGB(0,0,0))
         Box(536,0,32,64,RGB(0, 0, 0))
       EndIf
       
       
       If Cos(alpha4*#Pi/180)>0 And Sin(alpha4*#Pi/180)>0
         Circle(568,32,32,RGB(128, 128, 128))
         Box(536,0,32,64,RGB(0, 0, 0))
         Ellipse(568,32,32*Cos(alpha4*#Pi/180),32,RGB(128, 128, 128))
       EndIf
     EndIf
     ;*********************************************************     
    
     LineXY(535,0,600,0)  ; cadre pour la Lune en haut à droite
     LineXY(535,0,535,64)   
     LineXY(600,0,600,64) 
     LineXY(535,64,600,64) 
   StopDrawing()
   
   Start3D(); utilisation des effets de la 3D pour la rotation des sprites
 
      RotateSprite3D(#SPR_Terre,-theta*180/#Pi,0); rotation de la terre avec l'angle en degrés
      RotateSprite3D(#SPR_OmbreTerre,-theta*180/#Pi,0)
      RotateSprite3D(#SPR_LuneMini,psi,0)       ; rotation de la Lune
      RotateSprite3D(#SPR_OmbreLune,psi,0)      
      Sprite3DBlendingMode(5, 7) ; change le BlendingMode pour un meilleur effet
      DisplaySprite3D(#SPR_RayonsSoleil,xs-48,ys-48, 255) ; affichage rayons soleil 
      DisplaySprite3D(#SPR_Soleil,xs-48,ys-48, 255)         ; affichage soleil 
      Sprite3DBlendingMode(5, 6)
      DisplaySprite3D(#SPR_Terre,xt-16,yt-16, 255)      ; affichage terre
      DisplaySprite3D(#SPR_OmbreTerre, xt-16,yt-16,128)
      DisplaySprite3D(#SPR_LuneMini,xl-8,yl-8, 255)      ; affichage lune
      DisplaySprite3D(#SPR_OmbreLune, xl-8,yl-8, 128)
      DisplaySprite3D(#SPR_Lune, 536, 1, 128) ; ombrage lune (haut droit)
      
   Stop3D()
   
   FlipBuffers () ;
   
   Delay(50)
   
ForEver
et les images :

Background.png
Image

Soleil.png
Image

RayonsSoleil.png
Image

Terre.png
Image

Lune.png
Image

Lune_mini.png
Image

J'espere que je ne t'ai pas trop compliqué le code 8)
Avatar de l’utilisateur
Huitbit
Messages : 939
Inscription : jeu. 08/déc./2005 5:19
Localisation : Guadeloupe

Nom d'une pipe en bois!!!!!

Message par Huitbit »

Droopy tu m'as donné une idée pour les élèves, je vais afficher 3 "fausses" phases en plus et ils devront choisir la bonne sinon....500 pompes( hé oui, la section de combat à l'armée m'a laissée des séquelles!)

Cederavic, laisse-moi deviner, tu fais à peu près 1,80 m, tu as une grande veste rouge avec un bonnet avec un pompon blanc, et tu fais "How, how, how" le matin?

Tu m'as fait un beau cadeau de Noël, j'espère que tout le monde en profitera.

Hasta la vista
Elevé au MSX !
Répondre