pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 2024
-
Modifié par pijaku le 18/09/2014 à 09:24
pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 2024
-
10 nov. 2014 à 08:09
Bonjour,
J'essaie de rendre "réaliste" (on s'entend bien, ça n'est que du VBA...), le jet de dé et son déplacement au sein d'un UserForm.
Je me heurte actuellement à deux problèmes :
1- par moment l'userform "bloque". Il reste figé comme lors d'un plantage Excel avec un message d'erreur dans son Caption (Ne répond pas...), puis m'affiche "l'image finale".
Je pense que cela est du aux .Repaint en boucles... A voir.
2- Le dé ne respecte pas l'obstacle que représente le bord bas de l'UserForm. Il "déborde" vers le bas. Je n'ai pas ce souci avec les 3 autres bords (quoiqu'un léger souci avec le bord droit...).
Ce problème est matérialisé, dans le code, par des commentaires :
'///////////////////////SOUCI
Pour vous rendre compte, par vous mêmes, vous pouvez, au choix, télécharger mon fichier exemple : sur cjoint.com, ou faire votre propre fichier.
Dans un cas, comme dans l'autre, vous aurez besoin des images des dés (à renommer : 1.jpg, 2.jpg etc... 6.jpg)
Pour faire votre propre fichier, dans un classeur vierge :
- insérez un UserForm (propriété Name : "Piste")
- dessinez y un contrôle Image (propriété Name : "ImageDe")
Les codes :
Module de l'UserForm :
Option Explicit
Dim StopIt As Boolean
Private Sub UserForm_Initialize()
With Me
.Height = 700
.Width = 700
.BackColor = 32768
.Caption = "Piste de dés"
With .ImageDe
.Height = 24
.Width = 24
.Visible = False
End With
End With
End Sub
'Pour calculer la force de lancer du dé (entre 1 et 100), le joueur doit maintenir le bouton gauche de la souris appuyé
'durant tout le temps ou ce bouton est maintenu (UserForm_MouseDown), la variable Force varie de 1 à 100 et de 100 à 1
'l'arrêt de cette procédure se fait en relachant le bouton (UserForm_MouseUp)
'la variable Boolean StopIt, déclarée en entête de ce module, combinée au DoEvents permet cet arrêt
Private Sub UserForm_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
Dim i As Integer
'initialisation de la variable Force (à chaque clic dans l'UserForm)
Force = 1
StopIt = False
'la variable i prends les valeurs uniques 1 & -1
'Elle sert donc à faire varier le "sens" d'incrémentation de la variable Force :
'quand i = 1, Force varie de 1 vers 100
'quand i = -1, Force varie de 100 vers 1
Do While StopIt = False
Force = Force + (1 * i)
If Force = 1 Then i = 1
If Force = 100 Then i = -1
DoEvents 'permet de déclencher l'événement Mouse_Up et donc de Stopper cette boucle
Loop
End Sub
Private Sub UserForm_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
StopIt = True
Jeter_Les_Des
End Sub
Dans un module standard :
Option Explicit
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Public Force As Integer
Dim De_Left As Integer, De_Top As Integer
Dim Coeff_Sens_Left As Double, Coeff_Sens_Top As Double
Sub Jeter_Les_Des()
Dim Tb(), i As Integer, Chemin As String, Cpt As Integer, Attente As Long
'Initialisation des variables
Chemin = ThisWorkbook.Path & "" '=> Pour les images à afficher dans le contrôle ImageDe
Randomize Timer ' => Tirages aléatoires
Attente = 80 + (100 - Force) ' => Représente la vitesse initiale du dé
Call Mouvements_Du_De(Tb()) ' Calcule et stocke toutes les positions du dés + ses valeurs
For i = LBound(Tb, 2) To UBound(Tb, 2) ' Boucle sur toutes les positions prévues du dé
'ralenti le dé
Cpt = Cpt + 1
If Cpt >= UBound(Tb, 2) / 10 Then
Cpt = 0
Attente = Attente + 20
End If
'affiche l'image du dé
With Piste
With .ImageDe
.Move Tb(1, i), Tb(2, i), 24, 24
.Visible = True
.Picture = LoadPicture(Chemin & Tb(3, i) & ".jpg")
.PictureSizeMode = fmPictureSizeModeStretch
End With
.Repaint
End With
Sleep Attente
Next i
End Sub
'Calcule et stocke toutes les positions du dés + ses valeurs
'Les données, stockées dans une variable tableau, sont : Left + Top + Valeur du dé
Sub Mouvements_Du_De(ByRef Tbl())
Dim i As Integer, Valeur_Du_De As Byte, FinBoucle As Integer
'Si la force = 1, il n'y aura pas de mouvement. Le dé tombe sur la piste.
'Dans ce cas, on ne lance que la procédure Point_De_Chute_Du_De.
If Force = 1 Then
Call Point_De_Chute_Du_De(Tbl())
Exit Sub
End If
'Point_De_Chute_Du_De => calcule aléatoirement ou va tomber le dé.
Call Point_De_Chute_Du_De(Tbl())
'Sens_Aleatoire => Calcule aléatoirement un coefficient Left et un coefficient Top
'Ces deux coefficients, multipliés à des constantes (en fonction de la force),
'nous donnent les coordonnées des emplacements du dé.
Call Sens_Aleatoire
'Initialisation variable
'La force va diminuer au fur et à mesure de la boucle, on stocke donc sa valeur initiale.
FinBoucle = Force
For i = 2 To FinBoucle
'calcul des coordonnées de l'emplacement suivant, en fonction de l'emplacement actuel.
De_Left = Tbl(1, i - 1) + (Force * 1.5) * Coeff_Sens_Left
De_Top = Tbl(2, i - 1) + (Force * 1.5) * Coeff_Sens_Top
'******************************************************************************************* A Faire.
'Apporter un coeff supplémentaire à une des deux "directions" pour donner un effet moins linéaire aux déplacements
'*******************************************************************************************
'Permet de changer de sens lorsque le dé touche un des bords de la piste
If De_Left < 0 Then
Coeff_Sens_Left = Coeff_Sens_Left * -1
De_Left = 0
End If
'Pas de valeur numérique => permet de changer la taille de l'UserForm
If De_Left >= Piste.Width - Piste.ImageDe.Width Then
Coeff_Sens_Left = Coeff_Sens_Left * -1
De_Left = Piste.Width - Piste.ImageDe.Width '///////////////////////SOUCI "Léger"
End If
If De_Top < 0 Then
Coeff_Sens_Top = Coeff_Sens_Top * -1
De_Top = 0
End If
If De_Top >= Piste.Height - Piste.ImageDe.Height Then
Coeff_Sens_Top = Coeff_Sens_Top * -1
De_Top = Piste.Height - Piste.ImageDe.Height '///////////////////////SOUCI "Important"
End If
'*******************************************************************************************A modifier.
'En fin de mouvement du dé, le dé roule et donc un 4 (par ex) ne peut pas être suivi :
'- ni pas un 4 (dé glissé),
'- ni par un 3 (situé sur l'autre face)
Valeur_Du_De = CInt((5 * Rnd()) + 1)
'*******************************************************************************************
'stockage des valeurs
ReDim Preserve Tbl(1 To 3, 1 To i)
Tbl(1, i) = De_Left
Tbl(2, i) = De_Top
Tbl(3, i) = Valeur_Du_De
'Baisse de la force => le dé va de moins en moins loin par rapport à sa position actuelle
Force = CInt(Force - (Force / 20))
Next i
End Sub
Sub Point_De_Chute_Du_De(ByRef Tabl())
'calcul aléatoire des 3 valeurs initiales du dé
Erase Tabl
ReDim Preserve Tabl(1 To 3, 1 To 1)
Tabl(1, 1) = CInt((675 * Rnd()) + 1) ' => Propriété Left
Tabl(2, 1) = CInt((675 * Rnd()) + 1) ' => Propriété Top
Tabl(3, 1) = CInt((5 * Rnd()) + 1) ' => Valeur
End Sub
Sub Sens_Aleatoire()
'calcul aléatoire de Coeff_Sens_Left et Coeff_Sens_Top pour la première direction
Dim Valeurs(200), i As Long
'Les 2 coeffs sont des valeurs comprises entre -1 et +1 Step 0.01 : -1, -0.99, -0.98, ...
For i = -100 To 100
Valeurs(i + 100) = i / 100
Next i
'calcul aléatoire de Coeff_Sens_Left et Coeff_Sens_Top
Coeff_Sens_Left = Valeurs(CInt((199 * Rnd()) + 1))
Coeff_Sens_Top = Valeurs(CInt((199 * Rnd()) + 1))
End Sub
Merci de m'avoir lu jusqu'ici et pour vos éventuels éclaircissements.
ucfoutu
Messages postés18038Date d'inscriptionlundi 7 décembre 2009StatutModérateurDernière intervention11 avril 2018211 3 oct. 2014 à 10:58
C'est plus complexe que cela, notamment dans le cas 1.
Le dé heurté ne peut continuer dans la même direction que s'il est heurté exactement à l'arrière par un dé allant exactement dans la même direction
Quelque soit d'ailleurs le cas de figure : deux paramètres entrent systématiquement en oeuvre :
1) un paramètre cinétique (la vitesse de chaque dé)
2) un paramètre dynamique, nécessairement dépendant en plus du poids des dés. Il y a dans tous les cas un calcul du vecteur résultant pour chaque dé.
C'est complexe.
pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 202414 3 oct. 2014 à 11:03
Il y a dans tous les cas un calcul du vecteur résultant pour chaque dé. C'est ce que j'essaye de réaliser.
Par contre, en fonction de la vitesse ok, cela me semble faisable. Mais en fonction du poids?
Ne peut-on pas ignorer ce facteur poids sous prétexte que les dés sont identiques?
Sinon, effectivement cela semble hyper compliqué à mettre en place et, là, le jeu n'en vaut pas la chandelle...
ucfoutu
Messages postés18038Date d'inscriptionlundi 7 décembre 2009StatutModérateurDernière intervention11 avril 2018211 Modifié par ucfoutu le 3/10/2014 à 11:19
Que les dés soient ou non identiques, ils ont un poids et ce poids intervient, comme la vitesse, dans le calcul.
On devrait d'ailleurs parler là de puissance, d'énergie, ...
je vais chercher un lien en parlant
________________________
Réponse exacte ? => "REPONSE ACCEPTEE" facilitera les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement répéter son contenu. Je n'interviend
ucfoutu
Messages postés18038Date d'inscriptionlundi 7 décembre 2009StatutModérateurDernière intervention11 avril 2018211 3 oct. 2014 à 11:20
pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 202414 3 oct. 2014 à 12:12
Oui...
Mais...
Je l'aime bien ce "mais".
Si on se base sur ces deux équations (approximation du choc entre deux boules de billard) :
ou m1 et m2 sont les masses respectives des boules, u les vitesses avant et v les vitesses après choc.
Si m1 = m2, on peut supprimer le poids de l'équation.
u1 + u2 = v1 + v2 -v + u = v - u
Donc, deux objets qui se choquent, ayant la même masse, repartent chacun avec leur vitesse initiale, si l'on considère le "coefficient de restitution" comme négligeable. On peut, nous, dans notre cas bien précis, si on le désire, définir un coefficient de restitution sous la forme d'une constante que l'on approximera pour obtenir un objectif purement "visuel".
Ceci est donc ok en ce qui concerne la vitesse.
Maintenant, si l'on s'attache à l'angle, il faut considérer le côté subissant l'impact comme étant un plan rigide. Les deux dés repartent alors avec un angle de réflexion égale à l'angle d'incidence. Un peu comme sur ce schéma :
pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 202414 3 oct. 2014 à 13:25
J'en arrive donc à ceci :
'Cas 1 : Les dés vont dans la même direction ou presque '=> le dé heurté : 'accélère légèrement ("coefficient de restitution"), 'change de direction mais pas de sens 'Angle????? '=> le dé qui heurte : 'ralentit ("coefficient de restitution"), 'change de direction et de sens suivant l'angle de réflexion (= angle d'incidence)
'Cas 2 : les dés vont dans des directions opposées '=> les deux dés 'ralentissent ("coefficient de restitution") 'changent de sens suivant l'angle de réflexion (= angle d'incidence)
Il me reste à comprendre le calcul de l'angle du dé heurté dans le cas 1.
Mais présentement, je ressens les effets d'une "sur-méningite" aiguë et j'ai un violent besoin de paracétamol. Donc, si vous le voulez bien, je vais arrêter pour l'instant et laisser passer le temps de la réflexion (ah non encore un terme en rapport avec les angles!).
Je reviendrais lire vos commentaires, n'ayez crainte...
pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 202414 6 oct. 2014 à 09:30
Bonjour,
Les nuits blanches du week end (merci Théo) portant conseil, il s'avère que l'on ne doit traiter le choc entre les dés qu'avec tous les paramètres nécessaires. Autrement dit, la vitesse, l'angle, la direction et la masse des dés sont des paramètres qui se doivent d'être pris en compte.
Par contre, je ne prendrais pas en compte la force du frottement de la piste ni l'effet du au "roulis" des dés.
Donc...
Il me faut me replonger dans mes manuels de physique du lycée et établir les formules utiles dans le calcul des angles et des vitesses de chaque dé après choc pour chacun des cas pouvant se produire.
Je reviendrais dès que j'aurais mis au point tout cela, c'est plus complexe que prévu, mais cette étude m'intéresse et pourra servir à d'autres... ou pas.
pijaku
Messages postés12263Date d'inscriptionjeudi 15 mai 2008StatutModérateurDernière intervention 4 janvier 202414 10 nov. 2014 à 08:09
Bonjour,
Non je n'ai pas laissé tomber, c'était juste plus complexe que prévu.
J'ai tout de même réussi à obtenir les formules nécessaires pour continuer ce projet. Toutefois, il faut savoir que pour un cas, il faudra définir un paramètre de sortie arbitrairement (3 équations à 4 inconnues).
Si vous êtes intéressés par ces formules et leurs "démonstrations", je me ferais une joie de vous les transmettre.
Dans le cas contraire, je reviendrais ici afin de vous faire part de l'avancée du code et des éventuelles difficultés que je rencontrerai assurément...
3 oct. 2014 à 11:03
C'est ce que j'essaye de réaliser.
Par contre, en fonction de la vitesse ok, cela me semble faisable. Mais en fonction du poids?
Ne peut-on pas ignorer ce facteur poids sous prétexte que les dés sont identiques?
Sinon, effectivement cela semble hyper compliqué à mettre en place et, là, le jeu n'en vaut pas la chandelle...