Hi there, I am reading a javascript book and I got a little stuck when analysing one of the scripts built as test. This is the one I am talking about http://aharrisbooks.net/jad/chap_08/bounce.html
I went through it but I don’t seem to be able to understandexactly the way it works.
Here’s the code.
html:
view-source:http://aharrisbooks.net/jad/chap_08/bounce.html
movement.js:
http://aharrisbooks.net/jad/chap_08/movement.js
bounce.js
http://aharrisbooks.net/jad/chap_08/bounce.js

Let’s see if I understand it correctly.
The <body onload = "init()"> in the html file calls the init() function in bounce.js because if you duplicate a function, the browser interprets only the last one it reads and in fact there is another init() function in movement.js which the script skips.
So in bounce.js the function init() calls animate() is called once every 0.05 seconds. Animate() calls moveSprite(deltaX, deltaY) . This function is contained in movement.js, so let’s just do a few rounds.
DeltaX and DeltaY are respectively 5 and 3, so the first run is moveSprite(5, 3) . As per the code in movement.js before checkBounds() is called - incidentally checkBounds() will call the function in bounce.js and not the one in movement.js - x = 105 and y =103 so we change the left and top values the sprite moves to that position. So far so good.
Now let’s run the function one last time, to see how the ball bounces back. Say that x = 365 now. So, Animate() calls moveSprite(deltaX, deltaY) , we run

x = parseInt(sprite.style.left);
y = parseInt(sprite.style.top);
x += dx;
y += dy;

and x, which is 365 should becomes 370 (365+5). checkBounds() is called and x>MAX_X is true – assume all the other conditions are false - so deltaX = -5. Control returns here

sprite.style.left = x + "px";
sprite.style.top = y + "px";

but x is still 370 so the left value is 370px?! I just don’t get how x becomes 365 again (370-5)
I got a little lost...

Violet, you're not lost at all, because everything you observe is correct.

checkBounds() effects direction reversals by negating the deltas but the current iteration's deltas have already been applied, immediately before checkBounds() was called in moveSprite() (though the DOM has not yet been updated). The deltas are not re-applied after checkBounds() returns, at least not in the current iteration. The first application of any direction reversal (negated delta) occurs at the next iteration.

In other words, at each iteration, moveSprite() does two things:

  • applies the current deltas and displays the sprite in its new position
  • calls checkBounds() to adjust, when necessary, the deltas for the next iteration.

The position of the statement checkBounds(); within moveSprite() is slightly confusing. Try moving the statement to the very bottom of moveSprite() and it should be much clearer that it has no effect until the next iteration.

Airshow

ahhhhh, thanks Airshow, that's much better! I have also run the code through Firebug (I know, I should have done it before posting this, sorry!:$) so I had a look at the code in action. I didn't realise checkBound() was working on the following iteration, I guess you're right, it is in an awkward position, so I moved it down at the end and it makes much more sense. I also had some problems understanding why checkBound() was set up like this

function checkBounds(){
  //bounce
  if (x > MAX_X){
    deltaX = -5;
  } // end if
  if (x < MIN_X){
    deltaX *= -1;
  } // end if
  if (y > MAX_Y){
    deltaY *= -1;
  } // end if
  if (y < MIN_Y){
    deltaY *= -1;
  } // end if
} // end function

I have now realized that when deltaX becomes -5, it stays -5 till it is changed back to +5 by this if (x < MIN_X){ deltaX *= -1; , whereas at the beginning I thought that deltaX becomes -5 only for 1 iteration...

Violet,

I'm not sure why the if (x > MAX_X) condition is coded differently from the other three conditions.

This would be more logical:

function checkBounds(){
  //bounce
  if (x > MAX_X){
    deltaX *= -1;
  } // end if
  if (x < MIN_X){
    deltaX *= -1;
  } // end if
  if (y > MAX_Y){
    deltaY *= -1;
  } // end if
  if (y < MIN_Y){
    deltaY *= -1;
  } // end if;:
} // end function

Or, in a lot less lines:

function checkBounds(){
  if (x > MAX_X || x < MIN_X){ deltaX *= -1; }
  if (y > MAX_Y || y < MIN_Y){ deltaY *= -1; }
}

Airshow

yes Airshow, that's much more logical. I guess it was coded differently because the author wanted to show another way of doing things.
Thanks for making things clearer!!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.