Rebond de boule de billard

Signaler
-
 Jacky -
Bonjour à tous ,

Une boule de billard qui part, rebondit et ... le programme s'arrête sans explication ! !
Si quelqu'un pouvait m'aider à comprendre pourquoi et éventuellement m'aider à corriger mon code ce serait super.

Ancien adepte de VB4, puis 5 puis 6, je ne suis pas passé au VB Net. Je crains que ce ne soit VB6 sur Windows 8.1 qui pose des problèmes de compatibilité.
Je voulais m'amuser à faire un jeu de billard mais quand la boule disparaît ou s'arrête et que le programme "plante", c'est rageant.

Je peux donner mon code ( en partie ou en entier) à qui serait tenté de m'aider.
Merci d'avance à celui qui me viendra en aide.
Jacques.

5 réponses

Messages postés
179
Date d'inscription
mardi 4 juillet 2017
Statut
Membre
Dernière intervention
12 mai 2020
5
Salut Jacky,
"Plante" ? … fermeture de la fenêtre sans erreurs ?
Désolé, impossible de t'aider.
Re bonjour Jeu du Taquin,
Je croyais avoir répondu et cliqué sur merci mais la page est revenue !
Donc quand je dis "plante", c'est VB6 qui ne répond plus. Arrive la page Fermer ou Attendre et je suis obligé de fermer VB6 !
J'ai beau essayer de mettre mes variables en "double" ou "currency" ou "variant", rien n'y fait.
Soit c'est un problème de temps d'affichage soit un problème de compatibilité ente V6 et W 8.1 !
Au cas où tu t'intéresserais davantage : sur ma form il y a une shape rectangulaire ( le tapis), et une shape ronde ( ma boule) que je lance sur une line que je peux orienter à partir du centre de la shape boule . Je la fait rebondir sur le bord de la shape tapis.
Elle rebondit bien entre 1 et 10 fois puis sans raison, s'arrête ou disparait avec l'apparition de l'icône "occupé" et en haut de ma form "VB6 ne répond plus" !

Voilà, je peux t'envoyer mon code si tu pense pouvoir le débuger.
Merci d'avance et bon dimanche,
Jacques
>
Messages postés
179
Date d'inscription
mardi 4 juillet 2017
Statut
Membre
Dernière intervention
12 mai 2020

Bonjour Jeu du Taquin,

Merci de ton aide.
Je crois que c'est ce que je venais de trouver : Je viens de diminuer le diamètre de ma boule et ça fonctionne un peu mieux.
Par contre, je n'ai jamais fait de mise à niveau sur mes connaissances et je ne comprends pas tout ton vocabulaire ( overflow, j'imagine que ça correspond à l'erreur de "pile", IDE?, snippet? . . c'est moins important !)
J'ai vu qu'il y avait un problème avec ma variable Att - qui pour moi était juste pour ralentir la boule après chaque rebond - car j'ai l'impression que parfois ma boule accélère au lieu de ralentir ! Ça je ne comprend pas pourquoi. Je n'ai aucun test sur Att !
J'ai fait arrêter ma boule à chaque rebond et afficher dans le label : V, H, et Rap et j'ai donc vu que la boule parfois rebondit au milieu du tapis !
Autre truc incompréhensible : la boule rebondit convenablement, s'arrête au milieu du tapis, (icône occupé !) et réapparaît au rebond suivant après quelques secondes ! Et ça, sans bloquer le programme !

Mais petit à petit je vais peut-être y arriver !

