ClanKiller.com
http://forums.clankiller.com/

Javascript programming - the bouncing ball
http://forums.clankiller.com/viewtopic.php?f=24&t=3662
Page 1 of 1

Author:  Satis [ Tue Sep 28, 2010 8:41 pm ]
Post subject:  Javascript programming - the bouncing ball

I did this bouncing ball simulation (with clouds and gravity) using just javascript. I also played with CSS3, so this doesn't work well on IE. It's fine on Firefox, Chrome, and should be fine on Safari and any webkit browser.

http://clankiller.com/stuff/bounce/

The clouds are dynamically generated objects the grab a random height, random speed and random direction, then fade in, scroll until they hit the end of the screen, and fade out. The master script controls the fade out, destroys the cloud object when it's done, and creates a new one. Fun stuff, but not actually all that hard.

The bouncing ball was a lot harder. Be advised you can click-grab the ball and throw it. That part was a lot of fun. Not so much fun was calculating the arc and speed of the ball. I hacked a gravity approximation, but it's poorly implemented... I basically subtract from the speed due to gravity, rather than just the vertical component of the speed. Trying to fix that has mostly caused me to just violate the laws of physics with flubber-like balls that gain speed instead of lose it. :roll: Oh, and if you throw the ball and it gets "stuck" on your pointer, just left click on the ball to drop it, then right-click on the background. I don't know why it happens, I really don't, or I'd fix it.

So, anyway, anyone that actually read this, please play with the page and enjoy. If you want to try your hand at fixing the physics, this is why it's in the programming forum. Here's the gravity/physics code for the ball object. This code block is executed every 25ms.

Most of the below should be fairly intelligible. that.speed refers to the speed of the ball object. that.vector is the vector of the ball object... more correctly it's the angle, with 0 being right, 90 being up, 180 being left, and 270 being down. tools.getlocation is from my javascript tools script, and it just gets the top and left of the object in question in pixels. gravity is a constant that I believe I have set to 9.8. There's also some code in there to make the ball flex when it hits the ground, but you can barely see it, so I'm not sure it's worth the code. *shrug*

Code:
    this.update = function(){
        if(that.speed > 400)
            that.speed = 400;    //sanity check on speed
        //calculate new location based off vector and speed
        var location = tools.getLocation(that.element);
        var rVector = that.vector * Math.PI / 180;
        var sinVector = Math.sin(rVector);
        if(that.speed != 0){
            location['top'] -= Math.round(that.speed/10 * sinVector);
            location['left'] += Math.round(that.speed/10 * Math.cos(rVector));
        }
        /*var vertical = that.speed * sinVector;
        vertical = (vertical > 0)? vertical - gravity : vertical + gravity;       
        that.speed = (vertical == 0)? gravity : Math.round(vertical / sinVector);*/
       
        that.element.style.top = location['top'] + 'px';
        that.element.style.left = location['left'] + 'px';
       
        //change speed due to gravitational influence
        if(that.vector > 180){
            //falling down, so add to speed
            that.speed += gravity;
        }
        else if(that.vector < 180){
            //going up, so subtract from speed
            that.speed -= gravity;
        }
       
        //change vector due to gravitational influence
        if(that.vector < 80 || that.vector > 280)
            that.vector -= 2;
        else if(that.vector < 85 || that.vector > 275)
            that.vector -= 1;
        else if(that.vector < 260 && that.vector > 100)
            that.vector += 2;
        else if(that.vector < 265 && that.vector > 95)
            that.vector += 1;
           
        //fix out-of-bounds vectors
        while(that.vector < 0)
            that.vector += 360;
        while(that.vector > 360)
            that.vector -= 360;

        var el = tools.getSize(that.element);
        //detect if there's a ground collision
        var groundDimensions = tools.getSize(that.ground);
        if(el['top'] + el['height'] > groundDimensions['top'] && that.vector > 180){
            //if ground collision, set ball distortion
            that.element.style.height = groundDimensions['top'] - el['top'] + 'px';
            //reverse vector
            var reference = 270 - that.vector;
            that.vector = 90 + reference;
            that.speed -= groundCollisionSpeedReduction;
        }
       
        //check for left wall collision
        if(el['left'] <= 0 && that.vector > 90 && that.vector < 270)
            that.vector = (reference > 0)? 180 + that.vector : 180 - that.vector;
       
        //check for right wall collision
        if(el['left'] + el['width'] > groundDimensions['width'] && (that.vector < 90 || that.vector > 270)){
            var reference = (that.vector < 90)? that.vector : (360 - that.vector) * -1;
            that.vector = (that.vector < 90)? 180 - that.vector : 180 - that.vector;
        }
       
        //fix ball disortion after rebound
        if(el['height'] != el['width']){
            that.element.style.height = (el['top'] + el['width'] > groundDimensions['top'])? groundDimensions['top'] - el['top'] + 'px' : el['width'] + 'px';
        }
       
        //subtract drag from speed
        if(that.speed > 0)
            that.speed -= drag/10;
        else if(that.speed <= 0){
            that.speed = 0;
            if(that.vector < 180 && that.vector > 90){
                var reference = 180 - that.vector;
                that.vector = 180 + reference;
            }
            else if(that.vector <= 90){
                var reference = 90 - that.vector;
                that.vector = 270 + reference;
            }
        }
    }


I'm interested in any feedback, be it programming or physics related... or anything else, really. I am pretty much done messing with this, but that doesn't mean I won't make a similar physics experiment in the future and I could well benefit from good advice.

Author:  Rinox [ Wed Sep 29, 2010 2:32 am ]
Post subject:  Re: Javascript programming - the bouncing ball

I can't click/grab the ball? I'm at work on IE though.

Mmm sounds like this is more of a physics than programming conundrum, so something I may actually be able to say something slightly useful about. ;) But for the real deal, I hope J drops in since he's a trained physicist and not a poorly self-educated theoretical astrophysics amateur like myself. :roll:

Also, wouldn't it be more appropriate to make the 'ball' a circle instead of a square, aesthetically speaking?

Author:  Mole [ Wed Sep 29, 2010 8:14 am ]
Post subject:  Re: Javascript programming - the bouncing ball

The ball is a circle, maybe it's just IE.

Anyway had a play and obviously with the little coding I do know I'm completely useless. Suffice it to say that there are obvious things the ball does which are not physically correct, but I can't knock you because I can't do any better (Or even close!).

Good work man :)

Author:  Rinox [ Wed Sep 29, 2010 12:23 pm ]
Post subject:  Re: Javascript programming - the bouncing ball

Oh yeah, just tried it at home here on firefox, much better. :lol: It was like a depressing brown smudge with a bouncing square I couldn't "drag" in IE, go figure. :)

Ball physics are clearly funky when it comes down from apex yes...slows down every time.

Author:  Satis [ Wed Sep 29, 2010 6:07 pm ]
Post subject:  Re: Javascript programming - the bouncing ball

Yea, doesn't work in IE. I use CSS 3 to make the ball and clouds have their circular edges, and IE just doesn't do it. So I didn't even bother testing IE for the rest of it. BTW, Chrome has much better performance than FF.

Anyway, yea, basically I just have the angle and speed, and I subtract gravity from speed. But that only works well if the ball is going up or down... if it's sideways at an angle, you can see it basically stop as it hits an apex.

Oh well. I doubt I'll go back unless someone gives me a big reason to. I'm now working on something new. :roll:

Page 1 of 1 All times are UTC - 6 hours
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/