Skip to content

方块的操作

如果你想要地图在非运行状态,通过脚本在场景中快速建造,可以尝试以下操作:

  1. 开启编辑器右上角的调试模式(小虫子图标)
  2. 使用窗口底部的控制台,输入对应的代码。

即使游戏没有运行,也能使部分代码直接生效。 使用控制台执行脚本前,请务必要小心,提前做好项目备份工作。一旦代码生效后,有可能造成无法恢复的情况。 要操作方块时,建议先使用空白地图对代码进行充分测试,效果满意后,再操作正式的地图。

方块旋转码

方块名称和方块id都是描述某位置方块的方法
方块名称只包含方块的类型
id包含方块的旋转码,在setVoxel方法不填rotation参数的情况下修改方块旋转码
方块正面面朝北方(-z方向)的旋转码数值上和将方块名称使用id方法转换后(即方块为初始旋转状态的id,也可说为不带旋转码)相同
方块正面面朝北方(-z方向)的旋转码为基准,取此时的旋转码为voxel,每顺时针转90°,方块voxel163840x4000
我们以泥土(方块名称为'dirt',id为125)为例:

  • 面向北方(-z方向)的旋转码为125 + 0 = 125
  • 面向东方(+x方向)的旋转码为125 + 16384 * 1 = 16509
  • 面向南方(+z方向)的旋转码为125 + 16384 * 2 = 32893
  • 面向西方(-x方向)的旋转码为125 + 16384 * 3 = 49277

若只是想判断方块的类型,应使用name将方块id转换成方块名称或者将方块id取模163840x4000)后再判断
这不只是为了规范和便于维护,因为方块的id会包含旋转码,旋转码会使直接判断方块id相等的方法无效(除非你把四个方向都考虑到)!

属性

shape

默认值:当前地图尺寸

当前世界地形最大尺寸。

定义于 #L10385


VoxelTypes

默认值:方块数组

返回包含所有方块名称的数组。

定义于 #L10390

方法

方块ID<互转>方块名称

id()

将方块id转换为方块名称

输入参数

参数必填默认值类型说明
namestring方块名称

返回值

类型说明
number方块ID

定义于 #L10396


name()

将方块名称转换为方块id

输入参数

参数必填默认值类型说明
idnumber方块ID

返回值

类型说明
string方块名称

定义于 #L10402


放置方块

setVoxel()

在指定的坐标位置放置一个方块。

输入参数

参数必填默认值类型说明
xnumber放置位置的x坐标
ynumber放置位置的y坐标
znumber放置位置的z坐标
voxelnumber | string方块名称或id
rotationnumber | string方块的旋转码(0,1,2,3)

返回值

类型说明
number新的方块id

定义于 #L10409

警告

若方块名称为'air' 或者方块id为0,则会打破

警告

voxel参数中包含的方块旋转码无效,实际旋转只和rotation参数有关

点击查看示例代码
javascript
// 利用循环批量设置方块
for(let x=0; x<127; x++){
  for(let z=0; z<127; z++){
    for(let y=9; y<127; y++){
      setVoxel(x, y, z, 'air')
    }}}

javascript
// 利用循环批量设置方块
for(let x=0; x<127; x++){
  for(let z=0; z<127; z++){
    setVoxel(x, 8, z, 'snow')
  }}

javascript
// 利用循环批量设置方块
for(let x=0; x<127; x++){
  for(let z=0; z<127; z++){
    for(let y=9; y<127; y++){
      setVoxel(x, y, z, 'air')
    }}}

javascript
// 根据地面的方块铺设,将方块往上增长5格高度的墙。
for(let x=0; x<127; x++){ 
  for(let z=0; z<127; z++){ 
    let vox = getVoxelId(x,9,z);
    if (!vox) continue // 如果没有方块则跳过
    for(let y = 10; y < 10+5; y++){ // 从y=10的位置开始增长5格
      setVoxel(x, y, z, vox);
    }
  }}

javascript
// 在指定位置放置字母方块
function voxelAlhpabet(str, x, y, z) {
  str = str.toUpperCase()  // 将字母转换为大写
  for(var i = 0; i < str.length; i++){
    var char = str[i]
    setVoxel(x+i, y, z, char);
  }
}

// 调用方法
voxelAlhpabet('hello world', 63, 20, 63)

