3D React: Create Minecraft (with physics!) in React

In this post, I'm going to show you how to build Minecraft in React. What? A 3D Game, in React??

Yes. It's been said that React is more of a mindset than a DOM library and I'm going to show you an example that is both surprising and beautiful: a voxel Minecraft clone - with 3D rendering - in React.

Below I'm going to walk you through how to recreate the smash hit game Minecraft, but if you prefer to watch a video, Maksim - Fullstack React with TypeScript author --gives a walkthrough tutorial here on Youtube.

Here is the code repository. Clone it, run it, and play around to see how the code really works. Then go ahead and make your own React game!

Minecraft is an open-ended game that allows the player to explore a procedurally-generated game world. The game allows the player to build structures from materials such as wood, stone, dirt, and ores. The player's character has to occasionally eat food to replenish their health bar.

For the demo, these are the main features:

  • draws a game world with grass blocks

  • the player is able to move using the keys W, A, S, and D

  • pressing the spacebar allows the player to jump

  • clicking in a space allows the player to place a block there in order to build structures

The Building Blocks#

This game uses React for rendering UI and controlling events.

For graphics, it uses these libraries:

  • Three.js - A wonderful library for creating real-time 3D graphics and animations.

  • React-Three-Fiber - A React renderer that makes integrating Three.js into React components easier.

  • Cannon.js - A lightweight physics engine for the web. It helps create realistic gravity and other effects.

  • Use-Cannon - Npm module that exposes the Cannon.js API through Hooks.

The Game World#

The basic world in the game has a Three.js Scene with a mesh which has grass material.

The grass is provided through a grass.jpg image file.

Here is the code that creates the ground, contained in Ground/js.

In this code, we create a Ground function component that renders a Three.js mesh with a grass texture. This creates a green view in our scene. The grass texture is repeated 240 times in each direction.

The Player#

The Player is defined in a function component in Player.js. Here's what it looks like:

First, we import some libraries we'll use to implement the player: use-cannon for physics, react-three-fiber gives us the 3D rendering, and then a few of our own modules.

Continuing on, here's the Player:

There's a lot here! But the short version is that this code creates a ref to the player representation. It uses a custom usePlayerControls hook to allow the player to move (described below), and we update the camera to reflect the current view.

Here's what it looks like:

Amazing!

Game Controls#

The code that implements Player movement is contained in usePlayerControls.js.

What's super-cool is that we can use keyup and keydown listeners in a custom hook. I don't have room to paste the whole thing, but it looks like this:

You can find the full source file here.

This code uses Hooks like useState to provide functionality for handling user key presses as well as making the Player move. We use common game control keys for movement as follows:

  • W - move forward

  • A - move left

  • S - move backwards

  • D - move right

Tying It All Together With React#

Check out the App.js component file for a great look at how React components make composing all the game parts elegant!

For more on modern React patterns like custom Hooks, Testing, GraphQL and Redux, check out Fullstack React with TypeScript.