Three.js中如何在其他类调用Application类的render函数?
解决方案
你不需要在Physics类内部额外触发渲染,当前Application类已经实现了基于requestAnimationFrame的自驱动渲染循环,只需要把物理更新逻辑接入这个现有循环即可,避免多套循环导致的更新节奏混乱。
1. 调整Application类逻辑
初始化Physics实例时,通过构造函数传入需要的上下文引用,同时在每帧渲染前调用物理更新方法:
export class Application { constructor() { this.objects = []; this.createScene(); // 初始化物理模块,传入需要的依赖 this.physics = new Physics({ scene: this.scene, camera: this.camera, renderer: this.renderer, appInstance: this }); } createScene() { this.scene = new THREE.Scene(); this.camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 10000); this.renderer = new THREE.WebGLRenderer(); this.renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(this.renderer.domElement); this.render(); } getMesh(){ return this.curveObject; } update(){ } render() { requestAnimationFrame(() => { this.render(); }); this.objects.forEach((object) => { object.update(); }); // 每帧先执行物理模拟更新 this.physics.animate(); this.renderer.render(this.scene, this.camera); } }
2. 调整Physics类构造函数接收依赖
如果确实需要在Physics类内部访问Application的方法、渲染器或场景,直接使用构造函数接收的引用即可:
class Physics { constructor(deps) { // 缓存传入的依赖引用 this.scene = deps.scene; this.camera = deps.camera; this.renderer = deps.renderer; this.app = deps.appInstance; // 保留你原有的物理世界、刚体、网格相关初始化逻辑 } animate(){ if (this.pinTest){ this.pin1Mesh.position.copy(this.pin1Body.position); this.pin1Mesh.quaternion.copy(this.pin1Body.quaternion); this.pinTest.position.copy(this.pin1Body.position); this.pinTest.quaternion.copy(this.pin1Body.quaternion); } // 特殊场景下需要主动触发渲染可以直接调用 // this.app.render() // 或 this.renderer.render(this.scene, this.camera) // 常规场景不需要在这里调用,外层渲染循环已经统一处理渲染 } }
关键注意事项
- 整个应用只保留一个
requestAnimationFrame渲染循环,不要在Physics等其他模块里再写独立的帧循环,否则会出现更新不同步、性能浪费的问题 - 类之间的依赖通过构造函数显式传入是可维护性最高的写法,不要用全局变量、跨文件硬找实例的野路子实现
- 物理模拟更新要放在渲染执行前调用,保证渲染出来的画面和物理计算结果同步
内容的提问来源于stack exchange,提问作者Sara Gold
相关产品推荐
相关产品推荐

