Voxel.js文档——用js实现“我的世界”

用网页实现‘我的世界’,并且可以添加网页的基本功能

已实现网页

小记

本次创作是基于Voxel.js框架实现,但是该框架已发布8年,后期的维护工作并不完善,官网并无文档,并且官网介绍的voxel-hello-world启动文件包已在npm库中失效。作者由于对该框架很感兴趣就制作了该文档。以各个引入文件中的readme文件为主,源代码为辅总结。如有理解不当之处,欢迎批评指教。

Voxel.js官网地址:Voxel.js

文档作者csdn:lmmmmmnb

文档作者:YiDaoDo

简单的开始

1,创建你的web项目:只需要一个js文件(以下称为index.js)与html文件(以下称为index.html)
2,在你创建好的项目中执行

npm install voxel-engine --save-dev
npm install voxel-player --save -dev
npm install voxel-highlight --save -dev

下载好基础的三个包。(当然还有很多别的功能包,后期作者会同步上)
3,

npm install browserify -g

安装browserify为的是可以利用Node.js实现JS模块化加载
4,

var createGame =require('voxel-engine');//引入包
var Highlight = require('voxel-highlight')//引入包
var game=createGame(       //以该函数为基础创造世界 
    { 
    generate: function(x,y,z) {   //generate里面的函数为初始的地图创建函数  
    if (y==0){  
        return x*x+z*z <=55*55? 1:0 
        }else if(y==8&&x==0&&z==0){ 
        return 1    
        } 
    }, 
    texturePath:'textures/',      //引入纹理包。纹理包里面的图片都可以在voxel-engine包里面找到     
    materials: ["grass"]   //添加初始纹理(都是纹理包里面的)

      }
 );

var createPlayer=require('voxel-player')(game);   //引入包

game.appendTo(document.body);       //获得全屏

var substack=createPlayer('skin/shama.png');  //创建你的小人

substack.possess();      //小人获得移动视角

substack.yaw.position.set(3,30,0);    //小人初始位置

在index.js中加入上述代码.

5,

browserify index.js -o bundle.js

终端里执行该命令(用browserify加载你的index.js产生bundle.js)
然后在你的index.html引入bundle.js文件。运行你的html页面,这样初始世界就创建好了


以下是对于三个基础包函数解读

voxel-engine

1,generate创建世界的三维坐标并不是z轴朝上,是y轴朝上。x轴,z轴分别是:左右,前后。

2,texturePath:'textures/'是引用纹理
3,game.appendTo(document.body)
是获得页面
4,game.controls.target().avatar.position()
获取当前玩家位置
5,

game.setBlock(pos, 0) // off
game.setBlock(pos, 1) // on
game.setBlock(pos, 2) // on, with another material

pos是传的方块[x,y,z]的坐标,后面的数字决定该模块是否存在

6,game.voxels.voxelVector([x,y,z])
获取某个位置的体素坐标,
以下是该函数的源码

Chunker.prototype.voxelVector = function(pos) { 
var cubeSize = this.cubeSize  
var mask = (1 << this.chunkBits) - 1  
var vx = (Math.floor(pos[0] / cubeSize)) & mask  
var vy = (Math.floor(pos[1] / cubeSize)) & mask  
var vz = (Math.floor(pos[2] / cubeSize)) & mask 
return [vx, vy, vz]};

7,
game.voxels.chunkAtPosition([0,3,1])
根据方块的坐标来获取块

8,gameInstance.createBlock([x,y,z], val)
由于在传入的坐标处创建一个全新的块,
val可以是0-9,这些对应于您传递给游戏的材质数组。
(和setBlock差不多但是有一定的区别:这个会检查小人是否阻碍着新方块的创建,如果你不建议,完全可以用setBlock)

9,
gameInstance.getBlock([x,y,z])
用于获取某一位置方块的值

10,
game.raycastVoxels()
获取默认光影投射到的方块的信息(所谓光影就是小人身前的描点),可以在里面传入参数
gameInstance.raycastVoxels(start, position, distance)
来自定义光影投射。

11,
gameInstance.createAdjacent(raycastResults, materialIndex)
在此函数中传入光影投射结果,方块纹理参数。就可以在光影投射到的方块旁边创建新方块。

12,
game.on('tick', function(delta) {})
渲染函数,delta距离上次渲染发生的毫秒数

13,
game.on('mouseup', function(pos) {}), game.on('mousedown', function(pos) {})
鼠标点击事件函数,pos为点击方块的地址(未使用)

14,
game.on('collision', function(item) {})
回调函数,当item项目与小人操作发生碰撞,进行回调

15,
game.voxelRegion.on('change', function(pos) {})
小人发生移动时就会调用的函数

16,
game.chunkRegion.on('change', function(pos) {})
当小人在方块之间移动时会调用的函数

17,
game.on('renderChunk', function(chunk) {})
当方块被绘制时(使用showcunk方法)调用的函数。

18,
game.on('missingChunk', function(chunkPosition) {})
小人到尚未加载的区域时会调用

19,
game.on('dirtyChunkUpdate', function(chunk) {})
当方块被更改时会调用的函数。(例如setBlock)

20,
game.on('setBlock', function(pos, val, old) {})
只要game.setBlock函数被调用,该函数就会被调用。