javascript
// 将字符串与方块名称对应
const char_table = {
  0:'zero',
  1:'one',
  2:'two',
  3:'three',
  4:'four',
  5:'five',
  6:'six',
  7:'seven',
  8:'eight',
  9:'nine',
  '+':'add',
  '-':'subtract',
  '?':'question_mark',
  '!':'exclamation_mark',
  '=':'equal',
  ' ':'black',
  '&':'ampersand',
  '*':'asterisk',
  '@':'at',
  '\\':'backslash',
  ']':'bracket_close',
  '[':'bracket_open',
  '^':'caret',
  ':':'colon',
  ',':'comma',
  '$':'dollar',
  '>':'greater_than',
  '<':'less_than',
  '(':'paren_open',
  ')':'paren_close',
  '%':'percent',
  '.':'period',
  '#':'pound',
  '"':'quotation_mark',
  ';':'semicolon',
  '/':'slash',
  '~':'tilde',
}

// 如果符号在列表内,则放置列表对应名称的方块。否则直接放置字母方块。
function voxelText(str, x, y, z) {
  for (var i=0; i<str.length; i++) {
    var char = str[i].toUpperCase()
    var name = char_table[char]
    if (name) {
      setVoxel(x+i, y, z, name)
    } else {
      setVoxel(x+i, y, z, char)
    }
  }
}

// 在指定的位置,依次生成字符串方块
function voxelTextWall(words, x, y, z) {
  for (var i=0; i<words.length; i++) {
    voxelText(words[i], x, y-i, z)
  }
}

// 调用方法
voxelTextWall(['HELLO BOX3.0','2333'], 64, 13, 64)

javascript
// 棋盘方块
const B = {
  '+': id('board1'),
  'T': id('board4'),
  'L': id('board3'),
  '.': id('board2'),
}

// 方块旋转码
const R = {
  N: 0x8000,
  S: 0,
  E: 0xc000,
  W: 0x4000,
};

// 创建棋盘
function createBoard(originX, originY, originZ, size) {
  // 创建size * size的棋盘
  for (let x = 0; x < size; ++x) {
    for (let z = 0; z < size; ++z) {
      // 通常来讲是交点
      let p = B['+'];
      // 以下四个判断用于判断是否是边角
      if (x === 0 && z === 0) { 
        p = B['L'] | R['S'];
      } else if (x === 0 && z === size - 1) {
        p = B['L'] | R['E'];
      } else if (x === size -1 && z === 0) {
        p = B['L'] | R['W'];
      } else if (x === size -1 && z === size - 1) {
        p = B['L'] | R['N'];
        // 以下四个判断用于判断是否是边缘
      } else if (x === 0) {
        p = B['T'] | R['E'];
      } else if (x === size -1) {
        p = B['T'] | R['W'];
      } else if (z === 0) {
        p = B['T'] | R['S'];
      } else if (z === size -1) {
        p = B['T'] | R['N'];
      }
      // 放置方块
      setVoxelId(x + originX, originY, z + originZ, p);
    }
  }
}


// 调用方法: 在{x:32, y:9, z:32} 位置,创建19*19的棋盘
createBoard(32, 9, 32, 19)

setVoxelId()

使用方块ID,直接在指定的坐标位置放置方块。

信息

voxel参数包含的方块旋转码有效

输入参数

参数必填默认值类型说明
xnumber放置位置的x坐标
ynumber放置位置的y坐标
znumber放置位置的z坐标
voxelnumber方块id

返回值

类型说明
number新的方块id

定义于 #L10424


获取方块

getVoxel()

获取指定位置的方块ID

警告

用此方法获取的id不带旋转码

提示

由于其不带旋转码的特性,可以直接用此方法判断方块的id来判断的种类,而不是用name方法转换成方块名称后再比较

输入参数

参数必填默认值类型说明
xnumber获取位置的x坐标
ynumber获取位置的y坐标
znumber获取位置的z坐标

返回值

类型说明
number返回指定位置的方块id,不包含方块的旋转码

定义于 #L10414


getVoxelId()

直接获取指定位置的方块ID。

信息

用此方法获取的id带旋转码

输入参数

参数必填默认值类型说明
xnumber获取位置的x坐标
ynumber获取位置的y坐标
znumber获取位置的z坐标

返回值

类型说明
number返回指定位置的方块id

定义于 #L10429


getVoxelRotation()

获取某个坐标位置的方块旋转码

输入参数

