基于 **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 场景基础:

javascript 复制代码
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 事件监听,阻止默认行为避免页面滚动)。

四、技术亮点

  1. 物理模拟:实现了重力作用下的抛体运动(炮弹飞行)和粒子运动(爆炸);
  2. 视觉效果:雾效、阴影、发光材质、轨迹绘制、爆炸闪光,多层级视觉叠加;
  3. 性能优化 :限制轨迹点数量(20个)、自动移除失效炮弹/粒子、帧率适配(devicePixelRatio 限制为 2);
  4. 交互友好:滑块控制参数、实时统计数据、键盘+按钮双发射方式。

五、总结

这个代码是一个完整的 Three.js 3D 交互特效案例,核心是「抛体运动物理模拟」+「粒子爆炸视觉效果」,结构上采用面向对象封装,逻辑清晰,从场景搭建、物体创建、物理更新到 UI 交互、性能监控都包含在内,可直接集成到网页中作为互动特效(比如游戏、宣传页动画)。

相关推荐
放羊郎2 小时前
一款基于鲁班猫和STM32的自主导航实践
人工智能·数码相机·slam·视觉slam·建图·激光slam
Heo2 小时前
原型理解从入门到精通
前端·javascript·后端
三条猫2 小时前
AI 大模型如何给 CAD 3D 模型“建立语义”?
人工智能·机器学习·3d·ai·大模型·cad
Heo2 小时前
通用会话控制方案
前端·javascript·后端
Heo2 小时前
跨域问题解决方案汇总
前端·javascript·后端
shmily麻瓜小菜鸡2 小时前
Element Plus 的 <el-table> 怎么点击请求后端接口 tableData 进行排序而不是网络断开之后还可以自己排序
前端·javascript·vue.js
二川bro3 小时前
第38节:WebGL 2.0与Three.js新特性
开发语言·javascript·webgl
xiaoxue..3 小时前
深入理解 JavaScript 异步编程:从单线程到 Promise 的完整指南
前端·javascript·面试·node.js
倚肆3 小时前
HTMLElement 与MouseEvent 事件对象属性详解
前端·javascript