00:00/00:00TIME LEFT
Choosing the a bcd
3:22
00:03:22

Shortcuts

  • SPACE to play / pause
  • ARROW RIGHT or L to go forward
  • ARROW LEFT or J to go backward
  • ARROW UP to increase volume
  • ARROW DOWN to decrease volume
  • F to toggle fullscreen
  • M to toggle mute
  • 0 to 9 to go to the corresponding part of the video
  • SHIFT + , to decrease playback speed
  • SHIFT + . or ; to increase playback speed

Want to learn more?

That's the end of the free part 😔

To get access to 45 hours of video, a members-only Discord server and future updates, join us for only $95!

53.

Create a game

Difficulty Hard

Downloads

Introduction 00:00

In this lesson, we are going to learn how to create a mini-game.

We play a marble and we have to go through a level filled with various moving obstacles in order to reach the destination.

Here are some of the mechanics:

  • The player can move the marble and make it jump with the keyboard.
  • As soon as the marble is moving, a timer starts running and it indicates to the player how long it took to finish the obstacle course.
  • At the end of the race, a “restart” button appears and by clicking on it, it will reset the marble to the initial position, reset the timer and create a new set of obstacles so that the level is never the same.

This lesson is a good opportunity to put into practice the knowledge we gathered like physics, interface & components but also new concepts like a global state or keyboard controls.

And obviously, we get to create and play a game!

Setup 01:12

In the starter, we have the classic orange sphere, purple cube, and green floor.

Both the directional light source and an ambient light source are in a <Lights> component because we are going to make some tweaks related to lights a bit later and we want to keep things organised.

Shadows are already enabled and the directional light is set to cast the shadows within a pretty large area:

<directionalLight
    castShadow
    position={ [ 4, 4, 1 ] }
    intensity={ 1.5 }
    shadow-mapSize={ [ 1024, 1024 ] }
    shadow-camera-near={ 1 }
    shadow-camera-far={ 10 }
    shadow-camera-top={ 10 }
    shadow-camera-right={ 10 }
    shadow-camera-bottom={ - 10 }
    shadow-camera-left={ - 10 }
/>

The @react-three/drei dependency is already installed within the project.

We are using the OrbitControls helper to be able to move the camera around, but we are going to remove it later so that we can have the camera follow the marble.

We haven’t added <Perf /> from r3f-perf but you should definitely use it if you create your own game. Having a good frame rate is very important and monitoring performance will help you.

No debug UI has been added because all the various values and colors have already been carefully chosen, but you should definitely add one (like Leva) if you were to create your own game or if you want to improve this game once you are done with the lesson.

Level 02:17

When creating a game, it’s good to have things on screen as quickly as possible. Even if the mechanics don’t work yet, it helps to get an idea of what’s coming up and it’s much more interesting.

That’s why we are going to start by creating the level and its various traps.

Our level will be composed of what we are going to call blocks.

The first block will be composed of a simple floor without anything else. It’s where the player will start.

The last block will be the finish line.

In between, there will be a bunch of trap blocks with moving obstacles.

We are going to create 3 different types of traps and then populate the blocks between the start and the end with a random set composed of those trap blocks.

Component

In /src/, create a Level.js file, export a Level function component and put the 3 meshes from Experience in it:

export default function Level()
{
    return <>
        <mesh castShadow position-x={ - 2 }>
            <sphereGeometry />
            <meshStandardMaterial color="orange" />
        </mesh>

        <mesh castShadow position-x={ 2 } scale={ 1.5 }>
            <boxGeometry />
            <meshStandardMaterial color="mediumpurple" />
        </mesh>

        <mesh receiveShadow position-y={ - 1 } rotation-x={ - Math.PI * 0.5 } scale={ 10 }>
            <planeGeometry />
            <meshStandardMaterial color="greenyellow" />
        </mesh>
    </>
}

In Experience, import Level:

import Level from './Level.js'

Instantiate it after the <Lights>:

export default function Experience()
{
    return <>

        <OrbitControls makeDefault />

        <Lights />
        <Level />

    </>
}

We have our little scene back, but now it’s set in the <Level>.

Add Physics

The game will rely heavily on physics and we are going to use Rapier with @react-three/rapier as seen in the previous lesson.

Want to learn more?

That's the end of the free part 😔

To get access to 45 hours of video, a members-only Discord server and future updates, join us for only $95!

That was the last lesson!

Care to join?

How to use it

  • Download the Starter pack or Final project
    (if your browser detects a menace, do not worry, it is not)
  • Unzip it
  • Open your terminal and go to the unzip folder
  • Run npm install command to install dependencies
  • Run npm run dev to launch the local server
    (your browser should start automatically)

You can now start coding.

  • The JS is located in src/script.js
  • The HTML is located in src/index.html
  • The CSS is located in src/style.css

Any trouble? Go to the discord server: