1
\$\begingroup\$

I am trying to start making a simple game using HTML5 with a canvas and some JS. I have a player whose movement I am comfortable with, but the rate at which the player animates when it moves is too fast.

Now the way I'm handling that animation ATM is that it does not use one image that gets positioned differently depending on movement, rather it alternates between two different images depending on which direction it is moving. It should become a bit more clear in the code. I imagine part of the solution might be handling the movement vs the alternating images in different sections, but I admit I'm not too familiar with this and its the first time I've made such a game.

$(document).ready(function(){

    //****************************************************//
    //******   Create and get Canvas and its info  *******//
    //****************************************************//
    var canvas = $("#canvas")[0];
    var ctx = canvas.getContext("2d");
    var w = $("#canvas").width();
    var h = $("#canvas").height();

    var score = 0;

    //the background, loaded and drawn onto canvas              
    var FPS = 30;
    setInterval(function() {

        draw();
        update();

    }, 1000/FPS);


    //****************************************************//
    //**********  Load the images        *****************//
    //****************************************************//

    //not moving:
    var img = new Image();
    img.src = "still.png";

    //primary frames
    var img_down = new Image();
    img_down.src = "down.png";

    var img_up = new Image();
    img_up.src = "up.png";

    var img_left = new Image();
    img_left.src = "left.png";

    var img_right = new Image();
    img_right.src = "right.png";

    //secondary frames
    var img_down_b = new Image();
    img_down_b.src = "down_b.png";

    var img_up_b = new Image();
    img_up_b.src = "up_b.png";

    var img_left_b = new Image();
    img_left_b.src = "left_b.png";

    var img_right_b = new Image();
    img_right_b.src = "right_b.png";        


    //****************************************************//
    //**********  Defining the Player object *************//
    //****************************************************//
    var player = {
        color: "#ff5050",
        //randomly place the player into the game field, within boundaries
        x: Math.floor((Math.random() * 991) + 1),
        y: Math.floor((Math.random() * 511) + 122), 
        width: 32,
        height: 32,
        direction: 'S', 
        isMoving: false,
        //Frame system: alternate along the following system:
        //  down:1      down_b:5
        //  up:2        up_b:6
        //  left:3      left_b:7
        //  right:4     right_b:8
        //  0 for stillness, or non-moving
        frame: 0,
        draw: function() {
                if (this.isMoving) {
                if (this.direction == 'S') {

                    if (this.frame == 1) {
                        ctx.drawImage(img_down, this.x, this.y, this.width, this.height);

                    }
                    else if (this.frame == 5) {
                        ctx.drawImage(img_down_b, this.x, this.y, this.width, this.height);

                    }
                }
                else if (this.direction == 'N') {

                        if (this.frame == 2) {
                        ctx.drawImage(img_up, this.x, this.y, this.width, this.height);

                    }
                    else if (this.frame == 6) {
                        ctx.drawImage(img_up_b, this.x, this.y, this.width, this.height);

                    }
                }
                else if (this.direction == 'E') {

                        if (this.frame == 4) {
                        ctx.drawImage(img_right, this.x, this.y, this.width, this.height);

                    }
                    else if (this.frame == 8) {
                        ctx.drawImage(img_right_b, this.x, this.y, this.width, this.height);

                    }
                }   
                else if (this.direction == 'W') {

                        if (this.frame == 3) {
                        ctx.drawImage(img_left, this.x, this.y, this.width, this.height);

                    }
                    else if (this.frame == 7) {
                        ctx.drawImage(img_left_b, this.x, this.y, this.width, this.height);

                    }
                }
            } else {
                ctx.drawImage(img, this.x, this.y, this.width, this.height);
            }
        },

        move: function() {
            player.draw();
                if (!keydown.left && !keydown.right && !keydown.up && !keydown.down) {
                    player.color = "#ff5050";
                this.isMoving = false;
            } else {
                this.isMoving = true;
            }

            //simple moves: horizontal, vertical
            if (keydown.left) {
                if (player.frame != 3) player.frame = 3;
                else player.frame = 7;
                player.direction = 'W';
                player.x -= 3;
                player.color = "red";
            }

            if (keydown.right) {
                if (player.frame != 4) player.frame = 4;
                else player.frame = 8;
                player.direction = 'E';
                player.x += 3;
                player.color = "blue";
            }

            if (keydown.up) {
                if (player.frame != 2) player.frame = 2;
                else player.frame = 6;
                player.direction = 'N';
                player.y -= 3;
                player.color = "green";
            }

            if (keydown.down) {
                if (player.frame != 1) player.frame = 1;
                else player.frame = 5;
                player.direction = 'S';
                player.y += 3;
                player.color = "yellow";
            }

            //dual keypress up and down, left and right
            if (keydown.down && keydown.up) {
                player.color = "#ff5050";
            }

            if (keydown.left && keydown.right) {
                player.color = "#ff5050";
            }


            //combined moves: diagonal
            //up and left
            if (keydown.left && keydown.up && !keydown.right && !keydown.down) {
                player.color = "grey";
            }
            //up and right
            if (keydown.right && keydown.up && !keydown.left && !keydown.down) {
                player.color = "black";
            }
            //down and left
            if (keydown.left && keydown.down && !keydown.right && !keydown.up) {
                player.color = "white";
            }

            //down and right
            if (keydown.right && keydown.down && !keydown.left && !keydown.up) {
                player.color = "brown";
            }

            //quick-fix for combined keypressse down, left and right
            if (keydown.right && keydown.left && keydown.down) {
                    player.color = "yellow";
            }

            //checking player boundaries *~*~* DELETE IF NOT BEING USED
                    if (player.x <= 0) { player.x = 1; } 
                    if (player.x >= w-player.width) { player.x = 991; } 
                    if (player.y >= h-player.height) { player.y = 511-player.height; }
                    if (player.y <= 121) { player.y = 122; }    
        }   
    }

    //Snip...


    //****************************************************//
    //**********  The global Draw Method *****************//
    //****************************************************//
    function draw() {
                ctx.clearRect(0, 0, w, h);
        player.move();
        ctx.fillStyle = "#000";
        ctx.font = "20px Arial";
        ctx.fillText("Score: ", 10, 50);
        ctx.fillText(score.toString(), 75, 50);

        ctx.fillText("Moving:", 115, 50);
        ctx.fillText(player.isMoving.toString(), 185, 50);

        ctx.fillText("Frame:", 255, 50);
        ctx.fillText(player.frame.toString(), 335, 50);
        npcs.forEach(function(Npc) {
            Npc.draw();
        });  
    };

})