21,
game.getCollisions(item.mesh.position, item)
返回与item的碰撞对象信息。(REANME记载,但是并未在源码中找到该函数)
22,
game.materials.load(['obsidian', 'dirt'], function(textures) { })
将纹理加入到纹理图集。前提是obsidian,dirt已经存在textures
23,

{
  materials: ["#fff", "#000", "#ff0000"],
  materialFlatColor: true
}

可以指定十六进制颜色作为材质,只要在创建时,传入以上参数

24,以下内容用来在世界添加自定义的是事务(村民,怪物,自定义方块)

var mesh = new game.THREE.Mesh(
  new game.THREE.CubeGeometry(1, 3, 1), // 宽,高,深
  game.materials.material
)

创建一个mesh,并将该世界已添加的纹理库赋予使用权。

game.materials.paint(mesh, 'obsidian')

向事物添加纹理库里的纹理。

mesh.position.set(0, 3, -5)

设定事务出现的位置

var item = game.addItem({
  mesh: mesh,
  size: 1,
  velocity: { x: 0, y: 0, z: 0 } // initial velocity
})

将你创建的事物添加的你的世界里

game.removeItem(item)

可使用该方法删除你已添加的方法

25,
setTimeout
setInterval
这两个函数是与电脑时间保持同步,但是当你的世界掉帧或者暂停,这个函数还是会跟着电脑的时间进行发生。
例如:

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

上述代码是让你的小人跟着电脑时间。每两秒跳一次。

game.setInterval(fn, duration[, args])
game.setTimeout(fn, duration[, args])
这两个函数是与游戏世界里的时间保持同步,当你游戏暂停,这个函数的时间也会暂停

var clearInterval = game.setInterval(function() {
  jump()
}, 2000)

上述代码是让你的小人跟着游戏时间。每两秒跳一次。
26,
关于voxel交换格式(没看懂,上源码)

{
  "voxels": [packed 1D array of voxels],
  "dimensions": [2, 2, 2],
  "position": [10, 10, 10]
}
  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}

voxel-player

1,var substack=createPlayer('maxogden.png');
给小人添加纹理

2,substack.possess();
给小人添加可移动视角

3,
substack.toggle();
切换小人第一人称和第三人称视角

4,
player.position.set(x, y, z)
给小人设置个初始位置

5,
player.subjectTo(forceVector)
使小人收到力矢量
6,
player.move(x, y, z)

player.move(vec)
小人刚开始降落到的位置
7,
player.moveTo(x, y, z)

player.move(pos)
和4差不多

8,player.pov(view)
将小人视角固定为第一人称或者第三人称

voxel-highlight

该文件主要是投影到方块时,方块的变化,以及信息获取等。

1,

var Highlight = require('voxel-highlight')
var highlighter = new Highlight(game)

通过这两行代码可以使投影投射到的方块出现高亮边框,并且可以获取到投影到的方块的信息。
也可以用以下代码代替:

var highlight = require('voxel-highlight')
var highlighter = highlight(game)
highlighter.on('highlight', function (voxelPosArray) {
  //添加你需要的代码
})

2,

{
  frequency: 以毫秒为单位高亮显示的频率,默认值为100
  distance: 游戏中应该突出显示的距离,默认值是10
  geometry: threejs用于高亮显示的几何体,默认为cubegeometry
  material: 用于几何体的材质,默认为线框(wireframe)
  wireframeLinewidth: 如果使用默认材质线框,则默认值为3(边框宽度)
  wireframeOpacity: 如果使用默认材质线框,则默认值为0.5(边框透明度)
  color: 高亮显示立方体颜色,默认值为0x000000
  animate: 动画高亮长方体的移动,默认为 false
  adjacentActive: 用于切换相邻突出显示的函数,默认值为 { return game.controls.state.alt }
  selectActive: 用于切换相邻高亮显示的函数,默认值为 { return game.controls.state.select }
  animateFunction: 用于简化位置更改的函数,详细请见该部分文档第三条
}

以上是可以在创建highlight时可以添加的选项

3,

opts.animateFunction = function (position, targetPosition, deltaTime) {
    if (!position || !targetPosition || !deltaTime) return;
    var rate = 10 // speed in voxels per second
    if (Math.abs(targetPosition[0] - position.x) < 0.05
     && Math.abs(targetPosition[1] - position.y) < 0.05
     && Math.abs(targetPosition[2] - position.z) < 0.05) {
      position.set(targetPosition[0], targetPosition[1], targetPosition[2])
      return; // close enough to snap and be done
    }
    deltaTime = deltaTime / 1000 // usually around .016 seconds (60 FPS)
    position.x += rate * deltaTime * (targetPosition[0] - position.x)
    position.y += rate * deltaTime * (targetPosition[1] - position.y)
    position.z += rate * deltaTime * (targetPosition[2] - position.z)
  }

animateFunction的使用

4,
highlighter.on('highlight', function(voxelPosArray) {})
方块被高亮显示时调用
5,
highlighter.on('remove', function(voxelPosArray) {})
方块高亮显示被取消时调用
6,
highlighter.on('highlight-adjacent', function(voxelPosArray) {})
相邻方块被高亮显示时调用
7,
highlighter.on('remove-adjacent', function(voxelPosArray) {})
相邻方块高亮显示被取消时调用

8,
highlighter.on('highlight-select', funnction(selectionBounds) {}
多个方块被高亮显示时调用

9,
highlighter.on('highlight-deselect', funnction(selectionBounds) {}
多个方块被取消高亮时调用

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值