Game with Three.js, ReactJS and WebGL in java

View: 500    Dowload: 0   Comment: 0   Post by: hanhga   Category: Javascript   Fields: Other

I’m making a game titled “Charisma The Chameleon.” It’s built with Three.js, ReactJS and WebGL. This is an introduction to how these technologies work together using react-three-renderer (abbreviated R3R).

Check out A Beginner’s Guide to WebGL and Getting Started with React and JSX here on SitePoint for introductions to React and WebGL. This article and the accompanying code use ES6 Syntax.

How It All Began

Some time ago Pete Hunt made a joke about building a game using React in the #reactjs IRC channel:

“I bet we could make a first person shooter with React!
Enemy has <Head /> <Body> <Legs> etc.”

I laughed. He laughed. Everyone had a great time. “Who on earth would do that?” I wondered.

Years later, that’s exactly what I’m doing.

Charisma The Chameleon is a game where you collect power-ups that make you shrink to solve an infinite fractal maze. I’ve been a React developer for a few years, and I was curious if there was a way to drive Three.js using React. That’s when R3R caught my eye.

Why React?

I know what you’re thinking: why? Humor me for a moment. Here’s some reasons to consider using React to drive your 3D scene:

  • “Declarative” views let you cleanly separate your scene rendering from your game logic.
  • Design easy to reason about components, like <Player /><Wall /><Level />, etc.
  • “Hot” (live) reloading of game assets. Change textures and models and see them update live in your scene!
  • Inspect and debug your 3D scene as markup with native browser tools, like the Chrome inspector.
  • Manage game assets in a dependency graph using Webpack, eg <Texture src={require('../assets/image.png') } />

Let’s set up a scene to get an understanding of how this all works.

React and WebGL

I’ve created a sample Github repository to accompany this article. Clone the repository and follow the instructions in the README to run the code and follow along. It stars SitePointy: The 3D Robot!

Organizing View Code

The main benefit of using React to drive WebGL is our view code is decoupled from our game logic. That means our rendered entities are small components that are easy to reason about.