Sinon, tu parles de VB5 sur W 10 ! C'est-y possible ?
Je n'ai plus la possibilité d'installer VB5 ( c'est sur de vieilles disquettes ) j'ai essayé à partir d'une ancienne installation, j'ai une incompatibilité avec W 8.1 ( que j'avais eu aussi avec W 8) et même VB6 a du mal à être installé, j'ai des erreurs d'installation quand je tente d'y ajouter les mises à jours que j'ai.
Faut dire que mon disque d'installation de VB6 vient d'un disque piraté il y a au moins 15 ans.

Tout fonctionnait très bien avec W XP jusqu'aux premières mises à jours de W XP !
Après ça a été de pire en pire. J'avais eu juste envie de reprendre VB6.

Mais je digresse, pardon.
Merci encore et bonne journée,
Jacques
Messages postés
14669
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
5 juin 2020
143 > Jacky
Je n'ai pas plus regardé que cela, mais ton méthode de déplacement m'interroge, une méthode prise au hazard :
Public Sub SudOuest()
Att = Att + 10
For i = 1 To 500
    V = V - i * Rap: H = H - i
    If V + 240 > 10500 Then Rap = -Rap: NordOuest
    If H - 240 < 2500 Then Rap = -Rap: SudEst
affich
Next
End Sub


Pourquoi faire une boucle de 500 ?
Au lieu de mettre les valeurs en dur dans le code (2500, 10500, ...) préfères utiliser les constantes ou les données de objets (Shape.Width par exemple)

Ensuite sur la forme, on évite l'utilisation des :
If V + 240 > 10500 Then Rap = -Rap: NordOuest

Est moins lisible et maintenable que
If V + 240 > 10500 Then 
    Rap = -Rap
    NordOuest
End If


Ensuite, on limite la portée des variables autant que possible (ici "i" devrait être locale).
Et si tu termine ta boucle avant i=500, il est préférable de faire un "Exit For" ou "Exit Sub" selon le cas, cela rendra ton code moins sujet à des effets de bords.
>
Messages postés
14669
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
5 juin 2020

Bonjour

Super, j'ai de la chance de trouver votre aide.
Il y a plus de 15 ans que je n'ai plus utilisé VB6 et j'avoue que j'en ai oublié beaucoup, et comme MSDN ne veut plus s'installer ...!
Vous êtes trois maintenant à m'avoir répondu mais je ne sais pas trop me servir du forum et je vais faire un copier-coller pour répondre à tous et vous remercier.

Je vais tâcher de répondre dans l'ordre.
Pour le déplacement, je fais avancer ma boule par petits coups, pas à pas, j'ai juste utilisé l'équivalent de y = ax+b sauf que le b est connu grâce à l'emplacement de départ de la boule.
Tous mes calculs sont dépendants du repère qui a le coin haut gauche de la form en tant que 0 x et 0 y. C'est pour ça que je n'ai pas pris une picturebox qui m'empêchait d'utiliser une queue de billard.
Cette position de départ changeant à chaque rebond, j'ai trouvé plus simple d'utiliser la tangente pour calculer le point prochain.
Pour la lisibilté de mon code, moins j'ai de lignes mieux je vois car utiliser la barre défilante verticale est moins pratique que scinder la page de code en deux.
Je fais avancer ma boule par petits coups, pas à pas, j'ai juste utilisé l'équivalent de y = ax+b sauf que le b est connu grâce à l'emplacement de départ de la boule.
Tous les calculs sont dépendants du repère qui a le coin haut gauche de la form en tant que 0 x et 0 y. C'est pour ça que je n'ai pas pris une picturebox qui m'empêchait d'utiliser une queue de billard.
Ce départ changeant à chaque rebond, j'ai trouvé plus simple d'utiliser la tangente pour calculer le point prochain.
Mais je ne vois pas d'autres moyens pour faire avancer ma boule sur une droite du style ax+b.

Boucle de 500, j'ai commencé avec 500, j'y suis resté, il faudrait peut-être que j'augmente, ça éviterait peut-être que ma boule s'arrête sans prévenir. Je vais regarder ça.

Utilisation des constantes ou des propriétés gentes Shape.Width, ça c'est une bonne idée. Je vais suivre ton conseil.

Pour la lisibilté de mon code, moins j'ai de lignes mieux je vois car utiliser la barre défilante verticale est moins pratique que scinder la page de code en deux.
ainsi, je travaille sur une seule fenêtre.

Le Exit Sub en sortie de boucle c'est fait (je l'avais mis dans la partie avec la queue de billard mais pas avec la line L)

Pour ma vatiable Att, j'avais compris que c'était une histoire de capacité mais j'avais oublié de faire attention que l'Api Sleep était en Long ! Habitude perdue !

J'avais déjà corrigé les variables integer qui étaient insuffisantes. Le fait qu'elles soient en variant et soient plus lentes n'est pas trop gênant : si ça va trop vite on n'a pas le temps de voir le boule avancer !
Sinon, j'ai pas mal avancé :
La boule qui rebondit au milieu du tapis : résolu ( j'avais une erreur dans mes limites du tapis)
J'ai bloqué les rebonds à 5 et ça évite des bloquages ( sans doute dus à la mémoire pour l'affichage)
J'ai ajouté un son au moment du rebond.
J'ai supprimé le module, tout se fait sur la Form "Ecran" à l'ouverture.
J'ai diminué le code en utilisant les mêmes procédures ( N-O, S-E . . .) qu'on utilise la queue de billard ou pas. Maintenant on a le choix : Clic gauche sans la queue, Clic droit avec la queue)
On garde la possibilité d'affiner la direction de la queue de billard avec les flèches.
J'ai ajouté une boule rouge et une noire qui se posent au hasard sur le tapis.
Et j'en suis maintenant à regarder comment gérer les chocs de boules.
Ca va être un peu plus difficile !
Mais je vous tiendrai au courant.

