JeuWeb - Crée ton jeu par navigateur
Ball bounce résolu mais ne comprend pas... - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : Ball bounce résolu mais ne comprend pas... (/showthread.php?tid=7640)

Pages : 1 2 3


Ball bounce résolu mais ne comprend pas... - tatactic - 08-05-2016

J'avais un problème de rebond de balle dans une classe de test...
sans arrondir les valeurs de mes variables posx et posy, la balle ne prenait parfois pas le bon angle.

En arrondissant ces valeurs, plus de problème...
Quelqu'un a une idée de ce qui peut se passer lors du calcul du Math.cos() et Math.sin() en AS3 ???
Un problème de décimales???
Je comprends d'autant moins que je n'ai pas besoin d'arrondir la valeur de la rotation obtenue

Merci d'avance.
Nicolas.

Code :
        private function moveBall(e:Event):void{
            //speedx = Math.sin(deg2rad(rotation+90))*speed;
            //speedy = Math.cos(deg2rad(rotation+90))*speed;
            // IF the values are not round() -> Unknow Error
            speedx = Math.round(Math.sin(deg2rad(rotation+90))*speed);
            speedy = Math.round(Math.cos(deg2rad(rotation+90))*speed);
            if((this.x + this.radius + speedx >= this.stage.stageWidth)){
                bSound.play();
                rotation = rad2deg(Math.atan2(-speedy,-speedx));
            }
            if((this.y + this.radius + speedy >= this.stage.stageHeight)){
                bSound.play();
                rotation = rad2deg(Math.atan2(speedy,speedx));
            }
            if((this.x - this.radius + speedx <= 0)){
                bSound.play();
                rotation = rad2deg(Math.atan2(-speedy,-speedx));
            }
            if((this.y - this.radius + speedy <= 0)){
                bSound.play();
                rotation = rad2deg(Math.atan2(speedy,speedx));
            }
            this.x += speedx;
            this.y += speedy;
        }



RE: Ball bounce résolu mais ne comprend pas... - Xenos - 08-05-2016

Salut,

Sans une démo live et sans les valeurs précises qui entrainent un "pas le bon angle", je ne saurai répondre.
Il n'est pas à exclure que ton atan2 dégénère pour des valeurs de X proches de zéro (genre 1E-10). Sinon, ton rad2deg est peut-être en cause.


RE: Ball bounce résolu mais ne comprend pas... - tatactic - 08-05-2016

Argh, je pourrais te poster ma classe Main et la classe Ball en omettant le son afin que tu puisse y jeter un œil juste en faisant un copier-coller?
La classe Ball est un peu longue mais je pourrais l'expurger en virant la fonction moveBallDebug qui prend de la place.

Je ne sais pas si c'est permis de poster un code aussi long.

Sinon, là tout roule mais ça me gave d'avoir résolu le "hic" sans vraiment comprendre ce qui foirait...
Merci pour ta réponse (rapide qui plus est) en tout cas!!!
Bien à toi.
Nicolas

PS : le code avant et après bug se trouve sur https://stackoverflow.com/questions/37088746/ball-bounce-issue-in-as3

Le hic c'est qu'avec la réponse d'Atriace, ça ne marche que pour des angles droits, et je ne peux plus récupérer l'angle de collision exact.
Bon sinon il y aurait moyen que je poste ça sur pastebin.com/ au cas où tu n'as pas accès au post.

Tu as la bosse des Maths toi non?? Big Grin
Un pote de Zwetan???


RE: Ball bounce résolu mais ne comprend pas... - Xenos - 08-05-2016

Refais tes tests qui donnent la version "qui plante" et récupères les valeurs de speedX et speedY car je suis à peu près certains qu'à l'approche d'un 0 (ou d'un éventuel Pi/4), tu as une dégénérescence (type "return (x == 0 ? 1 : 1/x);"), soit dans ton code (rad2deg) soit dans le fonctionnement de atan2.

Et oui, j'ai parfois la réponse rapide, cela dépend si tu postes juste avant mes horaires de passage ou pas Tongue (mais le fait d'avoir un onglet JeuWeb ouvert en permance et d'y faire un tour régulièrement, cela doit jouer aussi ^^). Pourquoi tous les informaticiens n'auraient pas la bosse des maths? L'informatique n'est que de la logique, ce sont de pures maths... (c'est une vraie question en plus; j'ai jamais trop compris en quoi aimer les maths serait exceptionnel en informatique...)

[PS: Je ne vois pas qui est "Zwetan"]

