A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/deathcap/voxel-engine-stackgl below:

voxel/voxel-engine-stackgl: 3D HTML5 voxel game engine using stackgl

A voxel engine in javascript using stackgl

An experimental port of voxel-engine replacing three.js with stackgl

Caution: not all of the functionality of the three.js-based voxel-engine is implemented, documentation may be outdated, and the API may be unstable. Pull requests to improve this situation are greatly welcomed.

Learn more at http://voxeljs.com

Write a voxel.js game in browser: http://voxel-creator.jit.su

hello world template repo: http://github.com/deathcap/voxel-example

var createGame = require('voxel-example')
var game = createGame()

voxel-engine-stackgl is an OPEN Open Source Project. This means that:

Individuals making significant and valuable contributions are given commit-access to the project to contribute as they see fit. This project is more like an open wiki than a standard guarded open source project.

See the CONTRIBUTING.md file for more details.

voxel-engine-stackgl is only possible due to the excellent work of the following contributors:

require('voxel-engine-stackgl')(options)

Returns a new game instance. options defaults to:

{
  pluginLoaders: {
    'voxel-engine-stackgl': require('voxel-engine-stackgl'),
    'voxel-registry': require('voxel-registry'),
    'voxel-stitch': require('voxel-stitch'),
    'voxel-shader': require('voxel-shader'),
    'voxel-mesher': require('voxel-mesher'),
    'game-shell-fps-camera': require('game-shell-fps-camera')
  },
  pluginOpts: {},
  keybindings: {
    'W': 'forward',
    'A': 'left',
    'S': 'backward',
    'D': 'right',
    '<up>': 'forward',
    '<left>': 'left',
    '<down>': 'backward',
    '<right>': 'right',
    '<mouse 1>': 'fire',
    '<mouse 3>': 'firealt',
    '<space>': 'jump',
    '<shift>': 'crouch',
    '<control>': 'alt',
    '<tab>': 'sprint'
  },
  isClient: process.browser,
  generate: function(x,y,z) {
    return x*x+y*y+z*z <= 15*15 ? 1 : 0 // sphere world
  },
  generateVoxelChunk: function() {
    return require('voxel').generate(low, high, self.generate, self)
  },
  arrayType: Uint8Array,
  skyColor: 0xBFD1E5,
  chunkSize: 32,
  chunkPad: 4,
  chunkDistance: 2,
  removeDistance: 3,
  worldOrigin: [0, 0, 0],
  startingPosition: [35, 1024, 35],
  controls: {},
  generateChunks: true,
  asyncChunkGeneration: true,
  meshType: 'surfaceMesh',
  playerHeight: 1.62,
  pointerLock: true,
  stickyPointerLock: true,
  tickFPS: 16,
  exposeGlobal: false
}

Default 'player size' is a 1/2 block long/wide and 1.5 blocks high:

game.playerAABB().width() // => 12.5
game.playerAABB().height() // => 37.5

See implementation of Game.prototype.playerAABB for more details.

We try to always use arrays to represent vectors (aka positions)

Sometimes you may also see objects used, e.g. {x: 0, y: 0, z: 0}, this is because three.js uses objects for vectors.

Worlds have many chunks and chunks have many voxels. Chunks are cube shaped and are chunkSize x/y/z (default 32/32/32 - 32768 voxels per chunk). When the game starts it takes the worldOrigin and generates chunkDistance chunks in every x/y/z dimension (chunkDistance default of 2 means the game will render 2 chunks behind you, 2 in front etc for a total of 16 chunks.).

There is one major coordinate system in voxel.js: "game coordinates" (aka world coordinates)

There are also some other less used coordinate systems that you should be aware of:

When you create a game you can also pass functions that the game will ask for voxel data. Here is an example generate function that makes a randomly textured cube world with a diameter of 20 voxels:

function generator(x, y, z) {
  if (x*x + y*y + z*z > 20*20) return 0
  return Math.floor(Math.random() * 4) + 1
}

The generate function will be called once for each voxel in the world. x, y and z will be values in game coordinates.

Generate a flat world 1 block high

