cannon+three实现设定点数三维掷骰子效果代码

代码语言:html

所属分类:三维

代码描述:cannon+three实现设定点数三维掷骰子效果代码,两个骰子会根据你设定好的点数落地呈现预定点数。

代码标签: cannon three 设定 点数 三维 掷骰子

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  


  
  
  
<style>
html, body {
    padding: 0;
    margin: 0;
}

body {
    height: 100vh;
    display: flex;
    align-items: end;
    justify-content: center;
}

.container {
    width: 100%;
    height: 100%;
    background-image: linear-gradient(#6DD5FA, #2980B9);
}

.lil-gui {
    --width: 450px;
    max-width: 90%;
    --widget-height: 20px;
    font-size: 15px;
    --input-font-size: 15px;
    --padding: 10px;
    --spacing: 10px;
    --slider-knob-width: 5px;
    --background-color: rgba(5, 0, 15, .8);
    --widget-color: rgba(255, 255, 255, .3);
    --focus-color: rgba(255, 255, 255, .4);
    --hover-color: rgba(255, 255, 255, .5);

    --font-family: monospace;
}
</style>

 
  
</head>

<body translate="no">

<div class="container">
    <canvas id="canvas"></canvas>
</div>


<script type="importmap">{
	"imports": {
      "three": "//repo.bfw.wiki/bfwrepo/js/module/three/build/164/three.module.js",
      "three/addons/": "//repo.bfw.wiki/bfwrepo/js/module/three/examples/164/jsm/"
	}
}
</script>
<script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/es-module-shims.1.6.3.js"></script>
      <script  type="module">
import * as CANNON from "//repo.bfw.wiki/bfwrepo/js/module/cannon-es.0.20.0.js";
import * as THREE from "three";
import * as BufferGeometryUtils from "three/addons/utils/BufferGeometryUtils.js";
import GUI from "//repo.bfw.wiki/bfwrepo/js/lil-gui.esm.js";

const containerEl = document.querySelector(".container");
const canvasEl = document.querySelector("#canvas");

let renderer, scene, camera, diceMesh, physicsRender, simulation;

let simulationOn = true;
let currentResult = [0, 0];

const params = {

  // dice
  segments: 40,
  edgeRadius: .08,
  notchRadius: .15,
  notchDepth: .17,

  // physics
  restitution: .3,
  friction: .1,

  // ux
  desiredResult: 7,
  throw: throwMe };


function throwMe() {
  simulationOn = true;
  throwDice();
}


const diceArray = [];
const floorPlanesArray = [];
let throwBtn;

initPhysics();
initScene();


createFloor();
diceMesh = createDiceMesh();
for (let i = 0; i < 2; i++) {
  diceArray.push(createDice());
  addDiceEvents(diceArray[i], i);
}

createControls();

throwMe();
render();

window.addEventListener("resize", updateSceneSize);
window.addEventListener("click", () => {
});

function initScene() {
  renderer = new THREE.WebGLRenderer({
    alpha: true,
    antialias: true,
    canvas: canvasEl });

  renderer.shadowMap.enabled = true;
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

  scene = new THREE.Scene();

  camera = new THREE.PerspectiveCamera(45, containerEl.clientWidth / containerEl.clientHeight, .1, 100);
  camera.position.set(0, 10, 16);
  camera.lookAt(0, 4, 0);

  updateSceneSize();

  const ambientLight = new THREE.AmbientLight(0xffffff, 1);
  scene.add(ambientLight);

  const light = new THREE.PointLight(0xffffff, 1000.);
  light.position.set(10, 20, 5);
  light.castShadow = true;
  light.shadow.mapSize.width = 2048;
  light.shadow.mapSize.height = 2048;
  scene.add(light);
}

function initPhysics() {

  const gravity = new CANNON.Vec3(0, -50, 0);
  const allowSleep = true;
  physicsRender = new CANNON.World({
    allowSleep, gravity });

  simulation = new CANNON.World({
    allowSleep, gravity });

  physicsRender.defaultContactMaterial.restitution = params.restitution;
  simulation.defaultContactMaterial.restitution = params.restitution;
  physicsRender.defaultContactMaterial.friction = params.friction;
  simulation.defaultContactMaterial.friction = params.friction;

}

function createFloor() {
  for (let i = 0; i < 4; i++) {

    const body = new CANNON.Body({
      type: CANNON.Body.STATIC,
      shape: new CANNON.Plane() });

    physicsRender.addBody(body);
    simulation.addBody(body);

    let mesh;
    if (i === 0) {
      mesh = new THREE.Mesh(
      new THREE.PlaneGeometry(100, 100, 100, 100),
      new THREE.ShadowMaterial({
        opacity: .1 }));


      scene.add(mesh);
      mesh.receiveShadow = true;
    }

    floorPlanesArray.push({
      body, mesh });

  }

  floorPositionUpdate();
}

function floorPositionUpdate() {
  floorPlanesArray.forEach((f, fIdx) => {
    if (fIdx === 0) {
      f.body.position.y = 0;
      f.body.quaternion.setFromEuler(-.5 * Math.PI, 0, 0);
    } else if (fIdx === 1) {
      f.body.quaternion.setFromEuler(0, .5 * Math.PI, 0);
      f.body.position.x = -6 * containerEl.clientWidth / containerEl.clientHeight;
    } else if (fIdx === 2) {
      f.body.quaternion.setFromEuler(0, -.5 * Math.PI, 0);
      f.body.position.x = 6 * containerEl.clientWidth / containerEl.clientHeight;
    } else if (fIdx === 3) {
      f.body.quaternion.setFromEuler(0, Math.PI, 0);
      f.body.position.z = 3;
    }

    if (f.mesh) {
      f.mesh.position.copy(f.body.position);
      f.mesh.quaternion.copy(f.body.quaternion);
    }
  });
}


function createDiceMesh() {
  const boxMaterialOuter = new THREE.MeshStandardMaterial({
    color: 0xffffff });

  const boxMaterialInner = new THREE.MeshStandardMaterial({
    color: 0x000000,
    roughness: 0,
    metalness: 1 });


  const g = new THREE.Group();
  const innerSide = 1 - params.edgeRadius;
  const innerMesh = new THREE.Mesh(
  new THREE.BoxGeometry(innerSide, innerSide, innerSide),
  boxMaterialInner);

  const outerMesh = new THREE.Mesh(
  createBoxGeometry(),
  boxMaterialOuter);

  outerMesh.castShadow = true;
  g.add(innerMesh, outerMesh);

  return g;
}

function createDice() {
  const mesh = diceMesh.clone();
  scene.add(mesh);

  const shape = new CANNON.Box(new CANNON.Vec3(.5, .5, .5));
  const mass = 1;
  const sleepTimeLimit = .02;

  const body = new CANNON.Body({
    mass, shape, sleepTimeLimit: .01 });

  physicsRender.addBody(body);

  const simulationBody = new CANNON.Body({
    mass, shape, sleepTimeLimit: .02 });

  simulation.addBody(simulationBody);

  return {
    mesh,
    body: [body, simulationBody],
    startPos: [null, null, null] };

}

function createBoxGeometry() {

  let boxGeometry = new THREE.BoxGeometry(1, 1, 1, params.segments, params.segments, params.segments);

  const positionAttr = boxGeometry.attributes.position;
  const subCubeHalfSize = .5 - params.edgeRadius;

  const notchWave = v => {
    v = 1 / params.notchRadius * v;
    v = Math.PI * Math.max(-1, Math.min(1, v));
    return params.notchDepth * (Math.cos(v) + 1.);
  };
  const notch = pos => notchWave(pos[0]) * notchWave(pos[1]);

  for (let i = 0; i < positionAttr.count; i++) {

    let position = new THREE.Vector3().fromBufferAttribute(positionAttr, i);
    const subCube = new THREE.Vector3(Math.sign(position.x), Math.sign(position.y), Math.sign(position.z)).multiplyScalar(subCubeHalfSize);
    const addition = new THREE.Vector3().subVectors(po.........完整代码请登录后点击上方下载按钮下载查看

网友评论0