Cannon.js 从入门到精通
开发领域:前端开发 | AI 应用 | Web3D | 元宇宙
技术栈:JavaScript、React、ThreeJs、WebGL、Go
经验经验:6 年+ 前端开发经验,专注于图形渲染和 AI 技术
开源项目:智简未来、数字孪生引擎 github
大家好!我是 [晓智],一位热爱探索新技术的前端开发者,在这里分享前端和 Web3D、AI 技术的干货与实战经验。如果你对技术有热情,欢迎关注我的文章,我们一起成长、进步!
Cannon.js 是一个用于 Web 和 JavaScript 的 3D 物理引擎,广泛应用于游戏和仿真领域,能够处理物理碰撞、刚体、力、速度等效果。本文将通过简单的示例,帮助你理解如何将 Cannon.js 与 Three.js 集成,并在 3D 场景中实现物理模拟。
1. 安装和引入 Cannon.js
通过 CDN 引入
你可以通过 CDN 直接引入 Cannon.js:
<script src="https://cdn.jsdelivr.net/npm/cannon-es@0.23.0/dist/cannon-es.js"></script>
通过 npm 安装
如果你使用模块化开发(例如 webpack 或 Vite),可以使用 npm 安装 cannon-es:
npm install cannon-es
2. 创建基本的 Three.js 场景
首先,我们需要创建一个简单的 Three.js 场景,并添加一个立方体和一个平面,以便我们能够看到物理引擎的效果。
代码示例:基本的 Three.js 场景
import * as THREE from 'three';let scene, camera, renderer;
let cube, plane;function init() {scene = new THREE.Scene();camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000,);renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 创建立方体const geometry = new THREE.BoxGeometry();const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });cube = new THREE.Mesh(geometry, material);cube.position.y = 5; // 放置在空中scene.add(cube);// 创建地面const planeGeometry = new THREE.PlaneGeometry(2000, 2000);const planeMaterial = new THREE.ShadowMaterial({ opacity: 0.5 });plane = new THREE.Mesh(planeGeometry, planeMaterial);plane.rotation.x = -Math.PI / 2;plane.position.y = -5;scene.add(plane);camera.position.z = 10;animate();
}function animate() {requestAnimationFrame(animate);renderer.render(scene, camera);
}init();
3. 添加物理世界
接下来,我们需要添加 Cannon.js 物理引擎。我们将创建一个 Cannon.js 的世界并为立方体和地面添加物理属性。
代码示例:添加物理世界
import * as THREE from 'three';
import * as CANNON from 'cannon-es';let scene, camera, renderer;
let cube, plane;
let world, cubeBody, planeBody;function init() {scene = new THREE.Scene();camera = new THREE.PerspectiveCamera(75,window.innerWidth / window.innerHeight,0.1,1000,);renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);// 创建物理世界world = new CANNON.World();world.gravity.set(0, -9.82, 0); // 设置重力// 创建立方体(物理)const cubeShape = new CANNON.Box(new CANNON.Vec3(1, 1, 1)); // 立方体形状cubeBody = new CANNON.Body({mass: 1, // 质量position: new CANNON.Vec3(0, 5, 0), // 初始位置});cubeBody.addShape(cubeShape);world.addBody(cubeBody);// 创建立方体(Three.js 视觉部分)const geometry = new THREE.BoxGeometry(2, 2, 2);const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });cube = new THREE.Mesh(geometry, material);scene.add(cube);// 创建地面(物理)const planeShape = new CANNON.Plane(); // 地面形状planeBody = new CANNON.Body({mass: 0, // 地面不动position: new CANNON.Vec3(0, -5, 0),});planeBody.addShape(planeShape);world.addBody(planeBody);// 创建地面(Three.js 视觉部分)const planeGeometry = new THREE.PlaneGeometry(2000, 2000);const planeMaterial = new THREE.ShadowMaterial({ opacity: 0.5 });plane = new THREE.Mesh(planeGeometry, planeMaterial);plane.rotation.x = -Math.PI / 2;plane.position.y = -5;scene.add(plane);camera.position.z = 10;animate();
}function animate() {requestAnimationFrame(animate);// 更新物理世界world.step(1 / 60); // 每帧更新物理世界// 将物理世界中的立方体位置更新到 Three.js 中cube.position.copy(cubeBody.position);cube.rotation.copy(cubeBody.rotation);renderer.render(scene, camera);
}init();
创建物理世界 (CANNON.World):物理世界模拟了所有的物理对象和事件,我们为其设置了重力。
为物体添加物理属性:通过 CANNON.Box 创建了立方体的物理形状并将其添加到物理世界中。地面使用 CANNON.Plane 创建。
同步物理与可视化:每一帧更新物理世界,并将物理引擎中的物体位置同步到 Three.js 中。
4. 添加力与碰撞
你可以为物体添加力,或者监听物体之间的碰撞事件。
代码示例:为物体添加力
function addForce() {// 向立方体添加一个向上的力cubeBody.applyForce(new CANNON.Vec3(0, 10, 0), cubeBody.position);
}setInterval(addForce, 1000); // 每秒钟给立方体添加一次力
代码示例:监听碰撞事件
world.addEventListener('postStep', () => {if (cubeBody.position.y < 0) {console.log('The cube has hit the ground!');}
});
5. 总结
通过本教程,你已经学会了如何使用 Cannon.js 在 Three.js 场景中实现简单的物理模拟。你可以扩展这个示例,加入更多的物体,处理碰撞检测,或加入更复杂的物理效果。
相关文章:
Cannon.js 从入门到精通
开发领域:前端开发 | AI 应用 | Web3D | 元宇宙 技术栈:JavaScript、React、ThreeJs、WebGL、Go 经验经验:6 年 前端开发经验,专注于图形渲染和 AI 技术 开源项目:智简未来、数字孪生引擎 github 大家好!我…...
深入理解 TCP 标志位(TCP Flags)
深入理解 TCP 标志位(TCP Flags) 1. 简介 在网络安全和网络分析领域,TCP标志位(TCP Flags)是理解网络行为和流量模式的关键概念。特别是在使用工具如Nmap进行端口扫描时,理解这些标志位的意义和用法至关重…...
K8S,StatefulSet
有状态应用 Deployment实际上并不足以覆盖所有的应用编排问题? 分布式应用,它的多个实例之间,往往有依赖关系,比如:主从关系、主备关系。 还有就是数据存储类应用,它的多个实例,往往都会在本地…...
JavaScript动态网络爬取:深入解析与实践指南
引言 随着互联网技术的发展,越来越多的网站采用动态加载技术来提供丰富的用户体验。这些动态内容的加载依赖于JavaScript,给传统的网络爬虫带来了挑战。JavaScript动态网络爬取技术应运而生,它允许开发者模拟用户行为,获取动态加…...
MySql:Centos7安装MySql
目录 安装之前,清除MySql残留文件 下载MySql的官方yum源 安装MySql 服务 MySql配置 常见问题 本次安装基于Centos7,平台为云服务器,由XShell软件演示。 注意,请将用户切换为Root用户。 安装之前,清除MySql残留文…...
Vector软件CANdb++的信号起始位Bug
问题现象 前几天导入DBC文件发现不对劲,怎么生成代码的起始地址都怪怪的,检查下工程里面的配置,还真的是这样,一路查到输入文件——DBC文件,发现是DBC文件就有错误:一些CAN报文之后8字节长度,也…...
elasticsearch-7.14.0集群部署+kibana
1、修改系统参数 用户对软件的内存和硬盘使用权限 vim /etc/security/limits.conf * soft nproc 655350 * soft nofile 655350 * hard nproc 655350 * hard nofile 655350修改最大线程数 vim /etc/sysctl.conf vm.max_map_count262144配置用户最大的线程数 vim /etc/security/…...
如何给GitHub的开源项目贡献PR
🎯导读:本文详细介绍了如何向开源项目“代码随想录”贡献自己的题解。首先,需要Fork原项目的仓库至个人GitHub账户,然后解决克隆仓库时可能遇到的SSH密钥问题。接着,按照标准流程对本地仓库进行代码或文档的修改&#…...
神经网络-CNN
卷积神经网络 CNN 感受野 感受野(Receptive Field)在卷积神经网络(CNN)中是一个非常重要的概念,它描述了网络中某一层的输出(通常是特征图上的一个像素点)所对应的输入图像上的空间范围。 1. 定…...
4.Vue-------this.$set()的使用和详细过程-------vue知识积累
在Vue.js中,this.$set()是Vue实例this.someProperty someValue来为Vue实例的属性赋值时,Vue会自动将该属性设置为响应式的,这样当属性的值变化时,相关的视图会自动更新 一. 对象的修改 对象:修改和新增 先定义数据对…...
服务器上的常见Linux命令教程
在管理服务器(如香港服务器)时,掌握常见的 Linux 命令 是非常重要的,它们可以帮助你高效地完成服务器管理任务,如文件操作、进程管理、用户管理、网络配置等。 以下是一个系统化的 Linux 常见命令教程,分为…...
汽车总线协议分析-FlexRay总线
随着汽车智能化发展,汽车增加安全性和舒适体验的功能增多,用于实现这些功能的传感器、ECU的数量也在持续上升,严重阻碍了线控技术的发展。常用的CAN、LIN等总线由于缺少同步性、确定性和容错性不能满足汽车线控系统(X-by-Wire)的要求。因此&a…...
Java 集合:强大的数据管理工具
在 Java 编程中,集合是一种非常重要的工具,它提供了一种方便的方式来存储和操作一组对象。本文将深入探讨 Java 集合框架,包括其主要类型、特点、用法以及一些最佳实践。 一、引言 在软件开发过程中,我们经常需要处理一组数据。…...
FFmpeg 4.3 音视频-多路H265监控录放C++开发十九,ffmpeg复用
封装就是将 一个h264,和一个aac文件重新封装成一个mp4文件。 这里我们的h264 和 aac都是来源于另一个mp4文件,也就是说,我们会将 in.mp4文件解封装成一路videoavstream 和 一路 audioavstream,然后 将这两路的 avstream 合并成一…...
python之Django连接数据库
文章目录 连接Mysql数据库安装Mysql驱动配置数据库信息明确连接驱动定义模型在模型下的models.py中定义表对象在settings.py 中找到INSTALLED_APPS添加创建的模型 测试testdb.py中写增删改查操作urls.py添加请求路径启动项目进行测试 连接Mysql数据库 安装Mysql驱动 pip inst…...
基于Springboot+Vue的在线答题闯关系统
基于SpringbootVue的在线答题闯关系统 前言:随着在线教育的快速发展,传统的教育模式逐渐向互联网教育模式转型。在线答题系统作为其中的一个重要组成部分,能够帮助用户通过互动式的学习方式提升知识掌握度。本文基于Spring Boot和Vue.js框架&…...
声音克隆GPT-SoVITS
作者:吴业亮 博客:wuyeliang.blog.csdn.net 一、原理介绍 GPT-SoVITS,作为一款结合了GPT(生成预训练模型)和SoVITS(基于变分信息瓶颈技术的歌声转换)的创新工具,正在声音克隆领域掀…...
【STM32 Modbus编程】-作为主设备读取保持/输入寄存器
作为主设备读取保持/输入寄存器 文章目录 作为主设备读取保持/输入寄存器1、硬件准备与连接1.1 RS485模块介绍1.2 硬件配置与接线1.3 软件准备2、读保持寄存器2.1 主设备发送请求2.2 从设备响应请求2.3 主机接收数据3、读输入寄存器4、结果4.1 保持寄存器4.2 输入寄存器在前面的…...
前端开发入门指南Day 17:TypeScript高级类型(泛型,类型守卫,Partial<T>和 Required<T>等)
泛型:代码的"变色龙" 🦎 为什么需要泛型? 想象一个快递员,每天要处理不同类型的包裹。如果为每种类型的包裹都写一套处理程序,那会很麻烦。泛型就像是一个"通用的包裹处理系统",它能…...
flex布局容易忽略的角色作用
目录 清除浮动 作用于行内元素 flex-basis宽度 案例一: 案例二: 案例三: flex-grow设置权重 案例一: 案例二: 简写flex-grow:1 0 auto; flex作为一维布局,行和列的使用,忽略的小角色,大…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