Et je peux toujours vous redonner mon code si vous le désirez.

Il y a longtemps, j'avais regardé VB Net et j'avais baissé les bras, alors avec 10 ans de plus, j'ai bien peur d'être complètement dépassé !
Bonne journée à vous trois,
Jacques.
Messages postés
14669
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
5 juin 2020
143 > Jacky
>
Messages postés
14669
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
5 juin 2020

Bonjour, Il n'y a plus d'intervention, pour ma boule de billard mais je voulais vous remercier de votre aide. Je n'ai pas terminé mon jeu mais ça vient bien. Je voulais aussi vous signaler que pour que la boule ne s'affiche pas n'importe comment, il fallait juste ajouter un "Do Events" !
Maintenant elle rebondit bien, ralentit convenablement et je commence à gérer les chocs entre les boules.
Merci encore.
Jacques.
Messages postés
2154
Date d'inscription
samedi 11 janvier 2014
Statut
Non membre
Dernière intervention
5 juin 2020
109
Bonjour
Un "overflow" est un dépassement de capacité
La variable Att qui te sert pour faire une temporisation est de type Integer .
La plage de valeurs pour ce type va de - 32768 à + 32767 en VB 6 . hors dans le code tu augmente la variable Att ( à la ligne 64 de le form Ecran) . A un moment Att devient supérieure à +32767 et cela plante .
De plus l'API Sleep prend comme paramètre un Long : pourquoi donc Att est un Integer ?
Mets le en Long
Autre chose : évite le type Variant qui prend beaucoup de temps machine : préfères plutôt les types Integer, Long, Single ou Double
Les variables V, H et N devraient être des Integer
Quant à Rap 2 solutions
- Integer mais dans ce cas il faut utiliser la division entière
- Single mais pour l'utiliser il faut faire une conversion en Integer

