Javascript Smooth Animations

I have this HTML file:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Game Dev</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
        <script type="text/javascript" src="js/functions.js"></script>
        <script type="text/javascript" src="js/player.js"></script>
        <script type="text/javascript" src="js/map.js"></script>
        <script type="text/javascript" src="js/keyboard.js"></script>
        <script type="text/javascript" src="js/pacman.js"></script>
        <link rel="stylesheet" type="text/css" href="bootstrap/css/bootstrap.css">
        <link rel="stylesheet" type="text/css" href="css/stylesheet-play.css">
    </head>

    <body>
        <div class="container middle" id="play-container">
            <canvas id="canvas" width="800" height="640">
                
            </canvas>

            <div class= "col-md-12 ">
            <ul id = "scoreTable">
                <li><p id='score'>Score: </p></li>
                <li><p id='outputScore'></p></li>
                <li><p id='score'>Level: </p></li>
                <li><p id='level'></p></li>
            </ul>
            
            </div>
        </div>
    </body>

    </html>

this CSS file:

    #canvas
    {
        margin-top:2%;
        border:dashed 1px white;
        padding: 0px;
        background-color: rgb(0, 19, 26);
          
    }
    #play-container
    {

        width:100%;
        text-align: center;
    }
    body{
        background-color: black;
    }
    #score, #outputScore, #level{
        font-size: 18px;
    }
    #scoreTable li{
        display: inline-block;
        text-decoration: none;
    }

and this Javascript:

    var score = 0;
    var levelNumber = 0;
    var frameCycle = 1;
    var framesPerMovement = 30;
    var isMoving = false;
    var direction = 'stopped';
    var directions = {
            'up': {x: 0, y: -1},
            'down': {x: 0, y: 1},
            'left': {x: -1, y: 0},
            'right': {x: 1, y: 0},
            'stopped': {x: 0, y: 0}
        };

    var grid = [
            [2, 2, 2, 2, 2, 2, 2, 1],
            [2, 1, 2, 1, 2, 2, 2, 1],
            [2, 2, 1, 2, 2, 2, 2, 1],
            [2, 2, 2, 2, 2, 2, 2, 1],
            [2, 2, 2, 2, 2, 2, 2, 1],
            [1, 2, 2, 2, 2, 2, 2, 1],
    ];

    var screenWidth = grid[0].length;
    var screenHeight = grid.length;

    squareSize = 40;
    screenPixelWidth = screenWidth * squareSize;
    screenPixelHeigth = screenHeight * squareSize;

    var Player = function(){
      this.x = 1;
      this.y = 2;
        this.radius = 2;

        this.drawPac = function(){
            drawCircle(this.x, this.y, this.radius, 'rgb(255, 153, 51)', direction);
        }

        this.movePacman = function(dirz){
            if(isMoving || this.pathBlockedInDirection(dirz)){

            }else{
                direction = dirz;
                isMoving = true;
                this.movementLoop();
            }
        }

      this.collideWithBorder = function(){
          var pacmanOutOfBounds = this.x < 0 ||
                                  this.y < 0 ||
                                  this.x >= screenWidth ||
                                  this.y >= screenHeight;
          return pacmanOutOfBounds;
      }

      this.collideWithWall = function(){
        var x = this.x;
        var y = this.y;
        return grid[y][x] === 1;
      }

      this.clearScreen = function(){
        Context.context.clearRect(0, 0, screenPixelWidth, screenPixelHeigth);
      }

        this.processPellets = function(){
            if(grid[this.y][this.x] === 2){
                grid[this.y][this.x] = 0;
                score ++;
            }

            if(levelComplete()){
                levelNumber ++;
                restartLevel();
            }
        }

        this.movementLoop = function(){
            if(frameCycle === framesPerMovement){
                var dir = direction;
                //console.log(direction);
                this.x = this.nextCoordinate('x', dir);
                this.y = this.nextCoordinate('y', dir);

                isMoving = false;
                frameCycle = 1;

                this.processPellets();
            }else{
                frameCycle ++;
                //console.log(frameCycle);
                setTimeout(this.movementLoop(), 1000/60);
            }
            this.clearScreen();
            drawGrid();
            this.drawPac();
        }

        this.nextCoordinate = function(coords, direct){
            if(coords === 'x'){
                return this.x + directions[direct].x;
            }
            if(coords === 'y'){
                return this.y + directions[direct].y;
            }
        }

        this.pathBlockedInDirection = function(direction){
            var cellTypeInDirection = this.cellTypeInDirection(direction);
            console.log(cellTypeInDirection);
            return cellTypeInDirection === 1 || cellTypeInDirection === undefined;
        }

        this.cellTypeInDirection = function(direction){
            var nextX = this.nextCoordinate('x', direction);
            var nextY = this.nextCoordinate('y', direction);

                return grid[nextY][nextX];
        }
        //
    }

    drawCircle = function(x, y, radiusDivisor, fill, dirp){
      var radius = squareSize/2;
      var pixelX = (x+1/2 + offsetFor('x', dirp))*squareSize;
      var pixelY = (y+1/2 + offsetFor('y', dirp))*squareSize;

      Context.context.fillStyle = fill;
      Context.context.beginPath();
      Context.context.arc(pixelX, pixelY, squareSize/radiusDivisor, 0, Math.PI*2, false);
      Context.context.closePath();
      Context.context.fill();
    }

    offsetFor = function(coords, dirb){
      var frameRatio = frameCycle/framesPerMovement;
      if(coords === 'x')
        return directions[dirb].x*frameRatio;
      if(coords === 'y')
        return directions[dirb].y*frameRatio;
    }

Basically, I have built a game of pacman.
My main problem is that I cannot make it have smooth animations.
I am momentarily locked on the
setTimeout(...); piece of code in the javascript.
For now it just jumps around different positions.
How can I draw a smooth animation for my player?

See here for a how to create a game loop with requestAnimationFrame

The trick is to run requestAnimationFrame as many times as possible but to move things relative to the time between frames(the dt variable in that example).

Hope it helps :slight_smile:

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.