JavaScript - Game Part 2

In this lesson we will draw the ball and the paddles.


Let's now draw all the elements related to actually playing the game. There are only three: the ball, the player paddle, and the opponent paddle.

First, we need to define a draw() function that will draw the game. All the drawing and animation steps will exist within that function. You can use the requestAnimationFrame() function inside the draw function in order to create animation by continually calling the draw() function. Here is how the basic set-up looks:

        let canvas = document.getElementById("gameCanvas");
        let context = canvas.getContext("2d");
        
        function draw() {
            // Drawing code goes here
            requestAnimationFrame(draw);
        }
         
        draw();
                

Now we can draw everything inside the draw() function. By the way, the draw() function and any of the functions and variables we will be creating can be called anything you want, but I would recommend using the names we provide to reduce confusion.

Now, let's draw the ball. We'll draw it inside a drawBall() function and call the function inside the draw() function. The function could look something like this:

        function drawBall() {
            context.beginPath();
            context.arc(400, 300, 10, 0, Math.PI * 2);
            context.fillStyle = "#e0e0e0";
            context.fill();
            context.closePath();
        }
        
        function draw() {
            drawBall();
            requestAnimationFrame(draw);
        }
        
        draw();
                

This draws a circle of radius 10 at the coordinates (400, 300) with the hex color #e0e0e0. We have also put the drawBall() function inside the draw() function to call it. The canvas should now look like this:

We want to be able to move the ball later, though, so we want to replace the ball's x and y values with variables. We can also change the ball's radius/size and color to constants for ease of use. Here is what the code looks like after doing that:

        let canvas = document.getElementById("gameCanvas");
        let context = canvas.getContext("2d");
        
        const BALL_COLOR = "#e0e0e0";
        const BALL_SIZE = 10;
        
        let ballX = canvas.width / 2;
        let ballY = canvas.height / 2;
        
        function drawBall() {
            context.beginPath();
            context.arc(ballX, ballY, BALL_SIZE, 0, Math.PI * 2);
            context.fillStyle = BALL_COLOR;
            context.fill();
            context.closePath();
        }
        
        function draw() {
            drawBall();
            requestAnimationFrame(draw);
        }
        
        draw();
        

You can access the width and height of the canvas with dot notation as in lines 7 and 8, and taking half of those values allows us to initially place the ball in the middle of the canvas.

Now, we will draw the paddles. Since we have two paddles in the game, we could use one function to draw both of them for code efficiency. Since paddles should store multiple pieces of important information, we can store the paddle variables as objects which store values like the paddles' x and y positions. We can also store constants like the paddles' heights, widths, and color in const variables:

        let canvas = document.getElementById("gameCanvas");
        let context = canvas.getContext("2d");
        
        const BALL_COLOR = "#e0e0e0";
        const BALL_SIZE = 10;
        const PADDLE_COLOR = "#e0e0e0";
        const PADDLE_WIDTH = 15;
        const PADDLE_HEIGHT = 120;
        
        let ballX = canvas.width / 2;
        let ballY = canvas.height / 2;
        
        // paddles initialized opposite each other
        let opponentPaddle = {name: "opponent", x: 765, y: (canvas.height - PADDLE_HEIGHT)/2};
        let playerPaddle = {name: "player", x: 20, y: (canvas.height - PADDLE_HEIGHT)/2};
        
        /**
         * Draws the ball
         */
        function drawBall() {
            context.beginPath();
            context.arc(ballX, ballY, BALL_SIZE, 0, Math.PI * 2);
            context.fillStyle = BALL_COLOR;
            context.fill();
            context.closePath();
        }
        
        /**
         * Draws a paddle
         * 
         * @param {Paddle} paddle 
         */
        function drawPaddle(paddle) {
        
        }
        
        /**
         * Draws the game
         */
        function draw() {
            drawBall();
            requestAnimationFrame(draw);
        }
        
        draw();
        
                

I also added some comments above each function. The appropriate way to comment a function involves a summary of the function and definition of the inputs and their type. The drawPaddle() function has a parameter paddle, which we have decided in the comment is of object type Paddle. Each paddle has the properties name, x, and y, which will all be helpful later.

Side-note: You don't really have to worry about the technical details of the comments, but we really should have declared a class called Paddle and created the paddle objects from that, but with so few properties, just declaring the playerPaddle and opponentPaddle variables as objects is much easier.

Now all we have to do is define the drawPaddle function, which should be simple:

        function drawPaddle(paddle) {
            context.beginPath();
            context.rect(paddle.x, paddle.y, PADDLE_WIDTH, PADDLE_HEIGHT);
            context.fillStyle = PADDLE_COLOR;
            context.fill();
            context.closePath();
        }
        

...

function draw() { drawBall(); drawPaddle(playerPaddle); drawPaddle(opponentPaddle); requestAnimationFrame(draw); }

As you can see, we can use dot notation to get the x and y values of the input paddle object. In addition, we need to actually draw the paddles in the draw() function by inputting each paddle into the drawPaddle() function, as shown in lines 46 and 47. The canvas should now look like this when you re-open the html file:

Perfect! Next let's try to animate the ball.

Source code

< Previous Next >