R3R exposes a declarative API that wraps Three.js. For example, we can write:

        position={ new THREE.Vector3( 1, 1, 1 )

Now we have an empty 3D scene with a camera. Adding a mesh to the scene is as simple as including a <mesh />component, and giving it <geometry /> and a <material />.

            width={ 1 }
            height={ 1 }
            depth={ 1 }
            color={ 0x00ff00 }

Under the hood this creates a THREE.Scene and automatically adds a mesh with THREE.BoxGeometry. R3R handles diffing the old scene with any changes. If you add a new mesh to the scene, the original mesh won’t be recreated. Just as with vanilla React and the DOM, the 3D scene is only updated with the differences.

Because we’re working in React, we can separate game entities into component files. The Robot.js file in the example repository demonstrates how to represent the main character with pure React view code. It’s a “stateless functional” component, meaning it doesn’t hold any local state:

const Robot = ({ position, rotation }) => <group
    position={ position }
    rotation={ rotation }
    <mesh rotation={ localRotation }>

And now we include the <Robot /> in our 3D scene!


You can see more examples of the API on the R3R Github repository, or view the complete example setup in the accompanying project.

Organizing Game Logic

The second half of the equation is handling game logic. Let’s give SitePointy, our robot, some simple animation.

gameLoop( time ) {
        robotPosition: new THREE.Vector3(
            Math.sin( time * 0.01 ), 0, 0

Calling setState() triggers a re-render of the child components, and the 3D scene updates. We pass the state down from the container component to the presentational <Game /> component:

render() {
    const { robotPosition } = this.state;
    return <Game
        robotPosition={ robotPosition }

There’s a useful pattern we can apply to help organize this code. Updating the robot position is a simple time based calculation. In the future, it might also take into account the previous robot position from the previous game state. A function that takes in some data, processes it, and returns new data, is often refered to as a reducer. We can abstract out the movement code into a reducer function!

Now we can write a clean, simple game loop that only has function calls in it.

import robotMovementReducer from './game-reducers/robotMovementReducer.js'; 


gameLoop() {
    const oldState = this.state;
    const newState = robotMovementReducer( oldState );
    this.setState( newState );

To add more logic to the game loop, such as processing physics, create another reducer function and pass it the result of the previous reducer:

const newState = physicsReducer( robotMovementReducer( oldState ) );

As your game engine grows, organizing game logic into separate functions becomes critical. This organization is straightforward with the reducer pattern.

Asset management

This is still an evolving area of R3R. For textures, you specify a url attribute on the JSX tag. Using Webpack, you can require the local path to the image.

<texture url={ require( '../local/image/path.png' ) } />

With this setup, if you change the image on disk, your 3D scene will live update! This is invaluable for rapidly iterating game design and content.

For other assets like 3D models, you still have to process them using the built in loaders from Three.js, like the JSONLoader. I experimented with using a custom Webpack loader for loading 3D model files, but in the end it was too much work for no benefit. It’s easier to treat the model as binary data and load them with the file-loader. This still affords live reloading of model data. You can see this in action in the example code.


R3R supports the React developer tools extension for both Chrome and Firefox. You can inspect your scene as if it were the vanilla DOM! Hovering over elements in the inspector shows their bounding box in the scene. You can also hover over texture definitions to see which objects in the scene use those textures.

Performance Considerations

While building Charisma The Chameleon I’ve run into several performance issues that are unique to this workflow.

  • My hot reload time with Webpack was as long as thirty seconds! This is because large assets have to be re-written to the bundle on every reload. The solution was to implement Webpack’s DLLPlugin, which cut down reload times to below five seconds.
  • Ideally your scene should only call one setState() per frame render. After profiling my game, React itself is the main bottleneck. Calling setState() more than once per frame can cause double renders and reduce performance.
  • Past a certain number of objects, R3R will perform worse than vanilla Three.js code. For me this was around 1,000 objects. You can compare R3R to Three.js under “Benchmarks” in the examples.

The Chrome DevTools Timeline feature is an amazing tool for debugging performance. It’s easy to visually inspect your game loop, and it’s more readable than the “Profile” feature of the DevTools.

That’s It!

Check out Charisma The Chameleon to see what’s possible using this setup. While this tool chain is still quite young, I’ve found React with R3R to be integral to organizing my WebGL game code cleanly. You can also check out the small but growing R3R examples page to see some well organized code samples.

What do you think – have you already tried using React to organize your JavaScript game code? What did you make, and what were the pros and cons? Comment below and share your experiences!

Game with Three.js, ReactJS and WebGL in java

I’m making a game titled “Charisma The Chameleon.” It’s built with Three.js, ReactJS and WebGL. This is an introduction to how these technologies work together using react-three-renderer (abbreviated R3R).

Posted on 22-09-2016 


To comment you must be logged in members.

Files with category

  • Mini Youtube Using ReactJS

    Mini Youtube Using ReactJS

    View: 25    Download: 2   Comment: 0

    Category: Javascript     Fields: none

    This is one the best starter for ReactJS. MiniYoutube as the name suggests is a youtube like website developed using reactJS and youtube API. This project actually let's you search , play and list youtube videos. Do check it out and start learning...

  • Angular 6 Starter with Laravel 5.6 API Service

    Angular 6 Starter with Laravel 5.6 API Service

    View: 62    Download: 0   Comment: 0

    Category: Javascript     Fields: none

    Angular 6 and Laravel 5.6 This project is a starter for creating interface with Angular using bootstrap && css && sass and using Laravel 5.6 for api requests. Demo Installation This project is divided in two parts (projects) and before use them you...

  • Simple Richtext Editor Based on pellJS

    Simple Richtext Editor Based on pellJS

    View: 26    Download: 0   Comment: 0

    Category: Javascript     Fields: none

    A simple visual editor for websites using the pell javascipt. It also has the option to switch between visual editor mode and source code mode. I will upload an update for new functionality soon. Source Code Editor Visual Editor

  • Data Visualization for BI: How to Design Layouts for .NET Financial Reports

    Data Visualization for BI: How to Design Layouts for .NET Financial Reports

    View: 37    Download: 0   Comment: 0

    Category: Javascript     Fields: Other

    With the Active Reports Server, you can have a multi-tenant environment where users from various departments, companies, or other specifications can log in, view their reports (and only their reports), export the data, or set up a distribution...

  • AngularJS and REST API

    AngularJS and REST API

    View: 204    Download: 0   Comment: 0

    Category: Javascript     Fields: Other

    This is a tutorial for those interested in a quick introduction to AngularJS and REST API. We will build the familiar Periodic Table of the Elements found in every chemistry textbook, and allow the user to select a Chemical Element by clicking on...

  • Collective Intelligence, Recommending Items Based on Similar Users' Taste

    Collective Intelligence, Recommending Items Based on Similar Users' Taste

    View: 168    Download: 0   Comment: 0

    Category: Javascript     Fields: Other

    Using Collaborative Filtering to find people who share tastes, and for making automatic recommendations based on things that other people like.

  • Think Like a Bird for Better Parallel Programming

    Think Like a Bird for Better Parallel Programming

    View: 157    Download: 0   Comment: 0

    Category: Javascript     Fields: Other

    Coding an application to run in parallel is hard, right? I mean, it must be hard or we’d see parallel programs everywhere. All we'd see are slick parallel apps that use every available core effortlessly. Instead multi-threaded apps are the exception...

  • Getting Started with the Bing Search APIs

    Getting Started with the Bing Search APIs

    View: 169    Download: 0   Comment: 0

    Category: Javascript     Fields: Other

    Bing Search API is a set of REST interfaces that find web pages, news, images, videos, entities, related searches, spelling corrections, and more in response to queries from any programming language that can generate a web request. Applications that...

File suggestion for you
File top downloads
Codetitle - library source code to share, download the file to the community
Copyright © 2018. All rights reserved. codetitle Develope by Vinagon .Ltd