PSS: heu, en fait, "rotation" sert à quoi dans ton contexte? Car là, tu vérifies si tu travers les murs à la prochaine étape de mouvement (note que sans avoir de DT, [aka DT=1 implicite], tu vas en chier mais c'est un test donc bon ok), si oui, tu sauves une valeur dans "rotation" et... tu fais quand même le mouvement :heu:


RE: Ball bounce résolu mais ne comprend pas... - tatactic - 09-05-2016

Ben j'ai refais comme hier mais ça ne m'avance pas...
Ce qui est le plus dingue c'est que parfois l'erreur se produit bêtement et à l'appel suivant la trajectoire est corrigée.
A d'autres moment ma balle va longer un bord puis (parfois) va reprendre une trajectoire cohérente.

Je ne sais pas si je récupère les bons paramètres... mais voici la sortie console peu avant l'erreur, suivie de la sortie quand la balle foire...

Je dois sans doute passer à côté d'une valeur, mais quand ça plante il y a tellement de sorties à une vitesse de 60fps, je te dis pas Sad

Bon j'imagine qu’arrondir mes valeurs de speedx et speedy sans savoir pourquoi ça marche nickel n'est pas une "bonne démarche". Smile

Dans ce cas ci, j'obtiens une erreur mais à l'appel suivant, c'est corrigé et ça roule:

Code :
speedx=-3.5355339059327373, speedy=-3.5355339059327386, rotation=-135
sin=-0.7071067811865475, cos=0.7071067811865476
Error: rotation = -135, modif = 2
    condit =
x<=ZERO
speedx=-3.5355339059327373, speedy=-3.5355339059327386, rotation=45.00000000000001
sin=0.7071067811865476, cos=-0.7071067811865475
y<=ZERO
speedx=-3.5355339059327373, speedy=-3.5355339059327386, rotation=-135
sin=-0.7071067811865475, cos=0.7071067811865476

    at com.display::Ball/moveBall()
speedx=-3.5355339059327373, speedy=3.5355339059327378, rotation=-45.00000000000001
sin=0.7071067811865475, cos=0.7071067811865476
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=-135
sin=-0.7071067811865475, cos=0.7071067811865476

Là par contre ça foire complet! :

Code :
speedx=-3.5355339059327373, speedy=3.5355339059327378, rotation=-45.00000000000001
sin=0.7071067811865475, cos=0.7071067811865476
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=-135
sin=-0.7071067811865475, cos=0.7071067811865476
speedx=-3.5355339059327373, speedy=3.5355339059327378, rotation=-45.00000000000001
sin=0.7071067811865475, cos=0.7071067811865476
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=45.00000000000001
sin=0.7071067811865476, cos=-0.7071067811865475
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=-135
sin=-0.7071067811865475, cos=0.7071067811865476
Error: rotation = -135, modif = 2
    condit =
y>=this.stage.stageHeight
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=45.00000000000001
sin=0.7071067811865476, cos=-0.7071067811865475
x<=ZERO
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=-135
sin=-0.7071067811865475, cos=0.7071067811865476

    at com.display::Ball/moveBall()
speedx=-3.5355339059327373, speedy=3.5355339059327378, rotation=135
sin=-0.7071067811865475, cos=-0.7071067811865477
speedx=-3.5355339059327373, speedy=3.5355339059327378, rotation=-45.00000000000001
sin=0.7071067811865475, cos=0.7071067811865476
Error: rotation = -45.00000000000001, modif = 2
    condit =
y>=this.stage.stageHeight
speedx=-3.5355339059327373, speedy=3.5355339059327378, rotation=135
sin=-0.7071067811865475, cos=-0.7071067811865477
x<=ZERO
speedx=-3.5355339059327373, speedy=3.5355339059327378, rotation=-45.00000000000001
sin=0.7071067811865475, cos=0.7071067811865476

    at com.display::Ball/moveBall()
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=45.00000000000001
sin=0.7071067811865476, cos=-0.7071067811865475
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=-135
sin=-0.7071067811865475, cos=0.7071067811865476
Error: rotation = -135, modif = 2
    condit =
y>=this.stage.stageHeight
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=45.00000000000001
sin=0.7071067811865476, cos=-0.7071067811865475
x<=ZERO
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=-135
sin=-0.7071067811865475, cos=0.7071067811865476

    at com.display::Ball/moveBall()
speedx=-3.5355339059327373, speedy=3.5355339059327378, rotation=135
sin=-0.7071067811865475, cos=-0.7071067811865477
speedx=-3.5355339059327373, speedy=3.5355339059327378, rotation=-45.00000000000001
sin=0.7071067811865475, cos=0.7071067811865476
Error: rotation = -45.00000000000001, modif = 2
    condit =
y>=this.stage.stageHeight
speedx=-3.5355339059327373, speedy=3.5355339059327378, rotation=135
sin=-0.7071067811865475, cos=-0.7071067811865477
x<=ZERO
speedx=-3.5355339059327373, speedy=3.5355339059327378, rotation=-45.00000000000001
sin=0.7071067811865475, cos=0.7071067811865476

    at com.display::Ball/moveBall()
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=45.00000000000001
sin=0.7071067811865476, cos=-0.7071067811865475
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=-135
sin=-0.7071067811865475, cos=0.7071067811865476
Error: rotation = -135, modif = 2
    condit =
y>=this.stage.stageHeight
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=45.00000000000001
sin=0.7071067811865476, cos=-0.7071067811865475
x<=ZERO
speedx=3.5355339059327373, speedy=3.5355339059327378, rotation=-135
sin=-0.7071067811865475, cos=0.7071067811865476

    at com.display::Ball/moveBall()



RE: Ball bounce résolu mais ne comprend pas... - Xenos - 09-05-2016

A mon avis, t'as un problème algorithmique car tu fais:

T'as un défaut d'algorithme, en effet:
• Si (Y + rY + vY) > maxY => tourner la bille (= la faire rebondir) mais le déplacement se fait encore par rapport à la valeur non-tournée (bille non-rebondie), donc la bille traverse légèrement le mur, et sa vitesse Y s'inverse
• Au tour de boucle suivant, tu refais un calcul et si la vitesse (inversée précédemment) ne permet pas de revenir dans la zone de jeu (possible à cause du epsilon machine), alors tu ré-inverses la vitesse
• Et ainsi de suite: si la bille sort du plateau, elle peut ne jamais y revenir avec une vitesse qui s'inverse à chaque tour de boucle

J'upload l'exemple une fois rentré chez moi.

PS: Ah ouais, ok... je comprends mieux le "+90"... t'empiles les couches de complexification: pourquoi inverser sin() et cos() dans le calcul de X et de Y (ce qui t'oblige à parachuter un +90 ailleurs)?


