@3d-dice/dice-box 中文文档教程
Dice-Box
使用 BabylonJS、AmmoJS 并使用 网络工作者 和 offscreenCanvas。
Demo
0.5 版的新演示!
在 https://d3rivgcgaqw1jo.cloudfront.net/index.html 试用厨房水槽演示
请在此处查看厨房水槽代码演示:https://codesandbox.io/s/3d-dice-demo-2bily5
这是滚动属性的简单 React 演示(使用 3d6):https://codesandbox.io/s/react-roller-attributes-6jjiod
这是一个支持高级骰子符号的 React 演示:https://codesandbox.io/s/react-roller-advanced-notation-xl8foh
注意:一些演示包括其他 @3d-dice
模块,例如dice-roller-parser, FUI 和 FDP。 此处支持高级骰子符号,例如 4d6dl1
或 4d6!r<2
Quickstart (sort of)
安装库使用:
npm install @3d-dice/dice-box
安装库后,您需要将一些文件复制到您的开发文件夹。 它们可以在 @3d-dice/dice-box/src/assets
文件夹中找到。 将此文件夹中的所有内容复制到本地静态资产或公共文件夹。
这是一个 ES 模块,旨在成为构建系统的一部分。 要将模块导入您的项目,请使用:
import DiceBox from '@3d-dice/dice-box'
然后创建 DiceBox
类的新实例。 参数首先是目标 DOM 节点的选择器,然后是配置选项的对象。 请务必将路径设置为之前复制的资产文件夹。 这是唯一必需的配置选项。
const diceBox = new DiceBox("#dice-box", {
assetPath: '/assets/'
})
接下来初始化类对象,然后它将准备好掷一些骰子。 init
方法是一个异步方法,因此它可以等待或跟在 .then()
方法之后。
diceBox.init().then(()=>{
diceBox.roll('2d20')
})
Usage
Dice-Box 只能接受简单的骰子符号和修饰符,如 2d20
或 2d6+4
一旦骰子停止滚动,它会返回一个结果对象。 对于更高级的滚动功能,您需要查看添加支持完整 Roll20 骰子规格。
Configuration Options
| 选项 | 默认设置|说明| |-|-|-| |id|'dice-canvas'|要使用的画布元素的 ID。 如果不存在画布,则将创建一个| |assetPath|'/assets/'|此模块所需文件的路径| |重力|3|太大的重力会导致骰子抖动。 太少,他们需要更长的时间才能安顿下来。 |质量|3|骰子的质量。 影响力如何作用在骰子上,例如自旋| |摩擦力|.8|骰子与骰子盒之间的摩擦力| |恢复|0|骰子的弹性| |angularDamping|.4|确定骰子失去旋转的速度(角动量)| |linearDamping|.5|确定骰子失去线性动量的速度| |spinForce|6|骰子的最大旋转量| |throwForce|2.5|使用的最大投掷力| |startingHeight|15|抛球开始的高度| |settleTimeout|5000|模具停止移动之前的时间(以毫秒为单位)| |offscreen|true|如果offscreenCanvas可用,它将被使用| |delay|10|生成骰子之间的延迟。 如果它们同时生成,它们会立即相互碰撞,这看起来不太自然。| |enableShadows|true|骰子投射阴影吗? 关闭性能提升| |theme|'purpleRock'|十六进制颜色值或'purpleRock'、'diceOfRolling'、'galvanized'之一。| |规模|4| 选项最好在 2-9 之间。 数字越大,骰子越大。 接受十进制数 |
Die Types
本文档经常引用常见的骰子符号,例如 5d6
,其中第一个数字表示要掷的骰子数,d#
表示骰子的面数。 目前支持的骰子有d4
, d6
, d8
, d10
, d12
, < code>d20 和 d100
Common Objects
Roll Object
{
modifier: int, // optional - the modifier (positive or negative) to be added to the final results
qty: int, // the number of dice to be rolled
sides: int, // the type of die to be rolled
theme: string, // optional - the theme for this roll
}
Individual Die Result Object
{
groupId: int, // the roll group this die belongs to
rollId: int, // the unique identifier for this die within the group
sides: int, // the type of die
theme: string, // the theme that was assigned to this die
value: int, // the roll result for this die
}
Roll Result Array Object
[
{ // the roll group object
id: 0, // the id of this group - should match the groupId of rolls
modifier: int, // the modifier that was added to the final value
qty: int, // the number of dice in this roll
rolls: [ // an array of Die Result Objects
{
groupId: int,
rollId: int,
sides: int,
theme: string,
value: int,
}
],
sides: int, // the type of die used
theme: string // the theme for this group of dice
value: int // the sum of the dice roll results and modifier
}
]
3d6
的结果对象看起来像这样
[
{
qty: 3,
sides: 6,
mods: [],
rolls: [
{
sides: 6,
groupId: 0,
rollId: 0,
theme: 'diceOfRolling',
value: 5
},
{
sides: 6,
groupId: 0,
rollId: 1,
theme: 'diceOfRolling',
value: 2
},
{
sides: 6,
groupId: 0,
rollId: 2,
theme: 'diceOfRolling',
value: 3
}
],
id: 0,
value: 10
}
]
What's the difference between groupId
, and rollId
?
groupId:这个骰子的滚动组是部分。 这对于接受诸如 2d10+2d6
之类的符号的高级骰子滚筒变得更加有用。 在这种情况下,groupId: 0
将分配给 2d10,groupId: 1
将分配给 2d6
rollId:骰子的 ID组内。 默认情况下,这是由骰子滚筒自动递增的,但是在某些情况下会分配 rollId,例如爆炸骰子。 在这种情况下,为了在“exploder”和“explodee”之间建立关联,将添加的骰子的 rollId 设置为触发骰子的十进制值。 例如,1d6 会爆炸两次:
[
{
qty: 3,
sides: 6,
mods: [
{
type: 'explode',
target: null
}
],
rolls: [
{
sides: 6,
groupId: 0,
rollId: 0,
theme: 'diceOfRolling',
value: 6
},
{
sides: 6,
groupId: 0,
rollId: 0.1,
theme: 'diceOfRolling',
value: 6
},
{
sides: 6,
groupId: 0,
rollId: 0.2,
theme: 'diceOfRolling',
value: 5
}
],
id: 0,
value: 17
}
]
Methods
Promised based rolls
方法 .roll()
、.add()
、.reroll()
和 。 remove()
是所有返回包含被调用者掷骰子结果的承诺的方法。 所以可以这样写 DiceBox.roll('4d6').then(results => console.log(results))
。 还可以从 onRollComplete
回调事件或使用 .getRollResults()
方法(不是承诺)检索结果。
Roll
掷骰将清除当前的骰子并开始新的掷骰。
roll(notation:mixed, options = {theme:string})
notation 参数可以接受以下滚动格式
- string notation:
'3d6'
or with a simple modifier'3d6+2'
- an array of strings:
['2d10','1d6']
- a roll object:
{sides:6, qty:3}
- an array of roll objects:
[{qty:2, sides:10},{qty:1, sides:6}]
options 参数允许为此滚动组定义主题。
Themes
可以在三个地方指定主题。 在初始化时的配置对象上,在使用
.roll()
或.add()
时作为选项参数,或者在 roll 对象上指定 或 die 结果对象。 主题的应用顺序为:滚动对象第一,选项参数第二,框配置选项第三。
diceBox.roll('2d20',{theme:'#4b8968'}) // returns a Promise with an array of die results
Add
此方法将指定的符号添加到新滚动组中的当前滚动。
add(notation:mixed, options = {theme:string, newStartPoint:boolean})
可接受的参数与 .roll()
相同。 选项 newStartPoint
将从盒子边缘的新点开始掷骰子(默认为 true)
diceBox.add('1d8',{newStartPoint: false}) // returns a Promise with an array of die results for the dice that were added
Reroll
此方法将重新掷骰子。
reroll(notation:mixed, options = {remove:boolean, newStartPoint:boolean})
这里的符号参数需要一个 roll 对象或一个 roll 对象数组,用于标识你希望重新滚动的 roll 组 groupId
和 die rollId
。 先前掷骰的结果对象是有效参数,可以传入以触发重新掷骰。 remove 选项表示正在重新滚动的骰子应该从场景中移除。 选项 newStartPoint
将从盒子边缘的一个新点开始掷骰子(默认为 true)。
diceBox.reroll({
groupId: 0,
rollId: 2
}) // returns a Promise with an array of die results for the dice that were rerolled
Remove
从场景中移除骰子
remove(notation:mixed)
这里的符号与 .reroll()
相同,
diceBox.remove({
groupId: 0,
rollId: 2
}) // returns a Promise with an array of die results for the dice that were removed
Clear
这将从骰子盒中清除所有骰子。
diceBox.clear()
Hide
这将隐藏骰子盒渲染到的画布元素。
diceBox.hide()
Show
这将显示骰子盒渲染到的画布元素。
diceBox.show()
Get Roll Results
随时获取场景中所有骰子的结果。 但是,如果骰子仍在滚动,则它们还没有价值。
diceBox.getRollResults() // returns an array of roll result objects
Callbacks
onDieComplete
只要单个骰子完成滚动并包含骰子结果对象作为参数,就会触发此回调。
Box.onDieComplete = (dieResult) => console.log('die result', dieResult)
onRollComplete
只要所有骰子都已完成滚动和/或物理模拟已停止并包含滚动结果对象作为参数,就会触发此回调。
Box.onRollComplete = (rollResult) => console.log('roll results', rollResult)
onRemoveComplete
只要从场景中移除骰子并包含作为参数移除的骰子结果对象,就会触发此回调。
Box.onRemoveComplete = (dieResult) => console.log('die removed', dieResult)
Other setup options
在我的演示项目中,我将其设置如下所示。 您可能不需要 BoxControls
,但使用它们很有趣。 请在此处的代码沙盒中查看此演示:https://codesandbox.io/s/3d-dice-demo-2bily5
import './style.css'
import DiceBox from '@3d-dice/dice-box'
import { DisplayResults, AdvancedRoller, BoxControls } from '@3d-dice/fui'
let Box = new DiceBox("#dice-box",{
assetPath: '/assets/dice-box/',
})
document.addEventListener("DOMContentLoaded", async() => {
Box.init().then(()=>{
const Controls = new BoxControls({
onUpdate: (updates) => {
Box.updateConfig(updates)
}
})
// create display overlay
const Display = new DisplayResults("#dice-box")
// create Roller Input
const Roller = new AdvancedRoller({
target: '#dice-box',
onSubmit: (notation) => Box.roll(notation),
onClear: () => {
Box.clear()
Display.clear()
},
onReroll: (rolls) => {
// loop through parsed roll notations and send them to the Box
rolls.forEach(roll => Box.add(roll))
},
onResults: (results) => {
Display.showResults(results)
}
})
// pass dice rolls to Advanced Roller to handle
Box.onRollComplete = (results) => {
Roller.handleResults(results)
}
})
html,
body {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#dice-box {
position: relative;
box-sizing: border-box;
width: 100%;
height: 100%;
background-image: url(./assets/woodgrain2.jpg);
background-size: cover;
}
#dice-box canvas {
width: 100%;
height: 100%;
}
Other Projects
如果您正在寻找适用于 three.js 比我推荐的 Dice So Nice< /a>
Dice-Box
High performance 3D dice roller made with BabylonJS, AmmoJS and implemented with web workers and offscreenCanvas.
Demo
New demo for version 0.5!
Try out the kitchen sink demo at https://d3rivgcgaqw1jo.cloudfront.net/index.html
See the kitchen sink code demo here: https://codesandbox.io/s/3d-dice-demo-2bily5
Here's a simple React Demo for rolling attributes (using 3d6): https://codesandbox.io/s/react-roller-attributes-6jjiod
Here's a React Demo with support for advanced dice notation: https://codesandbox.io/s/react-roller-advanced-notation-xl8foh
Note: Some demos includes other @3d-dice
modules such as dice-roller-parser, FUI, and FDP. Advanced dice notation is supported here such as 4d6dl1
or 4d6!r<2
Quickstart (sort of)
Install the library using:
npm install @3d-dice/dice-box
After installing the library, you'll need to copy some files over to your development folder. They can be found in the @3d-dice/dice-box/src/assets
folder. Copy everything from this folder to your local static assets or public folder.
This is an ES module intended to be part of a build system. To import the module into your project use:
import DiceBox from '@3d-dice/dice-box'
Then create a new instance of the DiceBox
class. The arguments are first a selector for the target DOM node followed by an object of config options. Be sure to set the path to the assets folder copied earlier. It's the only required config option.
const diceBox = new DiceBox("#dice-box", {
assetPath: '/assets/'
})
Next you initialize the class object then it will be ready to roll some dice. The init
method is an async method so it can be awaited or followed by a .then()
method.
diceBox.init().then(()=>{
diceBox.roll('2d20')
})
Usage
Dice-Box can only accept simple dice notations and a modifier such as 2d20
or 2d6+4
It returns a result object once the dice have stopped rolling. For more advanced rolling features you'll want to look at adding @3d-dice/dice_roller which supports the full Roll20 Dice Specification.
Configuration Options
| Option | Default Setting|Description| |-|-|-| |id|'dice-canvas'|The ID of the canvas element to use. If no canvas present then one will be created| |assetPath|'/assets/'|The path to files needed by this module| |gravity|3|Too much gravity will cause the dice to jitter. Too little and they take much longer to settle. |mass|3|The mass of the dice. Affects how forces act on the dice such as spin| |friction|.8|The friction of the dice and the dice box they roll on| |restitution|0|The bounciness of the dice| |angularDamping|.4|Determines how quickly the dice lose their spin (angular momentum)| |linearDamping|.5|Determines how quickly the dice lose their linear momentum| |spinForce|6|The maximum amout of spin the dice may have| |throwForce|2.5|The maximum amout of throwing force used| |startingHeight|15|The height at which the toss begins| |settleTimeout|5000|Time in ms before a die is stopped from moving| |offscreen|true|If offscreenCanvas is available it will be used| |delay|10|The delay between dice being generate. If they're all generated at the same time they instantly collide with each other which doesn't look very natural.| |enableShadows|true|Do the dice cast a shadow? Turn off for a performance bump| |theme|'purpleRock'|HEX color value or one of 'purpleRock', 'diceOfRolling', 'galvanized'.| |scale|4| Options are best between 2-9. The higher the number the larger the dice. Accepts decimal numbers |
Die Types
This documentation makes frequent reference to common dice notations such as 5d6
where the first number represents the number of dice to roll and the d#
represents the number of sides on a die. Currently support dice are d4
, d6
, d8
, d10
, d12
, d20
, and d100
Common Objects
Roll Object
{
modifier: int, // optional - the modifier (positive or negative) to be added to the final results
qty: int, // the number of dice to be rolled
sides: int, // the type of die to be rolled
theme: string, // optional - the theme for this roll
}
Individual Die Result Object
{
groupId: int, // the roll group this die belongs to
rollId: int, // the unique identifier for this die within the group
sides: int, // the type of die
theme: string, // the theme that was assigned to this die
value: int, // the roll result for this die
}
Roll Result Array Object
[
{ // the roll group object
id: 0, // the id of this group - should match the groupId of rolls
modifier: int, // the modifier that was added to the final value
qty: int, // the number of dice in this roll
rolls: [ // an array of Die Result Objects
{
groupId: int,
rollId: int,
sides: int,
theme: string,
value: int,
}
],
sides: int, // the type of die used
theme: string // the theme for this group of dice
value: int // the sum of the dice roll results and modifier
}
]
The result object for 3d6
will look something like this
[
{
qty: 3,
sides: 6,
mods: [],
rolls: [
{
sides: 6,
groupId: 0,
rollId: 0,
theme: 'diceOfRolling',
value: 5
},
{
sides: 6,
groupId: 0,
rollId: 1,
theme: 'diceOfRolling',
value: 2
},
{
sides: 6,
groupId: 0,
rollId: 2,
theme: 'diceOfRolling',
value: 3
}
],
id: 0,
value: 10
}
]
What's the difference between groupId
, and rollId
?
groupId: the roll group this die is a part of. This becomes more useful with the advanced dice roller that accepts notations such as 2d10+2d6
. In this case groupId: 0
would be assigned to the 2d10 and groupId: 1
would be assigned to the 2d6
rollId: the id of the die within the group. By default this is incremented automatically by the dice roller, however there are cases where the rollId is assigned, such as exploding die. In this case, in order to make an association between the 'exploder' and the 'explodee' the rollId of the added die is set to a decimal value of the triggering die. For example with 1d6 that explodes twice:
[
{
qty: 3,
sides: 6,
mods: [
{
type: 'explode',
target: null
}
],
rolls: [
{
sides: 6,
groupId: 0,
rollId: 0,
theme: 'diceOfRolling',
value: 6
},
{
sides: 6,
groupId: 0,
rollId: 0.1,
theme: 'diceOfRolling',
value: 6
},
{
sides: 6,
groupId: 0,
rollId: 0.2,
theme: 'diceOfRolling',
value: 5
}
],
id: 0,
value: 17
}
]
Methods
Promised based rolls
The methods .roll()
,.add()
, .reroll()
and .remove()
are all methods that return a promise containing the results of the dice rolled by the callee. So it is possible to write DiceBox.roll('4d6').then(results => console.log(results))
. Results can also be retrieved from the onRollComplete
callback event or by using the .getRollResults()
method (not a promise).
Roll
A roll will clear current dice and start a new roll.
roll(notation:mixed, options = {theme:string})
The notation argument can accept the following roll formats
- string notation:
'3d6'
or with a simple modifier'3d6+2'
- an array of strings:
['2d10','1d6']
- a roll object:
{sides:6, qty:3}
- an array of roll objects:
[{qty:2, sides:10},{qty:1, sides:6}]
The options argument allows for defining a theme for this roll group.
Themes
Themes can be specified in three places. On the config object at initialization, as an options parameter when using
.roll()
or.add()
, or as specified on a roll object or die result object. Themes are applied in the order of roll object first, options parameter second and box config option third.
diceBox.roll('2d20',{theme:'#4b8968'}) // returns a Promise with an array of die results
Add
This method will add the specified notation to the current roll in a new roll group.
add(notation:mixed, options = {theme:string, newStartPoint:boolean})
The acceptable arguments are the same as .roll()
. The option newStartPoint
will toss the dice in from a new point along the edge of the box (defaults to true)
diceBox.add('1d8',{newStartPoint: false}) // returns a Promise with an array of die results for the dice that were added
Reroll
This method will reroll a die.
reroll(notation:mixed, options = {remove:boolean, newStartPoint:boolean})
The notation argument here requires an roll object or an array of roll objects identifying the roll group groupId
and die rollId
you wish to reroll. Die result objects from previous rolls are valid arguments and can be passed in to trigger a reroll. The remove option indicates the die being rerolled should be removed from the scene. The option newStartPoint
will toss the dice in from a new point along the edge of the box (defaults to true).
diceBox.reroll({
groupId: 0,
rollId: 2
}) // returns a Promise with an array of die results for the dice that were rerolled
Remove
Remove dice from the scene
remove(notation:mixed)
The notation here is the same a .reroll()
diceBox.remove({
groupId: 0,
rollId: 2
}) // returns a Promise with an array of die results for the dice that were removed
Clear
This will clear all dice from the dice box.
diceBox.clear()
Hide
This will hide the canvas element that the dice box is rendered to.
diceBox.hide()
Show
This will show the canvas element that the dice box is rendered to.
diceBox.show()
Get Roll Results
Get the results of all the dice in the scene at anytime. However, if dice are still rolling they will not have a value yet.
diceBox.getRollResults() // returns an array of roll result objects
Callbacks
onDieComplete
This callback is triggered whenever an individual die has completed rolling and contains the die result object as it's argument.
Box.onDieComplete = (dieResult) => console.log('die result', dieResult)
onRollComplete
This callback is triggered whenever all the dice have finished rolling and/or the physics simulation has been stopped and contains the roll result object as it's argument.
Box.onRollComplete = (rollResult) => console.log('roll results', rollResult)
onRemoveComplete
This callback is triggered whenever a die has been removed from the scene and contains the die result object that was removed as it's argument..
Box.onRemoveComplete = (dieResult) => console.log('die removed', dieResult)
Other setup options
In my demo project I have it set up as seen below. You probably won't need the BoxControls
but they're fun to play with. See this demo in Code Sandbox here: https://codesandbox.io/s/3d-dice-demo-2bily5
import './style.css'
import DiceBox from '@3d-dice/dice-box'
import { DisplayResults, AdvancedRoller, BoxControls } from '@3d-dice/fui'
let Box = new DiceBox("#dice-box",{
assetPath: '/assets/dice-box/',
})
document.addEventListener("DOMContentLoaded", async() => {
Box.init().then(()=>{
const Controls = new BoxControls({
onUpdate: (updates) => {
Box.updateConfig(updates)
}
})
// create display overlay
const Display = new DisplayResults("#dice-box")
// create Roller Input
const Roller = new AdvancedRoller({
target: '#dice-box',
onSubmit: (notation) => Box.roll(notation),
onClear: () => {
Box.clear()
Display.clear()
},
onReroll: (rolls) => {
// loop through parsed roll notations and send them to the Box
rolls.forEach(roll => Box.add(roll))
},
onResults: (results) => {
Display.showResults(results)
}
})
// pass dice rolls to Advanced Roller to handle
Box.onRollComplete = (results) => {
Roller.handleResults(results)
}
})
html,
body {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
overflow: hidden;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#dice-box {
position: relative;
box-sizing: border-box;
width: 100%;
height: 100%;
background-image: url(./assets/woodgrain2.jpg);
background-size: cover;
}
#dice-box canvas {
width: 100%;
height: 100%;
}
Other Projects
If you're looking for a 3D dice roller that works with three.js than I would recommend looking into Dice So Nice