Game with Three.js, ReactJS and WebGL in java

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

0 point/1 review File has been tested

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:

<scene>
    <perspectiveCamera
        position={ new THREE.Vector3( 1, 1, 1 )
    />
</scene>

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 />.

<scene>
    ...
    <mesh>
        <boxGeometry
            width={ 1 }
            height={ 1 }
            depth={ 1 }
        />
        <meshBasicMaterial
            color={ 0x00ff00 }
        />
</mesh>

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 }>
        <geometryResource
            resourceId="robotGeometry"
        />
        <materialResource
            resourceId="robotTexture"
        />
    </mesh>
</group>;

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

<scene>
    ...
    <mesh>...</mesh>
    <Robot
        position={...}
        rotation={...}
    />
</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 ) {
    this.setState({
        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.

Debugging

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

Game with Three.js, ReactJS and WebGL in java Posted on 22-09-2016  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). 5/10 412

Comment:

To comment you must be logged in members.

Files with category

  • AngularJS and REST API

    AngularJS and REST API

    View: 31    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: 72    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: 45    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: 48    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...

  • Brief Introduction of SocketPro High Performance and Scalable Persistent Message Queue

    Brief Introduction of SocketPro High Performance and Scalable Persistent Message Queue

    View: 156    Download: 0   Comment: 0

    Category: Javascript     Fields: Other

    Continuous in-line request/result batching, real-time stream sending/processing, asynchronous data transferring and parallel computation for best performance and scalability

  • Iteration Over Java Collections with High Performance

    Iteration Over Java Collections with High Performance

    View: 41    Download: 0   Comment: 0

    Category: Javascript     Fields: Other

    Java developers usually deal with Collections such as ArrayList, HashSet, Java 8 come with lambda and streaming API helps us to easily work with Collections. In most cases, we work with few thousands of items and performance isn't a concern. But in...

  • SR2JLIB - A Symbolic Regression Library for Java

    SR2JLIB - A Symbolic Regression Library for Java

    View: 46    Download: 0   Comment: 0

    Category: Javascript     Fields: Other

    Grammar-Guided Genetic Programming library featuring: multi-threading, just-in-time compilation of individuals, dynamic class loading, and JNI interfacing with C/C++ code

  • Yet Another Fluent JDBC Wrapper in 200 Lines of Code

    Yet Another Fluent JDBC Wrapper in 200 Lines of Code

    View: 54    Download: 0   Comment: 0

    Category: Javascript     Fields: Other

    Those who are not convinced to use Hibernate to manage persistence are forced to use plain old JDBC API. Though powerful, it requires lot of typing to get it right. For example, retrieving user data from database often requires such code snippet:

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