{{draft}}
Whitestorm.js is a framework built on the top of Three.js technology, enhanced by features such as a built-in Physics engine — a modified Physi.js that acts as a wrapper around Ammo.js (Bullet Physics ported to JavaScript) with usage of web-workers technology — and a plugin system providing useful modularity. In this article we show how you can get started with Whitestorm.js.
Environment setup
Whitestorm.js can be used in Node applications, and included in client-side projects either manually or as a bower component. Let's look at how we can do this.
Node
- Run
npm install whitestormjs
. - Import the whitetormjs module to your app and start using it, as demonstrated below:
import * as WHS from 'whitestormjs'; const world = new WHS.World({ background: { color: 0xDDDDDD } }); // ...
Bower
- Run
bower install whitestormjs
- Include whitetormjs in your app as follows:
<script src="bower_components/whitestormjs/build/whitestorm.js"></script>
Manual
- Make a copy of the WhitestormJS library file in your app directory.
- Include a {{htmlelement("script")}} element in your HTML {{htmlelement("head")}} (or after your {{htmlelement("body")}}) to apply the Whitestorm JavaScript to your HTML:
<script src="{path_to_lib}/whitestorm.js"></script>
Developing a Whitestorm app
Let's look at how we can create a quick sample Whitestorm app.
Getting started
Create a new index.html
file in a new directory. Use our simple template if you don't already have one handy.
Remove any content that you might already have inside your document body (like the {{htmlelement("p")}} element in our teplate above.)
Follow the {{anch("Manual")}} insrtructions above to apply the Whitestorm library to your HTML.
Create a new {{htmlelement("script")}} element just below the existing one, in which to write your app code.
Creating a world
Whitestorm has a global WHS
object that stores all of its functionality. To start off with making a whitestorm app you need to create a WHS.World
object, which represents the app's 3D scene. This allows you to set parameters of the scene like camera position and gravity, and it also processes any other objects added to the world (like spheres, for example — objects inside the scene can be considered children of the WHS.World
object).
Add the following code inside your second <script>
element:
const world = new WHS.World({ stats: "fps", autoresize: "window", // Call autoresize when app window is resized. gravity: { x: 0, y: -5, z: 0 }, camera: { z: 50 }, container: document.body });
The members set inside this object are as follows:
stats
: Declares whether you want to display stats while your app is running. Options are"fps"
(frames per second),"ms"
(milliseconds elapsed),"mb"
(megabytes downloaded), or booleanfalse
if not required (which is also the default).autoresize
: Declares whether you want the Whitestorm app {{htmlelement("canvas")}} to resize when the browser window is resized ("window"
), when its container is resized ("container"
), or not at all (booleanfalse
, which is the default).gravity
: Sets what gravity you want to act on objects in the scene, in thex
,y
, andz
directions. The default is 0 in all directions.camera
: Sets the position and other properties of the camera that will be viewing the scene.container
: Sets the HTML DOM object that the Whitestorm app's<canvas>
will be appended inside on the page. The default isdocument.body
.
Note: See the Whitestorm reference for more information on WHS.World features.
Creating a sphere
Whitestorm has available a number of primitives available for creating common shapes in the world, which mostly act as wrappers around Three.js primitives. WHS.Sphere
for example is analogous to Three's THREE.SphereGeometry
, and is based on WHS.Shape
— a class that wraps the Three API for working with meshes.
Let's create one now. Add the following below your previous code addition:
const sphere = new WHS.Sphere({ // Create sphere object. geometry: { // Create a THREE.SphereGeometry(3) radius: 3 }, mass: 10, // Mass of physical object. material: { // Material color: 0xffffff, kind: 'basic' // THREE.MeshBasicMaterial }, pos: { // Position vector. x: 0, y: 50, z: 0 } });
Here we are specifying:
geometry
: Sets geometry information about the object; in this case we only need to specify a radius for the sphere.mass
: Sets the relative mass of the object, which will for example have an effect on gravity's pull on the object.material
: Sets the type of material we want to cover the surface of the object with.pos
: Sets the initial position of the object on the scene, as anx
,y
,z
position vector.
Note: See the Whitestorm sphere documentation for more information.
Making things happen
Nothing will happen yet; you still need to add your sphere to the world, and start the app rendering. The following two lines will do this — add them to the scene now:
sphere.addTo(world); // Add Sphere to world. world.start(); // Start animations and physics simulation.
And that should be it — try saving and refeshing your code now, and you should see something like the following (with the ball moving down the screne due to the graivty in the y
direction):
[INSERT SCREENSHOT]
There is also explanation for usage with webpack
Creating a world
When you create a world in Whitestorm.js it automatically creates THREE.Scene
, WebGL renderer and applies camera. But don't worry, all of them you can access simply as: world.scene
, world.renderer
, world.camera
. WHS.World is highly editable class. All parameters are non-required and have their own default values. Check or change them you can in WHS.World.defaults
. See all of them
const world = new WHS.World({ background: { color: 0xffffff }, camera: { z: 50 }, gravity: { y: -100 } });
Using physics in Whitestorm.js is not required. You may rather use whitestorm.light.js
build that is without included Ammo.js and physics part.
Rendering a box
Same rule with defaults is also related to other classes. Each mesh consist of geometry & material. As we make a WHS.Box component - our geometry is THREE.BoxGeometry
. If you know Three.js - you would probably ask: What if i want to use THREE.BoxBufferGeometry
? - The answer is a buffer
property.
const cube = new WHS.Box({ geometry: { width: 10, height: 10, depth: 10 }, material: { kind: 'basic', color: 0x0095DD }, rot: { x: 0.4, y: 0.2 } }); cube.addTo(world);
cube.addTo()
method is used to apply this box to a specific world object that will render it and process collisions, "z-index" (Calculated by camera direction and other objects positions), it's color on rendered image (can depend on lights & shadows of other objects).
That's how combination of world & cube code looks in your browser:
You can try it right now:
{{JSFiddleEmbed("https://jsfiddle.net/4phf4oty/1/","","350")}}
- This JSFiddle uses
whitestorm.light.js
(A version without built-in physics). - You may also check the one with physics: https://jsfiddle.net/g2s5bgrL/
Components & Plugins
Almost each whitestorm.js class is a component. Box, Sphere, Tetrahedron - all these are components, but basic (simple Three.js geometries based on WHS.Shape).
Adding custom components is also welcome. To develop your own plugin/component you have to install generator-whs-plugin and follow it's instruction:
- Make a new repository.
- Install Yeoman:
npm install -g yo
- Install Whitestorm.js plugin generator:
npm install -g generator-whs-plugin
- Run
yo whs-plugin
. - Edit files in src/ for your needs. You will see already defined plugin source there, just change it as you want.
Playground
Playground is where you can create a basic whitestormjs app without downloading a WhitestormJS or setting up a project. You can also share your app with others by clicking “share” button and then you can share it in twitter, facebook or just copy to clipboard.
Conclusion
Whitestorm.js framework wil be best suitable for complex 3D browser games that rely on calculating objects transforms by collisions between them and other physics features. But flexibility of Whitestorm.js allows you to use it's API without parts you don't need, so usage in games that don't rely on physics on even basic apps or just beatiful websites is also welcome cause you can use whitestorm.light.js
that is more lightweight than whitestorm.js.
Links
- WhitestormJS website / API
- Github (Feel free to contribute)
- Playground
Tutorials
- Developing a street basketball game. Part I: Getting workflow ready
- Developing a street basketball game. Part ll: Throw a ball into a basket.
- Developing a street basketball game. Part lll: Level selecting and stats