Search code examples
javascripthtmlcanvasgame-physics

Movement multiple objects in canvas to x,y coordinate


I'm trying to use this "moveTo(x,y)" (by markE) function for multiple objects. This is what i've tried. And this is what I'm tried to do:

Calculating and moving object in woriking example look like this:

pct += .01;
// if we're not done, request another animation frame
if (pct < 1.00) {
    requestAnimFrame(animate);
}

// Calculate the next XY position
var nextX = startingX + dx * pct;
var nextY = startingY + dy * pct;

// Draw the shape
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(nextX, nextY, 40, 30);

And this, what I'm trying to do for multiple shapes:

var shapesLength = shapes.length;
for (var i = 0; i < shapesLength; i++) {// Loop through every object

var tmpShape = shapes[i];//selecting shape

    tmpShape.pct += .01;// increment pct towards 100%

    // if we're not done, request another animation frame
    if (tmpShape.pct < 1.00) {
        requestAnimFrame(animate);
    }

    // Calculate the next XY position
    var nextX = tmpShape.startingX + tmpShape.dx * tmpShape.pct;
        var nextY = tmpShape.startingY + tmpShape.dy * tmpShape.pct;

    // Draw the shape
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.fillRect(nextX, nextY, 10, 10);
};

But something goes wrong, and I'm don't know what.


Solution

  • What's going wrong is that requestAnimFrame is inside your loop.

    You'll want to call requestAnimFrame once outside your loop.

    Here is example code and a Fiddle: http://jsfiddle.net/m1erickson/HAbfm/

    <!doctype html>
    <html>
    <head>
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" />
    <script src="http://code.jquery.com/jquery.min.js"></script>
    
    <style>
        body{ background-color: ivory; }
        canvas{border:1px solid red;}
    </style>
    
    <script>
        $(function(){
    
            var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");
    
            window.requestAnimFrame = (function(callback) {
              return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
              function(callback) {
                window.setTimeout(callback, 1000 / 60);
              };
            })();
    
            var shapes=[];
            shapes.push({startX:10,  startY:10,  endX:140, endY:140, color:"red"});
            shapes.push({startX:280, startY:10,  endX:150, endY:140, color:"green"});
            shapes.push({startX:10,  startY:280, endX:140, endY:150, color:"blue"});
            shapes.push({startX:280, startY:280, endX:150, endY:150, color:"gold"});
    
            var pct=0.00;
            var fps = 60;
    
            animate();
    
            function animate() {
                setTimeout(function() {
    
    
                    // increment the percent (from 0.00 to 1.00)
                    pct+=.01;
    
                    // clear the canvas
                    ctx.clearRect(0,0,canvas.width,canvas.height);
    
                    // draw all shapes
                    for(var i=0;i<shapes.length;i++){
    
                        // get reference to next shape
                        var shape=shapes[i];
    
                        // note: dx/dy are fixed values
                        // they could be put in the shape object for efficiency
                        var dx=shape.endX-shape.startX;
                        var dy=shape.endY-shape.startY;
                        var nextX = shape.startX + dx * pct;
                        var nextY = shape.startY + dy * pct;                
                        var shape=shapes[i];
                        ctx.fillStyle=shape.color;
                        ctx.fillRect(nextX,nextY,7,7);
                    }
    
                    if(pct<1.00){requestAnimFrame(animate)};
    
    
                }, 1000 / fps);
            }
    
    
        }); // end $(function(){});
    </script>
    
    </head>
    
    <body>
        <canvas id="canvas" width=350 height=350></canvas>
    </body>
    </html>
    

    Here's an example of how to implement multiple waypoints for each shape:

    http://jsfiddle.net/m1erickson/UNjdC/

    [ Addition: explain how to create shapes and animate them ]

    You create and animate shapes in 3 steps:

    1. Create a polyline for one shape to follow during the animation.

    2. Push a new shape into the shapes[] array. Each shape object defines its own width, height, color and animation polyline from #1 above.

    3. After all new shapes are in the shapes[] array, call animate() to animate all shapes along their own polypaths.

    Here are the code bits for steps 1-3 above:

    // 1. create a polyline for one shape to follow
    
    points = pointsToSingleArray([
        {x:48,y:2},
        {x:48,y:365}
    ]);
    
    
    // 2. push the shape into the shapes array
    // 
    // a shape object contains width/height/color and the polyline
    
    shapes.push({
        width: shapeWidth,
        height: shapeHeight,
        waypoints: points,
        color: "red"
    });
    
    // 3. After you've pushed all desired shapes into the 
    //    shapes[] array, call animate() to start draw all
    //    objects along their own polyline paths.
    
    animate();