1. Introduction to React Game Development
Today I'm going to show you how to make games in React. It gives you a new tool for expressing yourself and opens new doors to do things that previously wouldn't have been possible.
Hi, my name is Paulo Henschel. Thanks for having me. I am a developer from Germany. And this is my Twitter account. You can check it out. This is not an old, it's a zero. And today I'm going to show you how to make games in React. I guess many of you, they will wonder why the hell would I make a game in React? The thing is, it just gives you a new tool for expressing yourself. So it could be a game, could be front end, could be anything, really. So maybe you have a story to share, political messages, whatever. So this just helps you to open new doors, to do things that previously wouldn't have been possible.
2. Introduction to React 3.0 Fiber
Today I'm going to show you how to use React 3.0 Fiber, a library I made as a reconciler or wrapper for three.js. It originated from Bureli, an open embeddable CAD platform for the web. We needed something to make it more Reacty and control the scene better. This is very specific and great for making models and variant configurators. I'll show you how to use it from a beginner's perspective.
The thing that we are going to use is called React 3.0 Fiber. This is a library I once made. It's a reconciler or a wrapper, whatever you want to call it, for three.js. And you can see here some fancy demos going on. The thing where it originated from is called Bureli, B-U-E-R-E-L-I.io, you can check out here. This is what we are doing at work, and this is where it comes from. It's basically like a open embeddable CAD platform for the web. And we just needed something to make it more Reacty, to control the scene in a better way. And this is very specific. You can make models with it, variant configurators, visually or headless. But what I'm going to show you today has to do more with the library itself, React 3.0 Fiber, and how you can use it, and everything from a beginner's perspective because that's what I am. I have never made games before, but if you can make something like this, I guess you can do everything, at least you have the starting grounds.
3. Introduction to Arcanoid Game Development
First, go to the repository and check out the fundamentals section. Today, we're doing a small game called Arcanoid. We'll explain how 3D space works, the axes, the camera, and the visible area. We'll project primitive objects like the paddle and the ping-pong ball. We'll use the Canvas from React 3.0 Fiber.
First, I would ask you to go to this repository and check out the fundamentals section. In here, you find your starting grounds, documentation and stuff like this, just to get an idea of how it's all coming together. Today, I won't get too much in depth, but we are just learning by doing. And obviously, you also need 3.js by side of the documentation, because the things that I'm going to do today, I'm not going to explain how 3.js handles it, and so on.
So, let's get right into it. The thing that we are doing today is, I think it's called Arcanoid. It's like a small game that we're going to do. The paddle, I think, cannot be seen, because of the video screens, but either way. We will make a very reduced version of this today. And so, yeah, let's get going.
The first thing is, I'm going to explain to you how the 3D space works. You have three axes. The X one, it's a horizontal one. Y is vertical. And then you have depth. So this is how the 3D space works. 3D is three dimensional. Then you have a camera. It's looking onto the area that is visible. And it creates something that's called either a frustum or a viewport. It's a visible area of our screen. And in this thing, we are going to project a couple of primitive objects. One will be the paddle. We will tie this to our mouse to make it interactive. And the other will be this little ping-pong ball. We make it gravitate downwards. So, we're also working with physics. So, let's jump right in.
The first thing, and this may be the most important one that you fetch from React 3.0 Fiber is called Canvas. Basically, it's a representation of the WebGL context.
4. Understanding Meshes and Lighting in 3.js
In 3.js, a mesh is a representation of a shape that also describes how the shape looks. To make the shape visible, we need to give it a material. The mesh standard material is a recommended material for beginners. It can receive a color, which affects how the shape appears. Lighting is important in the scene, just like in photography. Ambient light comes from everywhere, resulting in a flat appearance. To create shadows, we need a main light source, such as a point light positioned in a specific direction.
Everything that goes on here is visible. In 3.js, you have a couple of things you can do. The most important one is called a mesh. And, if I save this, nothing will happen. You see nothing. Because a mesh is a representation of a shape, and it also has to describe how the shape is looking.
The shape could be, for instance, a sphere. Now we have a sphere. If I save this, we see it. But, it is pierced white, because we need to give it a material as well. There are many materials, but the one that I'm always using, and I suggest you use this as a beginner, is called mesh standard material. This one can receive a color. Oops, color. Let's say hot pink. If I save this, it's going black, and this is because it doesn't receive any light. If you've ever been into photography, it's the same principle, really. Things are affected by light inside the scene. If you know what, for instance, is field light, strip light, or main light, you are good. If you don't know what this is, don't break your head. You can just wing it, you can just try stuff out.
At first we are at ambient light. That means light comes from everywhere. This sphere looks pretty dodgy. It's flat. It's the same as in photography. If light comes from every angle, there's no shadow. So, we need a main light, a light source that is a little bit angled. And let's put a point light into the scene like this. We position it. Let's say, upper right.
5. Shading, Lighting, and Reusability in React
Now let's explore shading and lighting techniques. We can adjust the intensity of the ambient light and create a strip light effect. To make objects smoother, we can use constructor arguments like radius and segments. React is not limited to the web; it can handle various elements, including meshes and point lights. We can now create reusable components, like a ping pong ball, by using properties.
And now you can see a little bit of shading going on. Let's make the ambient light less intense. Like that. And now you can see it in a better way. Also, there's a trick that I always use. It's called a strip light. Again, it's, this is like basic photography. So, now it's the light that comes from behind. And it creates this little edge.
This sphere looks pretty rough in 3js. So, if you make a sphere or any object, you have something called arcs or constructor arguments. The first one is the radius. And the other one is segments, like how smooth this thing is going to appear, as you can see. So, these are the basics. Now we know how to put stuff into the scene. Now we know how to put up lights.
And you might be wondering, this looks pretty strange because these aren't diffs and spans. These are meshes and point lights and so on. So, don't think of React as something that is only for the DOM, for the web. React is a cross-platform component standard. It can handle everything. So, here we are putting three JS elements into the scene. Because this is React, we can now rip it out and create components, reusable components.
We have created a ball. This will be our ping pong ball. Let's put it up here and back into the scene. And there we go. Nothing should change. But now we have made it reusable. The first thing that we can do is using properties like this.
6. Adding Interactivity and Physics with Canon.js
Now we need to have our pedal. Let's also call this pedal. We have two components, the ping pong ball and the pedal. And now we need to make them interactive and react to two physics basically. Physics are very, very complex and there are many libraries that you can choose. For now, we will use Canon.js. It's called useCanon and it could be the easiest way you've ever seen to make physics possible.
Now, I can I could if I wanted, I could go in here and give it a different size, different radius. Whatever. I guess we are good. The pink combo should be white and maybe it shouldn't be so big like this. That looks good.
Now we need to have our pedal. Let's also call this pedal. I have copied the component. This one takes different arguments. We want to have a rectangle or a box like this. It also shouldn't be a sphere, should be box buffer and geometry. If I save this... Oops, I need to put it into this thing. Pedal, and yeah, that looks good. Let's put this down here.
Now I have the pedal but I don't want a box. I want something like a stretched rectangular. So, one like this. Let's give it another color, let's say light blue. Okay, we are good. We have two components, the ping pong ball and the pedal. And now we need to make them interactive and react to two physics basically. So this is the next thing that we need to do. Physics are very, very complex and there are many libraries that you can choose. MLJS, Canon.JS and so on. For now, we will use Canon.js. So that's a library that we made. It's on the React Spring Github organization. It's called useCanon and it could be the easiest way you've ever seen to make physics possible and I will show you this. Let's add it.
7. Physics and Object Interaction
Now we have physics and we can make objects behave in a physical way. By using hooks, we can describe the geometry of objects and give them properties like mass and gravity. We can tie these hooks to our objects and see them interact in the scene. Adjusting the gravity value can control the speed and direction of the objects' movements.
Physics, let's say provider like this. Now we have physics. And can I make this? This thing really sucks. Okay, I put it here. I saved us, nothing happens because I need to tell the physics world about these objects that I have put into the scene. And the easiest way to do this, this library gives us a couple of hooks and they think of them as an approximation. We have created a sphere. There's the little white thing you can see here and we need to tell the physics world that this is a sphere and we get a couple of hooks that describe how geometry looks and they work in the same way. We have the hook here. The hook wants to have arcs, the same ones. So in this case, it wants to know the radius and to behave in a physical way, an object needs to have mass. So we say mass one and all that we need to do is we need to tie it to our object, we get a reference, we put this to the mesh, ref. I can save it and as you can see it's dropping down. So physics is working. The thing is that it's way too slow. So we should give it a little bit more gravity, there's property on here that says gravity and it has three axes. Remember you have three axes in space and we want gravity come down, like from the Y axis upwards is positive values, downwards is negative values. So let's give it for instance minus 30 and that should look better. Yeah, that looks way better.
8. Controlling the Pedal with Mouse
The next thing is the pedal. We use the useBox hook to control it with our mouse. The API allows us to interact with objects, apply forces, and position them. The useFrame hook is crucial for animation and runs 60 times per second. By accessing the state model, we can use the mouse data to move the object left and right.
The next thing is the pedal. Nothing happens in here because only the ball is recognized in the physics world. There's another hook for this. The same principle, it's an approximation. So it's called use box. This time we don't give it a mouse because we want to control it with our mouse. That's the basic principle behind this, but it also just takes the same arguments that your box took.
So if I do this, and the same thing, I need to tie it to our mesh like this, and nothing happens because these two occupy the same space. So there's something else called API. And with this API, you can put, you can enact on it, put a force on it, put it in a certain spot, and so on. Normally you would position objects in here as I've shown you with the light, like yeah, you can make a position and then it should be left and right like this. But in our case, it's not like this because the physics was, it controls this mesh. So we needed to find a different way. And there's a hook called useFrame in React3 Fiber. And this is the most important one of them all. This one basically runs 60 times per second. It subscribes this component to the frame loop. That's what it does. So be careful. Everything that you put in here should not be expensive, but you can animate the object in there.
And what we are going to do is we take the API. It also has a position. It has a set where we can put in the three X's, and useFrame gives us a state model. The state model contains many useful things like how big is the viewport, responsiveness, but also has mouse data. So we can go in here, state mouse X. And if I save this, I should be able to move to seeing left and right. The thing is this doesn't do much because these are normalized mouse coordinates. They are zero in the center. If I go to the right, it's one. If I go to the left, it's minus one. So all I need to do is I need to know how big, how wide is the width of my viewport.
9. Bouncing the Ball and Increasing Bounce
Now it follows along with the mouse and all that's needed to do I need to put it down. Restitution is how strong is the bounce back. Right now, it has no restitution at all. So there's something called default contact material. In here, I can describe how the material work in the physical world. And now, you can see the ball is actually bouncing. And not just this, the bounce is increasing.
And that's it. Now it follows along with the mouse and all that's needed to do I need to put it down. So that's minus state viewport and height divided by two. And now it's here. And as you can see, it's already working. It catches the little sphere. And if I moved down, it goes away. But we wanted to bounce back. So there's something in physics. I have slept in physics school in the classes. I mean, but the property is called restitution. Restitution is how strong is the bounce back. Right now, it has no restitution at all. So there's something called default contact material. In here, I can describe how the material work in the physical world. So I say restitution, give it a little bit higher than 1. And now, you can see the ball is actually bouncing. And not just this, the bounce is increasing.
10. Resetting the Ball with a Contact Plane
We need something to reset, to respawn the ball. The easiest way would be a contact plane, a physical object that doesn't need a visual representation. It's supposed to catch the ball. We give it an object and rotate it to become a bottom or a surface. We also position it at the bottom and use the useFrame hook to get the viewport size.
It's increased. The next thing that we notice is the ball drops down. And the game is basically dead. So we need something to reset, to respawn the ball. And for this, there's something, there's many ways you could do it. But the easiest would be a contact plane. We put a physical object. It doesn't need a visual representation. And it's supposed to catch the ball. So we say use plane, give it an object again. This one also does not have mass. It stays fixed. And we need to rotate it. The reason for this is because if you put a mesh or a plane into the scene, it will appear like this. And we need to rotate it so that it becomes, say, a bottom or a surface. So we say rotation. This is going to be math pi. It's one rotation by two, so we rotate it by half. And this should be it. And also, now we need to put it a little bit down. It should be at the bottom. This is on the y-axis. And now we need to know the viewport. How big is the viewport? There's another very important hook. It's called useFrame. This one gives us the viewport. No, use3. In here, this is responsive. So every time the user resizes the screen, this component will be re-rendered. So let's just put this in here.
11. Respawning the Ball and Limited Gameplay
The ball can be respawned by using the onCollide hook and resetting its position and velocity. Additionally, a small upward velocity can be added to create a bouncing effect. However, the game is still limited as it only allows the ball to bounce up and down.
Viewport height. And it should be below. And if everything is working, then it should be fine already. So let's see. Yeah. OK. So we see we have this physical plane that's down there. But the problem is it's bouncing the ball back up. But we don't want this. We want to respawn the ball. So that's also easy. These hooks, they have something called onCollide. So every time they are hit, we are called back. And all we need to do, we get the API of this ball. And we just reset it. Position reset it to zero. So let's try this out. It works. But it maintains its velocity. So we also need to reset the velocity. It's the same thing. Velocity. And there it is. Now it respawns. We could actually make it, give it a little upward velocity. Then you can see it's bouncing up a little bit. And these are the bare bones of our game. The thing is, it doesn't do very much, because the thing can just bounce up and down.
12. Adding Rotation and Enemies
Let's angle the pedal and add rotation. By multiplying the state mouse x with an angle, we can achieve the desired effect. We can choose to add invisible walls or add enemies instead. The Enemy function can be used to create enemies with different colors and positions.
So let's angle the pedal a little bit. We do this in the pedal component. We already have one line of code for position so that it follows the mouse. Now we add another for rotation, like this. Set. And again, the camera comes from the x, no, from the z-axis. So we need to rotate it around this axis. It's this one. If we just say mouse, no, state mouse x, this time we multiply it with an angle because rotation takes angle. If we take a fraction of this, let's say 5. And what happens is this is already close to them. You can see you have to interact with it. You need to watch out.
So there's a couple of things we could do now. I don't want to stretch it. This should be a very reduced example, nothing more. We could put invisible walls at the side so that this bounds back. But let's not do this. Let's just add a couple of enemies. And I guess we are through. So I make a function called Enemy. And I copy everything inside the panel, like this. But this time, I also give it props. Let's take a color and the rest of the props. And let's spread the props over here and wire up the color here. So now, the developer can put enemies up. I create one. I say color, orange. And let's give it a position. Like this.
13. Creating and Customizing Enemies
Let's create enemies in our game and customize their appearance and position. We can place multiple enemies in the scene and observe their responsiveness. These simple steps demonstrate that game development in React is not difficult and can be accomplished with just a few lines of code. If you're interested, you can find a more complex example on my GitHub page. Feel free to reach out to me on Twitter if you create something cool.
Let's give it 0. So where do we want to place it? Let's move it upwards a little bit. And on the left side, arcs is not defined. OK. One. These are width, length, height, as I explained before. Ah. This one forgot to copy this one. OK. Now it should work. OK, there's our enemy. And as you can see, it's also responding. I can ping it. And I can put many of them inside the scene. Let's make another. Let's make this one a hot pink. Put it on the other side and put it a little bit higher. And there we go. Maybe still higher like this. So these are the bare bones of our application. I won't go further than this, because we are stretching time. What I wanted to show you with this is that all this stuff is not hard. As you can see, we only use like 60 lines. And you don't need much math. You can wing it. You can try stuff out. And the most important is that you have fun. So if it interests you, you can find the real example, the more complex one on my GitHub page. I will put up the reduced version as well. And yes, if you make something cool, could be game, could be anything, just make sure to ping me on Twitter.
14. Introduction and Appreciation
I would love to see your questions. And hope you had fun learning a little bit about WebGL, graphics, 3DJS, React 3 Fiber, in React. And yes, that's basically it. Thanks again for having me, have fun. And goodbye. Hey Paul. Hi. Thank you for joining us in this amazing demo. I have to say, I used to work at an advertising company doing development for ads. And once was in a team that built a 3D game with 3S, if I remember correctly. It's been six or seven years, so forgive me if I'm wrong. And that looked nowhere as easy. I was not involved in a 3D part that looked nowhere as easy as you make it look. You make it look, well, like, well, 60 lines and you build this bouncing ball pedal, Space Invaders start, no, Arkanoid. It's crazy. So there must be a lot of development that went, of course, into the engine, reactory fiber, that we can't go into detail now, but it looks really powerful. So thanks for giving that to the community.
I would love to see your questions. And hope you had fun learning a little bit about WebGL, graphics, 3DJS, React 3 Fiber, in React. And yes, that's basically it. Thanks again for having me, have fun. And goodbye.
Hey Paul. Hi. Thank you for joining us in this amazing demo. I have to say, I used to work at an advertising company doing development for ads. And once was in a team that built a 3D game with 3S, if I remember correctly. It's been six or seven years, so forgive me if I'm wrong. And that looked nowhere as easy. I was not involved in a 3D part that looked nowhere as easy as you make it look. You make it look, well, like, well, 60 lines and you build this bouncing ball pedal, Space Invaders start, no, Arkanoid. It's crazy. So there must be a lot of development that went, of course, into the engine, reactory fiber, that we can't go into detail now, but it looks really powerful. So thanks for giving that to the community.
Photography Skills for Reactory Fiber
If you want to use reactory fiber but don't have a photography background, just try it out and experiment with lights in the scene. You can also search for photography basics to understand terms like fill light, strip light, and main light. It can be helpful to connect with someone who has photography experience.
Okay, I wanna go to the first question from the audience. The question is from Cynthia. Any recommendations for basic photography skills for those who want to use reactory fiber, but don't have a photography background? Okay, I guess just wing it, just try out. You can put lights into the scene, see how it looks, but you will find it in Google, just Google for photography basics, so that you have a basic idea, what does a fill light, what does a strip light, what does a main light. These are essentials for photography and this stuff will really help you. Yeah, just to get the hang of the terminology, from my experience, there's always, photo people are really happy with what they're doing. So if you have someone in your environment that does photography, they will be happy to help you. Yes, just like developers, no disrespect to developers of course.
Physics Engines and Accelerometer API
There are physics engines, such as CanonJS, that take advantage of low power APIs. Combining React 3 Fiber with the Accelerometer API is possible, although I haven't personally experimented with it. The Accelerometer API is a JavaScript API that provides device angle data, allowing for potential phone rotation interaction. Pull requests are welcome.
Next question is from Danilo, with WebAssembly becoming more prominent, are there any physics engine, which take advantage of low power APIs? Actually there is, I'm not sure what was the name, I guess, AMO of physics JS or something like this, so there is, but CanonJS, the one that we are using is running in a WebWorker, so that's fine too, it doesn't clock the main thread. Okay, I hope Danilo is happy with that answer and else he can of course ask you in your Zoom room to go a bit further.
Next question is from Rin, have you had the opportunity to experiment with combining this with the Accelerometer API? Oh, nice one. No, not much. I haven't done much with PWA, also called PWA. Doesn't matter, Accelerometer API is just a JavaScript API. I haven't, or React Native, it's not so familiar to me, but I guess it would be easy. I don't think it would be very hard to do. Yeah, as far as I remember, it's been a while since I touched it, it's just an API that says, I don't know, device dot angle, something like that. You just get a number back so you could rotate the phone to move your panel, would be cool. So PR is welcome, right?
Custom Textures and Materials
Yes, everything that 3js can do is possible in react-3 fiber. You can combine React and 3js to learn both simultaneously. It's recommended to have a basic understanding of cameras, scenes, and lights. The React 3 Fiber GitHub has a fundamentals section for beginners. Learning how to write a custom React render is possible, but the API may change over time. Connect with me on Twitter for an easy example. Mouse moving the lighting with React 3 Fiber is possible.
Can you use custom textures and materials? So basically proper 3D stuff. Yes, of course. Everything that 3js can do is possible in react-3 fiber. There are no limitations, no restrictions. People usually they think because it's react or because it's declarative or JSX is involved that there must be something that it can't do, but it's not the case. Everything, every little thing that 3js does you can do here as well. Materials, textures, everything.
So then a follow up question from me, hi from Matthijs. This question is from Matthijs. If someone has seen this demo and it's like, that's it for me, I want to experiment with this. But they don't even have experience with 3js, would you recommend just taking time first to go raw at 3js or go in with their React experience and use react-3 fiber? Yeah, I would suggest that at least you go to 3js.org, check everything out, click some demos and they have something like a small document that teaches you how to make a scene, how to place the cameras, stuff like this. I guess it would be better if you do this first, but you don't need to get into 3js in depth, you can combine both, it's a little bit like people, they ask, what should I learn first, React? Or I don't know, HTML, whatever, but I think you can do both at the same time. React definitely will help you because there's no boiler plate, you can easily check things out, you have hot reload, so it will make learning actually easier. But you should definitely know the basics, what is a camera, what is a scene, lights and so on. You gotta learn to run, walk before you can run. Yeah, on the GitHub, React 3 Fiber GitHub, there's a small section called fundamentals. So that's the basic knowledge they should have before playing with React 3 Fiber.
Okay, thanks. Next question is from Andrew Greenage. Hey, Paul, great talk. Could you tell us a bit about the process of learning how to write a custom React render? I had no idea, there's no documentation. I was just trying it out. Trying on and error. They change the API all the time, so that was kind of a bummer, but it's possible. If you want, connect to me on Twitter and I can give you a very easy example. I have one on code sandbox, it's 50 lines or something, and yeah, it just gets the basics down. It's not so hard, but a little bit hard to get into if you know what I mean. Okay, we have time for one more question. It's from Martin Yu. Is it also possible to mouse move the lighting with Tree? Yeah, of course.
Mouse Moving Lighting with Tree
Is it possible to mouse move the lighting with Tree? Yes, there is a demo on my GitHub. Martin Yu, you can find the link to Paul's GitHub on the website. Feel free to ask any remaining questions in the Zoom room. Thank you, Tom.
Is it also possible to mouse move the lighting with Tree? Yeah, of course. I have a nice demo for this on my GitHub.
Okay, cool. So Martin Yu, I would recommend you going to Paul's GitHub. What's your GitHub handle? I have different handles on all platforms. Well, the link is on the website to your GitHub probably. It's D-R-C-M-D-A I think, I hope.
So for people that still have questions unanswered or the question was answered, but not deep enough, Paul still has time to answer your questions in his Zoom room where he's going to now. Paul, I would like to thank you a lot for joining us here today and sharing this awesome project of yours. Thank you, Tom. Bye bye.
Comments