Flat world is a nicer way to start (at least you can't fall off the edge). This places the player just above the ground.

var game = createGame({
  generate: function(x, y, z) {
    return y === 1 ? 1 : 0
  }
})
Interacting with the voxel world Get current player position
game.controls.target().avatar.position()

This returns a THREE.js Vector3 object (which just means an object with 'x', 'y', and 'z').

game.setBlock(pos, 0) // off
game.setBlock(pos, 1) // on
game.setBlock(pos, 2) // on, with another material
Get the chunk at some world coordinates:

gameInstance.voxels.chunkAtPosition(position)

Get the voxel coordinates at some position (relative to that voxels chunk):

gameInstance.voxels.voxelVector(position)

Create a brand new voxel at some position.

Intended for use in first player contexts as it checks if a player is standing in the way of the new voxel. If you don't care about that then just use setBlock:

gameInstance.createBlock(pos, val)

val can be 0 or you can also use any single digit integer 0-9. These correspond to the materials array that you pass in to the game.

Set the value of a voxel at some position:

gameInstance.setBlock(pos, val)

Get the value of a voxel at some position:

gameInstance.getBlock(pos)

If you wanna see the lower level API for voxel data manipulation look at chunker.js inside the voxel module.

shoots a ray and collides with voxels

gameInstance.raycastVoxels(start, position, distance)

if you just type gameInstance.raycastVoxels() it will default to using the current main camera position and direction, and default distance of 10, and epsilon of 1e-8

you will get back an object with the precise position, voxel position, direction, face normal and voxel value of the voxel that you intersected, or false if there was no collision

Create a new voxel adjacent to an existing voxel

first do a .raycastVoxels() then do gameInstance.createAdjacent(raycastResults, materialIndex)

There are a number of events you can listen to once you've instantiated a game. we use the node.js event emitter library which uses the following syntax for subscribing:

emitter.on('eventname', function(arg1, arg2, etc) {})

game.on('mouseup', function(pos) {}), game.on('mousedown', function(pos) {})

Captures mouse activity. pos is the game coordinate of the intersection of the voxel that you clicked on (if any)

game.on('tick', function(delta) {})

emits every time the game renders (usually no more than 60 times a second). delta is the time in milliseconds between this render and the last render

game.on('collision', function(item) {})

Called every tick when an item is colliding with the player. Callback is passed the item that is colliding.

game.voxelRegion.on('change', function(pos) {})

emits when you move between voxels. pos has x, y, and z voxel coordinates of the voxel you just entered

`game.chunkRegion.on('change', function(pos) {})``

emits when you move between chunks. pos has x, y, and z chunk coordinates of the chunk you just entered

game.on('renderChunk', function(chunk) {})

emits when a chunk is drawn (using the showChunk method). chunk is the full chunk object, which has the voxel data and a .position and .dims

game.on('missingChunk', function(chunkPosition) {})

emits when the player moves into range of a chunk that isn't loaded yet. if your game has generateChunks set to true it will automatically create the chunk and render it but if you are providing your own chunk generation then you can use this to hook into the game.

game.on('dirtyChunkUpdate', function(chunk) {})

emits when game updates a chunk, this is usually triggered when a chunk gets edited. if game.setBlock were to get called 50 times on one chunk in between renders, dirtyChunkUpdate will emit once with the chunk the chunk that gets updated

game.on('setBlock', function(pos, val, old) {})

emits whenever game.setBlock gets called

Check for collisions between an item and other 'things'

Detects collisions between an item and other items, or voxels.

game.getCollisions(item.mesh.position, item)

This will give you back a 'collisions object' whose keys are positions on the object and values are arrays of the positions of faces that are colliding.

For example, here we have 4 faces colliding with the bottom of our object:

{
  back: Array[0]
  bottom: Array[4]
  down: Array[1]
  forward: Array[0]
  left: Array[0]
  middle: Array[0]
  right: Array[0]
  top: Array[0]
  up: Array[0]
}

Loading textures onto the texture atlas.

game.materials.load(['obsidian', 'dirt'], function(textures) { })

Both of these textures will be loaded into the texture atlas and expanded creating 2 voxel block types.

Texture-less worlds with flat colors

You can specify hex colors to use as materials, just pass these options when creating a game:

{
  materials: ["#fff", "#000", "#ff0000"],
  materialFlatColor: true
}
Example: Creating an Item
// create a mesh and use the internal game material (texture atlas)
var mesh = new game.THREE.Mesh(
  new game.THREE.CubeGeometry(1, 3, 1), // width, height, depth
  game.materials.material
)

// paint the mesh with a specific texture in the atlas
game.materials.paint(mesh, 'obsidian')

// move the item to some location
mesh.position.set(0, 3, -5)

var item = game.addItem({
  mesh: mesh,
  size: 1,
  velocity: { x: 0, y: 0, z: 0 } // initial velocity
})
// use `game.removeItem(item)` to remove
{
  "voxels": [packed 1D array of voxels],
  "dimensions": [2, 2, 2],
  "position": [10, 10, 10]
}

this should be generated by something like this:

  var length = 5, width = 5, depth = 5
  var start = [10, 10, 10]
  var voxels = new Int8Array(length * width * depth)
  var idx = 0
  for(var z = start[2]; z < depth; ++z)
  for(var y = start[1]; y < height; ++y)
  for(var x = start[0]; x < length; ++x, ++idx) {
    voxels[idx] = getVoxelDataFor(x+start[0], y+start[1], z+start[2])
  }
  return {voxels: voxels, dimensions: [length, width, height], position: start}

setTimeout and setInterval work fine when timing things against the computer's clock but what about staying in sync with the game's clock? When the game lags, is paused or hasn't begun you probably don't want your timed operations firing.

game.setInterval(fn, duration[, args]) and game.setTimeout(fn, duration[, args]) are available and similar to the built in interval functions but stay in sync with the game's clock.

An example is we want our object to jump every 2 seconds. Normally we'd just do:

setInterval(function() {
  jump()
}, 2000)

But if the game's frame rate drops or the game hasn't begun the computer will still fire the jump() function every 2 seconds. Thus causing the object to fly way up into the air.

var clearInterval = game.setInterval(function() {
  jump()
}, 2000)
// later we can stop the interval by calling clearInterval()

Will achieve the same thing although now when the game's frame rate drops the jump() function won't be called repeatedly and the object will jump at the desired frequency.

basically https://github.com/felixge/node-style-guide#nodejs-style-guide with a couple of minor changes:

any contributions (pull requests) in any style are welcome, as long as:

if you send a pull request and you use, for example, 4 space indents it will not be rejected but please try to follow conventions when you can

BSD (see LICENSE)


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4