网站关键词优化推广,什么公司做网站,成都装修公司口碑最好的是哪家,廊坊百度关键词排名平台Cocos使用精灵组件显示相机内容
1. 为什么使用精灵渲染 在游戏引擎中#xff0c;游戏场景内除webview和video外所有的节点都是渲染在Canvas上#xff0c;这导致了webview和video只能存在于所有节点的最上层或最下层#xff0c;而这种层级关系会出现节点事件无法正常监听或者…Cocos使用精灵组件显示相机内容
1. 为什么使用精灵渲染 在游戏引擎中游戏场景内除webview和video外所有的节点都是渲染在Canvas上这导致了webview和video只能存在于所有节点的最上层或最下层而这种层级关系会出现节点事件无法正常监听或者webview和video被遮挡为解决这个问题可以通过将影像渲染在精灵组件上。 2. 如何实现
2.1 添加视频标签 可以直接用代码创建也可以在构建后添加到index.html文件中 // 创建一个新的视频元素
let video document.createElement(video);
// 设置视频元素的 ID
video.setAttribute(id, this._player_container_id);
// 设置视频预加载属性为自动
video.setAttribute(preload, auto);
// 将视频元素隐藏
video.setAttribute(hidden, hidden);
// 设置视频元素的样式宽高都为0以隐藏视频
video.setAttribute(style, width: 0px; height: 0px;)
// 将视频元素添加到文档的主体中
document.body.appendChild(video);2.2 逻辑实现 原理是将视频内容根据自己设置的固定帧绘制在画布再将纹理转换成精灵帧显示在精灵组件上适用于相机采集、直播采集、视频文件播放等 private _texture: cc.Texture2D; // 用于存储纹理
private _canvas: HTMLCanvasElement; // HTML画布元素
private _canvasCtx: CanvasRenderingContext2D; // 画布的2D上下文
private _sprite: cc.Sprite; // 精灵组件private spriteFrameCache: cc.SpriteFrame[] []; // 精灵帧缓存数组
private index 0; // 当前使用的缓存索引
private _video; // 视频元素private lastUpdateTime -1; // 上一次更新时间
private _Timer 0; // 定时器init() {// 创建画布并设置尺寸let canvas: HTMLCanvasElement document.createElement(canvas);canvas.width this.node.width; // 设置画布宽度canvas.height this.node.height; // 设置画布高度this._canvas canvas; // 保存画布引用this._canvasCtx canvas.getContext(2d); // 获取2D上下文this._sprite this.getComponent(cc.Sprite); // 获取精灵组件this._texture new cc.Texture2D(); // 创建新的纹理对象// 初始化两个精灵帧并存入缓存for (let i 0; i 2; i) {this.spriteFrameCache.push(new cc.SpriteFrame()); // 创建精灵帧并加入缓存}
}
private async updateTexture(): Promisevoid {// 如果视频未定义返回if (this._video undefined) return;// 如果视频未暂停且当前时间与最后更新时间不同进行更新if (!this._video.paused this._video.currentTime ! this.lastUpdateTime) {this.lastUpdateTime this._video.currentTime; // 更新最后更新时间this._Timer 0; // 重置计时器} else if (this._Timer 10) {this._Timer 1 / 25; // 增加计时器} else {this.unschedule(this.updateTexture); // 取消调度this.clearSprite(); // 清空精灵this._Timer 0; // 重置计时器console.log(updateTexture fail); // 打印失败日志return; // 返回}// 在画布上绘制视频内容this._canvasCtx.drawImage(this._video, 0, 0, this.node.width, this.node.height);this._texture.initWithElement(this._canvas); // 用画布元素初始化纹理let spriteFrame this.spriteFrameCache[this.index]; // 获取当前索引的精灵帧spriteFrame.setTexture(this._texture); // 设置精灵帧的纹理this._sprite.spriteFrame spriteFrame; // 更新精灵的显示帧this.index this.index ^ 1; // 切换索引0 和 1 之间切换
}
bind(cb): void {// 获取本地视频元素this._video document.querySelector(#local_video).children[0];// 请求用户媒体音频和视频navigator.mediaDevices.getUserMedia({audio: true,video: true}).then((stream) {this.handleSuccess(stream); // 成功时处理流this._video.play(); // 播放视频cb(); // 调用回调}).catch(this.handleError); // 处理错误
}
handleSuccess(stream) {this._video.srcObject stream; // 将流设置为视频播放器的源对象
}
handleError(e) {console.log(绑定失败:); // 输出错误信息console.log(e); // 输出具体错误
}
clearSprite() {this._sprite.spriteFrame null; // 清空精灵的显示帧
}
/**调用测试 **/
test() {this.bind(() { // 绑定视频流并在完成后执行回调this.unschedule(this.updateTexture); // 取消之前的调度this.schedule(this.updateTexture, 1 / 25, cc.macro.REPEAT_FOREVER); // 调度更新纹理的方法this.init(); // 初始化设置});
}