Mehdi
Mehdi

Reputation: 713

One function to rule them all

I am coding an application which displays balls obeying certain laws of physics. So I have a Ball Object, and a path prototype. This path prototype calculates the coordinates of the ball at any given moment and draws it, that goes kinda like this :

Ball.prototype.path = function(v) {
modifying the ball coordinates...
ctx.arc(....);
(other canvas stuff)}

If I want to display an animation of the ball, I do this:

var ball1 = new Ball(...);
var ball2...
function loop () {
ctx.beginPath(); // The balls won't show up if I begin and close the Path in path(), I don't know why...
ball1.path();
ball2...
ctx.closePath();
};
setInterval(loop, 0.0015);

But I want to add a button which adds and displays balls. So I'm looking for a function which executes these commands to any ball added.

It's a little bit tricky, because it has to:

  1. Create and name a new variable.
  2. Execute path() according to that name.
  3. All of that, in the same loop function so I can make a setInterval later.

EDIT: FIXED @Frederik @Doorknob I've used a BallArray:

var BallArray = new Array(); i=0; function AddBallonClick() { i++; BalleArray.push(i) }; function loop() { for (var i=0;i<BalleArray.length;i++) { ctx.beginPath(); var ball = new Ball(0, 0, 40); ball.path(); ctx.closePath(); }; }; setInterval(loop, dt);

But I want to name the new variables ball_i, ie: ball_1, ball_2..., and I don't know how to. The script doesn't seem to be working even when I add the ball just once, so that's a problem too...

EDIT 2: FIXED

Also, I want to set an initial speed to every new ball, typically I do this:

   ball.v = new V(...);

But now that I have an array, I added this to the loop, but it doesn't work...:

   balles[i].v = new V(...)

EDIT 3:

I have another problem, whenever I click the button, a ball is not added and drawn, but instead the animation "replays". It seems that javascript can't draw balls at the same time with my kind of code:

    function loop()
    {
    for(var i = 0; i < balls.length; i++) {
        ctx.beginPath();
        balls[i].path();
        ctx.closePath();
    }
};
    setInterval(loop, dt);

EDIT: ALL FIXED I've solved the last problem you just have to put the ctx.clearRect(0, 0, width, height) in the loop function but before the for(var i=0...).

Thanks to all of you :) !

Upvotes: 2

Views: 279

Answers (1)

icktoofay
icktoofay

Reputation: 129011

As mentioned in the comments, the answer is arrays. You don't seem to quite understand them, so here's a quick overview. An array is sort of a list of objects. In your case, you probably want a list of Balls. You can initialize it like this:

var balls = [];  // [] is about the same as new Array(), but more concise

To add a new ball to it, you can use push, passing it the ball:

balls.push(new Ball(/* ... */));

(You could, of course, pass it an already-existing ball, too:)

var ball = /* obtain ball from elsewhere */;
balls.push(ball);

You do seem to understand how to loop through the arrays, but not how to get the values as you loop through it. To loop through the array, you use a for loop:

for(var i = 0; i < balls.length; i++) {
    // ...
}

Obviously, i will be an integer from 0 to balls.length. We can't do much with the number on its own, though; what we really want is the ball at that index in the array. You can do this by indexing the array. That would look like this:

var ball = balls[i];

Now ball contains the ball at position i in the balls array, and you can do whatever you want with it from there. In your case, you probably want to call path on it:

// If you've stored it into a variable as above:
ball.path();
// Or more concisely without having to store it into a variable:
balls[i].path();

With arrays, there is no need for variables named, e.g., ball_1, ball_2, etc. Instead, you just have an array, balls, and index it, e.g., balls[0], balls[1], etc.

Upvotes: 3

Related Questions