\$\endgroup\$
  • \$\begingroup\$ Please remove everything irrelevant from your source code. Noone is going to read through all the pages of it. \$\endgroup\$ – Kromster Dec 2 '14 at 5:17
0
\$\begingroup\$

From your code :

       if (keydown.right) {
            if (player.frame != 4) player.frame = 4;
            else player.frame = 8;
            player.direction = 'E';
            player.x += 3;
            player.color = "blue";
        }

I can tell that the images are switched every update as long as the key is down. There are all kinds of ways you could change the speed at which this happens, based on current speed of the character, or just by giving it a hard limit.

An easy way of doing this with a hard limit is as follows :

 //... SNIP ...

 //we need to count updates so we can switch frames every x updates
 currentFrame : 0,

 move: function() {
        player.draw();
        //update current frame counter
        currentFrame ++;
 //... SNIP ...


       //this example is only the 'move right'portion. you'll need to do this for the other directions / animations yourself.
        if (keydown.right) 
        {
            //make sure we get the initial frame right if we just started moving right
            if (player.frame != 4 && player.frame != 8)
            {
               player.frame = 4;
            }
            //if the 'switch frames' timeout occurs (now hardcoded to ten updates)
            else if(currentFrame > 10)
            {
               //swap the current frame with the alternate frame
               if (player.frame != 4) player.frame = 4;
               else player.frame = 8;

               currentFrame = 0;
            }
            player.direction = 'E';
            player.x += 3;
            player.color = "blue";
        }
\$\endgroup\$
  • \$\begingroup\$ Timothy: Many thanks for the suggestion! I implemented your suggestion quite easily and now the animation works as desired! I'll also add that I was able to incorporate this fix towards normalizing the random movement of my NPCs in-game. Thanks again! Krom: My apologies, I am still quite new. I have removed large portions of the code that pertained to the NPCs, and anything else that was irrelevant to the matter of animation. \$\endgroup\$ – JLP1990 Dec 4 '14 at 21:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.