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.