参数必填默认值类型说明
xnumber获取位置的x坐标
ynumber获取位置的y坐标
znumber获取位置的z坐标

返回值

类型说明
number返回指定位置的方块旋转码(0,1,2,3)

定义于 #L10471

快速建造代码示例

javascript
/* 在指定位置快速建造一个实心的矩形 */
function cubefill(vox, sx, sy, sz, xsize, ysize, zsize){
  var xend = sx+xsize
  var yend = sy+ysize
  var zend = sz+zsize
  for(var x=sx;x<xend;x++){
    for(var y=sy;y<yend;y++){
      for(var z=sz;z<zend;z++){
        voxels.setVoxel(x,y,z,vox)
      }}}
}

cubefill('stone',64,9,64,10,5,10)   // 调用方法。在{x:64, y:9, z:64} 位置,建造一个长10格,宽5格,高10格的实心矩形

javascript
/* 在指定位置快速建造一个空心的矩形 */
function cube(vox, sx, sy, sz, xsize, ysize, zsize){
  var xend = sx+xsize
  var yend = sy+ysize
  var zend = sz+zsize
  for(var x=sx;x<xend;x++){
    for(var y=sy;y<yend;y++){
      for(var z=sz;z<zend;z++){
        if(x===sx || z===sz || x===xend-1 || z===zend-1 ){ //如果方块的位置在边缘
          voxels.setVoxel(x,y,z,vox)
        }
      }}}
}

cube('stone',64,9,64,10,5,10)  // 调用方法。在{x:64, y:9, z:64} 位置,建造一个长10格,宽5格,高10格的空心矩形

javascript
/* 在指定位置快速建造一个实心的球体 */
function sphere(vox, cx, cy, cz, radius){
  let xend = cx+radius
  let yend = cy+radius
  let zend = cz+radius
  for(let x=cx-radius;x<=xend;x++){
    for(let y=cy-radius;y<=yend;y++){
      for(let z=cz-radius;z<=zend;z++){
        let dx = x-cx;
        let dy = y-cy;
        let dz = z-cz;
        if(Math.round(Math.sqrt(dx*dx+dy*dy+dz*dz)) <= radius){
          voxels.setVoxel(x,y,z,vox)
        }
      }}}
}

sphere('stone',63,24,63,12) // 调用方法。在{x:63, y:24, z:63} 位置,建造一个半径为12格的实心球体

javascript
/* 在指定位置快速建造一个圆柱体 */
function cylinder(vox, cx, cy, cz, radius, height){
  let xend = cx+radius
  let yend = cy+height
  let zend = cz+radius
  for(let x=cx-radius; x<=xend; x++){
    for(let z=cz-radius; z<=zend; z++){
      let dx = x-cx;
      let dz = z-cz;
      if(Math.round(Math.sqrt(dx*dx+dz*dz)) <= radius){
        for(let y=cy; y<yend; y++){
          voxels.setVoxel(x,y,z,vox)
        }
      }
    }}
}

cylinder('stone',63,12,63,10,4)  // 调用方法。在{x:63, y:12, z:63} 位置,建造一个半径10格,高度4格的圆柱体

javascript
/* 在指定位置快速建造一个生成楼梯(+x轴方向) */
function stairs(sx, sy, sz, length, thickness){
  let xend = sx + length;
  let zend = sz + thickness;
  let i = 0;
  for(let x=sx; x < xend; x++){
    let yend = sy+i;
    i++;
    for(let y=sy; y<=yend; y++){
      for(let z=sz; z<zend; z++){
        voxels.setVoxel(x,y,z,'stone');
      }}
  }
}

stairs(63,9,63,6,4)  // 调用方法。在{x:63, y:9, z:63} 位置,建造一个高度6格,宽度4格的楼梯

javascript
/* 在指定位置快速建造一个生成楼梯(-x轴方向) */
function stairs(sx, sy, sz, length, thickness){
  let xend = sx + length;
  let zend = sz + thickness;
  let i = 0;
  for(let x=xend; x > sx; x--){ // 和前面+x轴方向的范例相比,此处正好相反
    let yend = sy+i;
    i++;
    for(let y=sy; y<=yend; y++){
      for(let z=sz; z<zend; z++){
        voxels.setVoxel(x,y,z,'stone');
      }}
  }
}

stairs(63,9,63,6,4)  // 调用方法。在{x:63, y:9, z:63} 位置,建造一个高度6格,宽度4格的楼梯