Breakout Game with JavaScript, React and SVG. Part 2

Radzion
Zero Equals False
Published in
5 min readJul 2, 2019

This is part of the course “Breakout Game with JavaScript, React and SVG”.

GitHub Repository and Deployed Game

In this course, we are building a Breakout Game with JavaScript, React, and SVG without libraries, just plain modern JS and React. We are utilizing functional, immutable programming, and along the way, we learn React Hooks, SVG rendering, and basics of game development. You can find the source code in this GitHub repository, and check out the game here. In this part, we are going to turn raw levels descriptions into the game state and finish the Page component.

Game State From Level

In the previous part, we decided on what parameters each level will include, and now we’ll generate an initial game state from the level object. The game state doesn’t care about what is used for rendering — SVG or Canvas, or does the user playing on keyboard or touchscreen. The state consists of:

  • Size has the width and height of the game. Distances measured not in pixels, but in abstract units — in our case, this unit is the width of the block. So we can say, this level has the size of 10x10 blocks.
  • Blocks are an array of objects, where each object have width, height, density and the position of the top-left corner.
  • The paddle has the same structure as a block but without density.
  • Ball has a center, radius, and direction.
  • Lives and speed we are passing right from level to the state.

First, let’s open utils.js and add a few functions that we will utilize farther in this part.

You can see what they do in examples below:

getRandomFrom() and flatten()

Next, we need to create the only class we will use in this game — Vector. We will use vectors, both for directions and coordinates. If you are not comfortable with vectors, check out this article that shows the basics with JS examples. Let’s create a file named vector.js and put it into the game folder. For now, it will only have a constructor and a few methods. Along the way, we will extend this class with other methods that also won’t mutate the object.

Let’s add file core.js to the game folder. First, we import Vector and utils and declare sizes of different things in the game.

We give 1/3 of game height to paddle, which means, that blocks will be on the center of the top 2/3 of the game.

paddle area

Beside paddle area, other constants, like ball radius expressed as fractions of block width, since block width is the unit in our game.

BLOCK_WIDTH and BLOCK_HEIGHT

Then we declare directions by using Vector class.

One thing that may look strange is that the UP vector is pointing down. This is also can look controversial since the state doesn’t deal with the screen where coordinate starts in the left top corner, but in this type of game, the choice of Y-direction doesn’t make much of a difference.

Since we also need to get an initial position of paddle and ball when the player misses the ball, it is better to create a separate function that will return the initial state for these objects. As parameters, it receives the width and height of the game field and the width of the paddle. It places the paddle and the ball at the bottom of the field and directs the ball randomly in the left or right direction.

Finally, we can write a function that receives a level and returns the initial state. The game field always square, we determine it’s size by looking at the length of the first row of blocks. Then we place blocks at the center of 2/3 area of the field.

Complete Page Component

Now we are going to finish the Page component that we started in the previous part. This component serves as a wrapper around a game scene. It is watching for window resize and passes how much free space is available to its children — Scene.

Since we will need to add window event listeners, let’s write a function at utils.js that will register a listener and will return function via which we can unregister the listener.

Next, we need to create a Scene component at the scene.js inside of the components folder. For now, it will receive container size and console log it out without doing anything.

We want the scene on the center of the screen, so let’s add styles for scene container in index.css.

Now, we can open page.js and finish it. We are using React hooks here to get access to the container and keep its size in the state. Via useEffect, we register an event listener when the component is mounted and unregister listener on unmount.

If we run the app and open developer tools, we can see that every time resize happens Scene receives a new width and height.

$ npm run

In this part, we’ve made a function that turns raw level description into game state and finished Page component. The commit with these changes you can find here. If you like more video format, check out this course on YouTube. In the next part, we will start the development of the Scene component. Stay tuned!

Reach the next level of focus and productivity with increaser.org.

Increaser

--

--