Concernant VB 6 il n'est plus mis à jour depuis 1998 si ce ne sont les correctifs de sécurité qui ont perduré jusqu'en 2008 . J'ai utilisé VB 6 pendant une dizaine d'années et depuis bientôt 10 ans je suis passé à VB Net ( VB 6 ne fonctionnant plus avec Windows 8 et supérieur à moins de "bidouiller" d'après certains ) et j'en suis tout à fait satisfait .

Messages postés
2154
Date d'inscription
samedi 11 janvier 2014
Statut
Non membre
Dernière intervention
5 juin 2020
109
Bonjour
Un truc qui me chagrine ( je peux me tromper )
Prenons ce cas là
Public Sub SudOuest()
    Att = Att + 10
    For i = 1 To 500
        V = V - i * Rap: H = H - i
        If V + 240 > 10500 Then Rap = -Rap: NordOuest
        If H - 240 < 2500 Then Rap = -Rap: SudEst
    affich
    Next
End Sub


La boule va vers le SudOuest . On teste avec les 2 If si elle arrive sur le bord du tapis en bas ou à gauche . Si c'est en bas elle prend la direction NordOuest et si c'est à gauche elle prend la direction SudEst .
Mais pourquoi ne pas sortir de la boucle For de la Sub SudOuest au changement de direction ?
Moi je ferais ainsi
Public Sub SudOuest()
     Dim Exit as Integer
     Att = Att + 10
    Do
        V = V - 1 * Rap: H = H - 1
        If V + 240 > 10500 Then Exit = 1: Exit Do
        If H - 240 < 2500 Then Exit = 2: Exit Do
        affich
    Loop
    If Exit = 1 Then Rap = -Rap: NordOuest
    If Exit = 2 Then Rap = -Rap: SudEst
End Sub


Tant que la boule ne touche pas le bord du tapis on reste dans la boucle Do Loop
Si elle touche on sort de la boucle avec Exit = 1 ou 2 selon le bord touché et selon le bord on rentre dans la Sub NordOuest ou SudEst


Messages postés
14669
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
5 juin 2020
143
Je dirais même (comme les Dupon(t/d) :
Mettre en variable le décalage en X et Y (1 / -1) et quand tu touches un bord, tu changes le signe de la variable.
Comme ça même plus besoin de faire 4 procédures pour faire les 4 directions.
Messages postés
2154
Date d'inscription
samedi 11 janvier 2014
Statut
Non membre
Dernière intervention
5 juin 2020
109 >
Messages postés
14669
Date d'inscription
vendredi 14 mars 2003
Statut
Modérateur
Dernière intervention
5 juin 2020

Tu as tout à fait raison NHenry .
Il faut une variable de décalage sur X et une sur Y .
Dans ce cas il faut 4 IF pour gérer les 4 rebonds sur les bords .
Il y a de l'optimisation à faire à mon avis ( dommage que je ne programme plus en VB 6 : cela m'aurait bien tenté )
Cependant comment arrèter la boucle Do Loop ? Surement avec le ralentissement de la boule géré par le Sleep(Att) : quand Att attend une certaine valeur on sort du Do Loop
Messages postés
179
Date d'inscription
mardi 4 juillet 2017
Statut
Membre
Dernière intervention
12 mai 2020
5 >
Messages postés
2154
Date d'inscription
samedi 11 janvier 2014
Statut
Non membre
Dernière intervention
5 juin 2020

Salut,
Pour un jeu des "quatre bandes", un traitement linéaire est approprié, mais si une frappe occasionne le déplacement d'une autre boule, le problème se pose.
Même chose pour le sleep… qui bloque temporairement la scrutation du code.
Il serai plus judicieux d'utiliser un code de ralentissement fixe et jouer sur un facteur de ralentissement basé sur une variable de déplacement de 0 à 1.
Il sera donc difficile de faire des déplacements synchrones avec plusieurs boules avec ce type de code.
Bonjour ,
Une question bête : si je réponds avec le bouton rouge, est-ce que la réponse va à tout le monde ? Et dans le bas d'une réponse seulement à celui qui a répondu ? Et qu'est-ce que ça fait de cliquer sur "Merci" ?
Je mets mon adresse mail et je coche recevoir par mail mais je ne suis jamais averti par mail. Normal ?
Bref, merci à tout le monde.
Y a-t-il une différence entre sortir de la boucle par Exit Sub ou sortir par Exit Do ou Exit For ?
Je pense que l'idée des variables X et Y inversées au rebond mérite réflexion.
Ça vaut le coup de diminuer le nombre de procédures. Mais comme je n'ai pas envie de perdre ce que j'ai déjà fait, il va falloir refaire le programme !
J'ai essayé un choc entre deux boules, ça marche mais j'ai encore le problème de non affichage des boules: il y a un temps pendant lequel les boules sont immobiles puis réapparaissent au bon endroit à la fin de la boucle.
Je crois qu'effectivement c'est la variable Att de Sleep qui pose problème.
J'ai tenté de la faire augmenter au fur et à mesure de la boucle pour ralentir la boule mais c'est pire; surtout avec 2 boules !
Je vais regarder ce que ça peu donner si on l'inclue dans la boucle, elle serait sans doute vidée en sortant de la boucle.
C'est vrai qu'il faudrait trouver un autre moyen pour ralentir la boule. Est-ce qu'un Timer aiderait ? Je vais tâcher d'y réfléchir mais je vais manquer de temps ces jours-ci.
Quant à gérer le déplacement de 2 boules, il faut juste avoir une variable "Rap" pour chaque boule : j'ai expérimenté et ça marche mais c'est toujours le problème d'affichage - dû très probablement au "Sleep" - qui coince.

A plus et merci encore de votre aide.
Jacques.
Messages postés
2154
Date d'inscription
samedi 11 janvier 2014
Statut
Non membre
Dernière intervention
5 juin 2020
109
bonsoir Jacky
1) Le bouton rouge est une réponse générale au post d'origine . L'autre bouton est une réponse spécifique à un commentaire ou une réponse spécifique .
Tout le monde voit toutes les réponses sans exception ( faut parfois cliquer sur "Afficher les commentaires" pour voir la discussion entière : voir image ci-jointe)

2) Pour le sortie d'une boucle on privilégie le Exit For ou le Exit Do . Cependant si en sortie de boucle la procédure n'a plus de code on pourrait faire un Exit Sub mais cela revient à un Exit For ou Exit Do

Public Sub SudOuest()
     Dim Exit as Integer
     Att = Att + 10
    Do
        V = V - 1 * Rap: H = H - 1
        If V + 240 > 10500 Then Exit = 1: Exit Do ' Exit Do obligatoire car code en sortie de boucle
        If H - 240 < 2500 Then Exit = 2: Exit Do
        affich
    Loop
    If Exit = 1 Then Rap = -Rap: NordOuest
    If Exit = 2 Then Rap = -Rap: SudEst
End Sub

Public Sub SudOuest()
     Dim Exit as Integer
     Att = Att + 10
    Do
        V = V - 1 * Rap: H = H - 1
        If V + 240 > 10500 Then Exit Do ' Exit Do ou Exit Sub mais préférer Exit Do car boucle Do Loop
        If H - 240 < 2500 Then Exit Do
        affich
    Loop
End Sub

Public Sub TestFichier(Fichier as String)
    If System.IO.File.Exits(Fichier) = false then Exit Sub ' là c'est un Exit Sub obligatoire
    ' suite du code si le fichier existe
    ''''''
    ''''''   
End sub