基于 **Three.js** 开发的 3D 炮弹发射特效系统
这是一个基于 Three.js 开发的 3D 炮弹发射特效系统,核心功能是模拟炮弹发射、飞行轨迹、落地爆炸的完整视觉效果,还包含了 UI 交互、性能统计等辅助功能。下面从「核心结构、功能拆解、技术细节」三方面详细解释:
一、核心结构(类与主要属性)
这是一个面向对象的封装类 CannonEffect,所有功能都集成在类内部,结构清晰:
| 核心属性 | 作用 |
|---|---|
scene/camera/renderer | Three.js 三要素(场景/相机/渲染器) |
cannons/explosions | 存储活跃的炮弹、爆炸效果实例 |
clock | Three.js 时钟,用于计算帧间隔(物理更新) |
cannonCount/explosionCount | 统计炮弹发射数、爆炸数(UI 展示) |
fps/frameCount | 实时计算帧率(性能监控) |
二、核心功能拆解(按方法分类)
1. 初始化流程(init() 入口)
初始化时按顺序执行以下步骤,搭建 3D 场景基础:
this.createScene(); // 场景/相机/渲染器初始化
this.createLights(); // 灯光系统(环境光+方向光+爆炸点光源)
this.createGround(); // 地面+草地装饰
this.createCannonBase();// 炮台底座+炮管
this.setupUI(); // UI 交互绑定
this.animate(); // 启动渲染循环
2. 场景基础搭建(createScene())
- 场景:设置深蓝色雾效(
Fog),增强空间纵深感; - 相机:透视相机(视野75°,近裁切面0.1,远裁切面1000),初始位置
(0,10,20)看向原点; - 渲染器:WebGL 渲染器(开启抗锯齿、透明背景),支持阴影(
PCFSoftShadowMap软阴影); - 窗口适配:监听窗口 resize 事件,更新相机宽高比和渲染器尺寸。
3. 灯光系统(createLights())
三种灯光组合,保证视觉效果:
- 环境光(
AmbientLight):亮度 0.6,照亮场景所有物体,避免纯黑阴影; - 方向光(
DirectionalLight):模拟太阳光,位置(10,20,10),开启阴影(阴影贴图 2048x2048); - 爆炸点光源(
PointLight):初始亮度 0,爆炸时激活,模拟爆炸闪光。
4. 地面与炮台(createGround()/createCannonBase())
- 地面:大平面(100x100)+ 随机小草地(20个),草地半透明(opacity 0.7)增加层次感;
- 炮台:
- 底座:圆柱体(上径1.5,下径2,高0.5),深灰色金属材质;
- 炮管:圆柱体(径0.3-0.4,长3),深灰色金属材质,旋转 90° 水平朝向。
5. 炮弹核心逻辑(createCannonball()/updateCannonballs())
(1)创建炮弹(createCannonball(power, angle))
- 接收两个参数:
power(发射力度)、angle(发射角度); - 炮弹数据结构:包含 3D 网格(红色发光球体)、速度向量、位置、重力、轨迹数组;
- 初始速度计算:将角度转为弧度,按力度计算水平(x轴)和垂直(y轴)速度;
- 附加效果:炮弹自带点光源,模拟发热发光。
(2)更新炮弹(updateCannonballs(deltaTime))
每帧执行物理模拟:
- 重力作用:垂直速度(y轴)叠加重力加速度(-9.8)× 帧间隔;
- 位置更新:按速度 × 帧间隔更新炮弹位置,同步 3D 网格;
- 轨迹绘制:记录最近 20 个位置,用半透明小黄点绘制轨迹(旧轨迹自动删除);
- 碰撞检测:当炮弹 y 坐标 ≤ 0.3(触地),触发爆炸,移除炮弹网格。
6. 爆炸效果(createExplosion()/updateExplosions())
(1)创建爆炸(createExplosion(position))
- 接收爆炸位置参数,创建 50 个爆炸粒子;
- 粒子特性:随机方向速度(x/z 轴 ±5,y轴 0-10)、随机大小(0.1-0.3)、橙红色发光材质;
- 激活爆炸点光源:亮度设为 5,模拟闪光。
(2)更新爆炸(updateExplosions(deltaTime))
每帧更新爆炸状态:
- 粒子物理:受重力影响(y轴速度衰减),位置随速度更新;
- 粒子衰减:生命值(life)按衰减率减少,同步降低透明度(opacity)和尺寸(scale);
- 爆炸光衰减:按爆炸持续时间(2秒)线性降低点光源亮度;
- 生命周期结束:爆炸持续 2 秒后,移除所有粒子和爆炸实例。
7. UI 交互与性能统计
(1)UI 交互(setupUI())
- 绑定页面滑块(
power/angle)与数值显示(power-value/angle-value); - 外部调用:
fireCannon()函数(供 HTML 按钮/空格键触发),读取滑块值发射炮弹。
(2)性能统计(updateStats())
- 实时更新:当前活跃炮弹数、爆炸数、帧率(FPS);
- 帧率计算:每 1 秒统计一次帧数量,计算 FPS 并四舍五入。
8. 渲染循环(animate())
Three.js 核心渲染循环,每帧执行:
- 请求下一帧:
requestAnimationFrame保证流畅循环; - 计算帧间隔:
clock.getDelta()获取当前帧与上一帧的时间差(用于物理更新); - 更新逻辑:炮弹物理、爆炸效果;
- 相机动画:相机绕 y 轴缓慢旋转(
sin/cos控制 x/z 位置),始终看向(0,5,0); - 渲染场景:
renderer.render(scene, camera)输出画面; - 帧率统计:每 1 秒计算一次 FPS 并更新 UI。
三、外部交互与使用
1. 页面依赖
需要 HTML 中包含以下元素:
- 容器:
<div id="canvas-container"></div>(渲染器画布挂载点); - 滑块:
<input type="range" id="power">(力度)、<input type="range" id="angle">(角度); - 数值显示:
<span id="power-value"></span>、<span id="angle-value"></span>; - 统计显示:
<span id="cannon-count"></span>、<span id="explosion-count"></span>、<span id="fps"></span>; - 发射按钮:
<button onclick="fireCannon()">发射</button>(或按空格键发射)。
2. 触发方式
- 点击发射按钮;
- 按下空格键(通过
keydown事件监听,阻止默认行为避免页面滚动)。
四、技术亮点
- 物理模拟:实现了重力作用下的抛体运动(炮弹飞行)和粒子运动(爆炸);
- 视觉效果:雾效、阴影、发光材质、轨迹绘制、爆炸闪光,多层级视觉叠加;
- 性能优化:限制轨迹点数量(20个)、自动移除失效炮弹/粒子、帧率适配(
devicePixelRatio限制为 2); - 交互友好:滑块控制参数、实时统计数据、键盘+按钮双发射方式。
五、总结
这个代码是一个完整的 Three.js 3D 交互特效案例,核心是「抛体运动物理模拟」+「粒子爆炸视觉效果」,结构上采用面向对象封装,逻辑清晰,从场景搭建、物体创建、物理更新到 UI 交互、性能监控都包含在内,可直接集成到网页中作为互动特效(比如游戏、宣传页动画)。
