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