Pong Animation Instructions

Follow these instructions to add animation functionality to your Pong game.

Example file in StudentDrive/Handouts/Programming/anim_basic.html

Add this code to top of script area

// **********************************************************************************
// Sprite class slightly modified from: http://jlongster.com/Making-Sprite-based-Games-with-Canvas
function Sprite(imageSource, frameWidth, frameHeight, speed, frameSequence)
{
    this.imageSource = new Image();
    this.imageSource.src = imageSource;
    this.frameWidth = frameWidth;
    this.frameHeight = frameHeight;
    this.speed = speed;
    this.frameSequence = frameSequence;

    this.currentSpeed = 0;
    this.onceThenGone = false;
    this.loop = false;

    this.currentFrame = 0;
};

Sprite.prototype =
{
    update: function(dt)
    {
        this.currentFrame += this.currentSpeed * dt;
    },

    playAnimation: function()
    {
        this.currentSpeed = this.speed;
    },

    render: function(ctx)
    {
        var frame;

        if (this.currentSpeed > 0)
        {
            var max = this.frameSequence.length;
            var idx = Math.floor(this.currentFrame);
            frame = this.frameSequence[idx % max];

            if (!this.loop && idx >= max)
            {
                this.currentSpeed = 0;
                this.currentFrame = 0;
            }

            if (this.onceThenGone && idx >= max)
            {
                this.done = true;
                return;
            }
        }
        else
        {
            frame = 0;
        }

        var u = 0;

        u += frame * this.frameWidth;
       
        ctx.drawImage(this.imageSource, u, 0, this.frameWidth,
                            this.frameHeight, 0, 0, this.frameWidth, this.frameHeight);
    }
};

// Preload Images -----------------------------------------

this.addEventListener("DOMContentLoaded", preloadImages, true);

var loadedImages = 0;
var imageArray = new Array("img/ball_sheet.png", "img/test1.jpg");

function preloadImages(e) {
    for (var i = 0; i < imageArray.length; i++) {
        var tempImage = new Image();
       
        tempImage.addEventListener("load", trackProgress, true);
        tempImage.src = imageArray[i];
    }
}

function trackProgress() {
    loadedImages++;
   
    if (loadedImages == imageArray.length) {
        setup();
    }
}
// --------------------------**

// **********************************************************************************

In 'Preload Images' section, populate imageArray with your image file paths

// Preload Images -----------------------------------------

this.addEventListener("DOMContentLoaded", preloadImages, true);

var loadedImages = 0;
// add image file paths to the array constructor here
var imageArray = new Array("img/my_sprite_sheet.png", "img/test1.jpg");

function preloadImages(e) {..........

Declare global variable for your sprite (up where all your other variables are declared)

var mySpriteName;

Change window.onload to setup

Instead of saying window.onload = function(){....

You will declare a 'setup' function

function setup(){...
// keep all the code inside the brackets
...
...
}

Initialize your Sprite object inside the setup() function

// Sprite parameters:      imageSource, width, height, speed, frameSequence
mySpriteName = new Sprite("img/my_sprite_sheet.png", 32, 32, 60, [0,1,2,3,4,5,4,3,2,1,0]);

If this Sprite needs to loop its animation, set that property now

mySpriteName.loop = true;

Remove the setInterval() function

Update lastTime variable and call main()

lastTime = Date.now();

main();

Your setup() function should look similar to this now:

function setup() 
{
        
    console.log("Init");
    
    canvas = document.getElementById('gameCanvas');
    canvasContext = canvas.getContext('2d');
                
    // images -----------------------------------------

    // Sprite parameters:      imageSource, width, height, speed, frameSequence
    mySpriteName = new Sprite("img/my_sprite_sheet.png", 32, 32, 60, [0,1,2,3,4,5,4,3,2,1,0]);

    lastTime = Date.now();

    main();
}

Create your main function (below init()), which will now do the main loop instead of setInterval()

This is what it should look like:

var lastTime;
function main()
{
    var now = Date.now();
    var dt = (now - lastTime) / 1000.0;

    moveEverything(dt);
    drawEverything();

    lastTime = now;
    requestAnimationFrame(main);
}

You are now passing the dt variable into your moveEverything() function, make sure to add that as an argument now at your moveEverything() definition

function moveEverything(dt)
{
    ...
    ...
    ...
}

At the end of moveEverything(), call update() on your Sprite object, and pass dt into it

function moveEverything(dt)
{
    ...
    ...
    ...
    mySpriteName.update(dt);
}

This is how you will now draw the Sprite (in your drawing function)

// ball ---------------------------------------------------
    canvasContext.save();
    canvasContext.translate(ballX, ballY);
    ballSprite.render(canvasContext);
    canvasContext.restore();

To trigger the animation, find where in your code the animation should start playing, and call the playAnimation() function on the Sprite object

mySpriteName.playAnimation();

As an example, I am triggering my ballSprite animation when it hits the right side of the canvas

if (ballBB_x + ballBB_width >= canvas.width)
    {
        dx *= -1;
        ballSprite.playAnimation();
    }