-
Notifications
You must be signed in to change notification settings - Fork 92
Explaining hello world
Let's look through all the code in the hello-world
example, and explain what each line does.
'use-strict'
Click here to learn what it does.
import Engine from 'noa-engine'
Imports the Noa Engine
var opts = {
debug: true,
showFPS: true,
chunkSize: 32,
chunkAddDistance: 2.5,
chunkRemoveDistance: 3.5,
}
These are the main options for the game, most of them do not have to be set. Here is a list of them and what they do:
-
debug: boolean
- Turns on or off debug mode for Noa. -
showFPG: boolean
- Turns on or off the FPS counter on the top right side of the screen. -
inverseY: boolean
- Invert the mouse Y. -
inverseX: boolean
- Invert the mouse X. -
chunkSize: int
- The size of chunks. Recommended value is 32. -
chunkAddDistance: float
- How far away you have to be before a chunk loads. -
chunkRemoveDistance: float
- How far away you have to be before a chunk unloads. -
blockTestDistance: int
- ? (someone please fill this) -
texturePath: string
- The main texture path. -
playerStart: float[3]
- The starting position of the player. -
playerHeight: float
- The height of the player. -
playerWidth: float
- The width of the player. -
playerAutoStep: boolean
- Weather the player can step up blocks or not. -
useAO: boolean
- Use Ambient Occlusion, -
AOmultipliers: float[3]
- ? (someone please fill this) -
reverseAOmultiplier: float
- ? (someone please fill this) -
tickRate: int
- How many milliseconds long thetick
event is. -
skipDefaultHighlighting: boolean
- If you hover over a block is show a highlight. This enables/disables that.
var noa = new Engine(opts)
Creates the Noa Engine.
var textureURL = null
In this example, there are no textures, so we use null.
var brownish = [0.45, 0.36, 0.22]
var greenish = [0.1, 0.8, 0.2]
The colors in RGB (Decimal)
noa.registry.registerMaterial('dirt', brownish, textureURL)
noa.registry.registerMaterial('grass', greenish, textureURL)
Registers the materials used by the blocks. The first argument is the name of the material, the second is the color, and the last is the texture, which is null in this case.
var dirtID = noa.registry.registerBlock(1, { material: 'dirt' })
var grassID = noa.registry.registerBlock(2, { material: 'grass' })
Next we register the blocks. These functions return the block ID so they are stored into a variable. The first argument is the block ID (0 is taken by air) and the second is a object which references the material. Another thing you can put in the object is whether the block is opaque or not using: opaque: boolean
.
function getVoxelID(x, y, z) {
if (y < -3) return dirtID
var height = 2 * Math.sin(x / 10) + 3 * Math.cos(z / 20)
if (y < height) return grassID
return 0 // signifying empty space
}
This is a function for the world generation.
noa.world.on('worldDataNeeded', function (id, data, x, y, z) {
// `id` - a unique string id for the chunk
// `data` - an `ndarray` of voxel ID data (see: https://github.com/scijs/ndarray)
// `x, y, z` - world coords of the corner of the chunk
for (var i = 0; i < data.shape[0]; i++) {
for (var j = 0; j < data.shape[1]; j++) {
for (var k = 0; k < data.shape[2]; k++) {
var voxelID = getVoxelID(x + i, y + j, z + k)
data.set(i, j, k, voxelID)
}
}
}
// tell noa the chunk's terrain data is now set
noa.world.setChunkData(id, data)
})
This is a event. A event is called when something happens, in this case when a new chunk is loaded. In the event we loop through all the blocks and use the getVoxelID
function to set the block, generating the world.
var player = noa.playerEntity
var dat = noa.entities.getPositionData(player)
var w = dat.width
var h = dat.height
These variables get info from the player to make the player a mesh, which gives the player a appearance, instead of nothing.
import { Mesh } from '@babylonjs/core/Meshes/mesh'
var scene = noa.rendering.getScene()
var mesh = Mesh.CreateBox('player-mesh', 1, scene)
mesh.scaling.x = w
mesh.scaling.z = w
mesh.scaling.y = h
We import the Mesh class from Babylon and use it to make the actual mesh.
// add "mesh" component to the player entity
// this causes the mesh to move around in sync with the player entity
noa.entities.addComponent(player, noa.entities.names.mesh, {
mesh: mesh,
// offset vector is needed because noa positions are always the
// bottom-center of the entity, and Babylon's CreateBox gives a
// mesh registered at the center of the box
offset: [0, h / 2, 0],
})
Comments says it all.
noa.inputs.down.on('fire', function () {
if (noa.targetedBlock) noa.setBlock(0, noa.targetedBlock.position)
})
This is another event, this time for inputs. If the fire
input is pressed (binded to left-click) we check if the block that the player is looking at is not air, if isn't air, we set the targeted block (the block you are looking at) to air.
noa.inputs.down.on('alt-fire', function () {
if (noa.targetedBlock) noa.addBlock(grassID, noa.targetedBlock.adjacent)
})
This is the same as above but we place a block using addBlock
instead.
noa.inputs.bind('alt-fire', 'E')
This binds alt-fire
(which is already binded to right-click) another key of E. So pressing right-click or E do the same thing.
noa.on('tick', function (dt) {
var scroll = noa.inputs.state.scrolly
if (scroll !== 0) {
noa.camera.zoomDistance += (scroll > 0) ? 1 : -1
if (noa.camera.zoomDistance < 0) noa.camera.zoomDistance = 0
if (noa.camera.zoomDistance > 10) noa.camera.zoomDistance = 10
}
})
This event is called every tick, which is ran around 30 times per second at default. Then we check the scrolling, and zoom the camera in and out.
This page was created by: EliteAsian123.