RE: Ball bounce résolu mais ne comprend pas... - tatactic - 09-05-2016

Ah ben oui tiens , je serais content de voir du code propre, car là je ne sais pas, je ne sais plus, je suis perdu...
Et aucune envie de faire comme l'oiseau (si tu vois à quelle chanson je fais référence).
Quand les neurones sont grillées c'est irrémédiable ou il est possible de recréer des connexions??? Smile

Si tu étais psy au lieu de pondre du code j'aurais claqué un sacré pognon chez toi LOL Big Grin


RE: Ball bounce résolu mais ne comprend pas... - Xenos - 09-05-2016

Je peux t'ouvrir un cabinet de psy dédié si tu a du pognon à claquer Confusediffle:


RE: Ball bounce résolu mais ne comprend pas... - tatactic - 09-05-2016

Hum... Pour le moment il faudrait pratiquer un tarif social Big Grin
"Avant d'être fort comme un chêne, il faut être con comme un gland"
Arf, je vais pouvoir en ch... avec tes liens!!! Smile
Au moins mes anciens profs m'adorent, comme mes employeurs qui me gardent malgré tout sous mon statut CDI.
Dans la vie il y a des gens sympas (même en Belgique) Wink
Merci pour les liens!!!


RE: Ball bounce résolu mais ne comprend pas... - Xenos - 11-05-2016

Bon, je vous rassure: j'étais rentré chez moi (plusieurs foi) depuis mon post d'il y a 2 jours... J'avais juste oublié de déployer mon Test&Tries:

Bouncing Ball

Je n'ai pas réussi à retrouver un cas limite, mais on voit, sur certaines frames, que la balle a traversé le mur. Quand la balle traverse le mur sur une frame F, si jamais elle ne revient pas sur le terrain à la frame suivante F+1 (à cause des arrondis internes des double/float ou du calcul de atan2, bref, à cause du epsilon machine) alors la vitesse de la balle sera ré-inversée, et elle retournera traverser les murs (encore plus loin que la 1ere fois). De fil en aiguille, la balle se tire de la zone de jeu.
La checkbox "fix bounce calculation" va re-calculer la vitesse de la balle après les "if" de tes rebonds, ce qui lui évitera de traverser les murs.
On peut quand même avoir un autre cas limite: si la vitesse de la balle dépasse la taille de la zone de jeu.