0.4.0 • Published 2 years ago

surreal-engine v0.4.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

Surreal Engine

NPM Package

A simple and powerful typescript game engine.

npm install --save surreal-engine

See examples at https://surreal-engine.onrender.com/examples

Usage

Let's create the simplest scene possible: A falling box. We have to initialize the engine and then create some entities based on existing templates. As a start create two boxes: one for the ground, and one for the falling box.

// Create a new instance of the engine with debug on
const engine = new Engine('#root', { debug: BasicDebug });
// Engine must be initialized before we can start adding components
await engine.init();

// Create a global lighting so our objects are visible
engine.new(GlobalLight, {
  color: '#ffffff',
  intensity: 0.5,
});

// Create a big white square as our ground
engine.new(Box, {
  size: new Vector3(25, 1, 25),
  mass: 0,
  restitution: 0.3,
  material: 'white',
  rigid: true,
  receiveShadow: true,
});

// Create a magenta box that will fall down.
engine.new(Box, {
  size: new Vector3(1, 1, 1),
  pos: new Vector3(0, 10, 0),
  mass: 0.5,
  restitution: 0.3,
  material: 'magenta',
  rigid: true,
  castShadow: true,
});

engine.start();

Now, let's add a ball after 1 second has passed.

engine.timer(() => {
  engine.new(Sphere, {
    radius: 1,
    pos: new Vector3(0, 10, 0),
    mass: 0.5,
    restitution: 0.3,
    material: 'yellow',
    rigid: true,
    castShadow: true,
  });
}, 1000, false);

Now, for some fun, let's make our ball more bouncy.

    mass: 0.5,
-   restitution: 0.3,
+   restitution: 2.5,
    material: 'yellow',
    rigid: true,

We now have a nice bouncy ball, yeeey. This still looks ugly. Notice the castShadow and receiveShadow options. Why aren't they working? It's because ambient lights cannot cast shadows. For that, we need a directionLight. So let's do that.

engine.new(DirectionalLight, {
  color: '#ffffff',
  intensity: 1,
  pos: new Vector3(-10, 10, 10),
  target: new Vector3(0, 0, 0),
  castShadow: true,
  shadowAreaHeight: 10,
  shadowAreaWidth: 10,
});

So much better. It would be nice if we could play around with the ball a bit, so let's add a character!

engine.new(Box, {
  size: new Vector3(2, 2, 2),
  pos: new Vector3(5, 0, 5),
  mass: 0.5,
  restitution: 0.5,
  material: 'red',
  rigid: true,
  castShadow: true,
  mods: [
    offsetCameraMod(),
    keyboardMotionMod(),
  ],
});

Entity templates can be moded to add new behaviour to them. That way, you can easily customize entities without having to create new entity templates. For our character, we want to apply the keyboardMotionMod, which allows us to move the character using WASD. Additionally, we want the camera to follow the character, so we apply the offsetCameraMod as well.

Note: Motion is not included in the base engine. It comes as a plugin instead. so we will have to register the plugin to the engine first:

engine.registerPlugin(new MotionPlugin());

Now we have nice red box that we can control. Let's have some more fun. Let's spawn a ball every 5 seconds, so we never run out of balls.

engine.timer(() => {
  engine.new(Sphere, {
    radius: 1,
    pos: new Vector3(0, 10, 0),
    mass: 0.5,
    restitution: 2.5,
    material: 'yellow',
    rigid: true,
    castShadow: true,
  });
- }, 1000, false);
+ }, 5000, true);

Check out a simple platformer tutorial here. (Work in Progress)

Alternatively take a look at the below examples to give you some ideas.

Examples