Cocos使用精灵组件显示相机内容
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(): Promise<void> {// 如果视频未定义,返回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(); // 初始化设置});
}
相关文章:
Cocos使用精灵组件显示相机内容
Cocos使用精灵组件显示相机内容 1. 为什么使用精灵渲染 在游戏引擎中,游戏场景内除webview和video外所有的节点都是渲染在Canvas上,这导致了webview和video只能存在于所有节点的最上层或最下层,而这种层级关系会出现节点事件无法正常监听或者…...
AListFlutter(手机alist)——一键安装,可在手机/电视上运行并挂载各个网盘
前面提到软路由系统OpenWRT的时候,当时说过可以在OpenWRT里安装alist,然后挂载网盘,这样就可以通过webdav的方式在家庭局域网下的任何设备都可以访问操作这些网盘,摆脱硬盘空间不够的问题。 但alist的官方版本是没有手机版本的&a…...
2024快手面试算法题-生气传染
问题描述 思路分析 生气只会向后传播,最后一个生气的人一定是最长连续没有生气的人中的最后一个人,前提是前面得有一个人生气。 注意,一次只能传播一个人,比如示例1,第一次只会传播给第一个P,不会传播给第…...
组织如何防御日益增加的 API 攻击面
应用程序编程接口 (API) 日益重要。随着 API 超出手动控制范围,组织可能面临更大的安全挑战。 在这里,我们与 Akamai 安全技术战略总监 Karl Mattson 进行了交谈。 请介绍一下您的职位和背景。 我在网络安全和技术领导方面拥有超过 25 年的经验&am…...
如何防止U盘盗取电脑数据?
数据安全无论是对企业还是个人都至关重要。这些用户群体随时面临着数据被窃取的风险,而 U 盘则成为了潜在的安全隐患。如果你想要禁止电脑上使用 这类USB 存储设备,看完这篇文章,防止 U 盘盗取数据并非难事。 禁止使用usb存储设备 打开电脑上…...
python爬虫抓取豆瓣数据教程
环境准备 在开始之前,你需要确保你的Python环境已经安装了以下库: requests:用于发送HTTP请求。BeautifulSoup:用于解析HTML文档。 如果你还没有安装这些库,可以通过以下命令安装: pip install requests…...
Mybatis 注意传递多种参数,不一定都有参数值,用xml如何写出查询语句
Mybatis 注意传递多种参数,不一定都有参数值,用xml如何写出查询语句 有一张User表,传递name和age参数,通过mybatis的xml格式编写查询namelike“%张%”,或者age18的学生信息,但是注意传递name和age参数&…...
【Windows】Redis 部署
1、部署 (1)下载 目前 Redis官网 没有提供Windows版本的安装程序,如果需要安装,需要到Github上下载适合Windows的版本。 具体下载地址为: Redis-x64-3.0.504.zipRedis-x64-5.0.14.1.zip (2)…...
【经典】Vue中this指向问题??
在Vue中,this关键字的指向取决于this在何处被定义。在Vue的组件方法中,this指向当前组件实例,即Vue的实例。 以下是一些常见场景的this指向示例: 组件方法内部: export default { methods: { someMethod() { …...
Oracle数据泵(expdp)导入导出数据
源数据库操作(数据备份) 自定义变量 1.查询当前数据库的自定义变量(里面包含导出数据文件路径变量配置,即DUMP_DIR) select * from dba_directories; 2.若没有配置,则创建一个dump_dir(变量…...
得物App 3D球鞋博物馆亮相两博会,打造沉浸式消费新体验
近日,2024中国体育文化博览会、中国体育旅游博览会(简称“两博会”)在苏州国际展览中心拉开帷幕。得物App携手Apple Vision Pro共同打造的3D球鞋博物馆亮相两博会上海展区,并通过3D技术为观众呈现独特的沉浸式消费新体验。 在3D球…...
深度学习中的迁移学习
文章目录 一、迁移学习的基本概念二、迁移学习的步骤三、迁移学习的策略四、迁移学习的应用五、迁移学习的挑战与未来展望 深度学习中的迁移学习是一种重要的机器学习方法,其 核心思想在于利用从一个任务(源任务)中学到的知识或模型…...
【深入浅出】深入浅出Bert(附面试题)
本文的目的是为了帮助大家面试Bert,会结合我的面试经历以及看法去讲解Bert,并非完整的技术细致讲解,介意请移步。 深入浅出】深入浅出Bert(附面试题) 网络结构Pre-TrainingFine-Tuning 输入编码词向量编码句子编码位置…...
Docker-安装
操作系统:Ubuntu 20.04.6 LTS 更新apt sudo apt update 删除旧版本docker sudo apt-get remove docker docker-engine docker.io 安装docker sudo apt install docker.io 查看docker版本 docker --version 启动docker 启动docker sudo systemctl start docker 启用…...
《盼归》
《盼归》 烈日炎炎天桥上,小月踮脚望远方。 汗水滑落笑颜开,心中英雄是父忙。 车声轰鸣情意长,喇叭回应泪两行。 生日快乐声声唤,盼父归来情意长。 在一个炎热的夏日午后,阳光炙烤着大地,天桥上的温度达…...
第十九章 Vue组件之data函数
目录 一、引言 二、示例代码 2.1. 工程结构图 2.2. main.js 2.3. App.vue 2.4. BaseCount.vue 三、运行效果 一、引言 在Vue CLI脚手架中一个组件的data选项必须是一个函数,以此保证每个组件实例,维护独立的一份数据对象。每次创建新的组件实…...
【jvm】什么时候对象进入老年代
目录 1. 对象年龄达到阈值2. 大对象直接进入老年代3. 动态晋升条件 1. 对象年龄达到阈值 1.基本机制:当一个对象在新生代(包括Eden区和Survivor区)中经历了多次垃圾回收(GC)后仍然存活,其年龄会逐渐增加。…...
Vue.nextTick 使用指南:数据更新与 DOM 同步利器
前言 在使用 Vue.js 开发单页面应用时,我们常常需要在数据更新后执行一些操作,比如更新 DOM 或者进行一些依赖于最新数据的计算。这时候,Vue.nextTick 就显得尤为重要,本文将详细介绍 Vue.nextTick 的作用与使用方法。 什么是 V…...
第三百零一节 Lucene教程 - Lucene索引文件
Lucene教程 - Lucene索引文件 索引是识别文档并为搜索准备文档的过程。 下表列出了索引过程中常用的类。 类描述IndexWriter在索引过程中创建/更新索引。Directory表示索引的存储位置。Analyzer分析文档并从文本中获取标记/单词。Document带有字段的虚拟文档。分析仪可以处理…...
动态规划 01背包(算法)
现有四个物品,小偷的背包容量为8,怎么可以偷得价值较多的物品 如: 物品编号: 1 2 3 4 物品容量: 2 3 4 5 物品价值: 3 4 5 8 记f(k,w) ,当背包容量为w,可以偷k件物品…...
现代React Native开发:从Expo生态到Redux状态管理的工程实践
1. 项目概述:一个为现代React Native开发量身定制的生产力引擎 如果你和我一样,在过去几年里用React Native做过几个项目,那你一定对项目初始化时那种重复、繁琐的“体力活”深有体会。每次新建一个项目,都要重新安装一堆依赖库&…...
IDEA里Artifact选war还是war exploded?一个设置解决Tomcat热部署难题
IDEA中Artifact选择:war与war exploded深度解析与热部署实战 每次修改完JSP页面后都要重启Tomcat?看着进度条缓慢加载,开发效率被硬生生拖慢。这可能是大多数Java Web开发者都经历过的痛苦。问题的根源往往藏在IDEA那个不起眼的Artifact配置选…...
告别配置烦恼!Qt 5.14.2下QCustomPlot源码集成与QChart开箱即用全攻略
Qt 5.14.2图表库极简集成指南:QCustomPlot源码直连与QChart零配置实战 刚接手一个需要快速实现数据可视化的Qt项目时,开发者往往会在图表库的选择和集成上耗费大量时间。传统方案如Qwt需要繁琐的编译配置,而官方文档又常常默认读者已经熟悉Qt…...
在OpenClaw项目中配置Taotoken作为Agent的模型供应商
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 在OpenClaw项目中配置Taotoken作为Agent的模型供应商 基础教程类,指导在虚拟机环境使用OpenClaw框架开发AI Agent的用户…...
高校食堂学生信息录入系统开发实战|从0到1搭建简易Web系统
大家好~ 最近完成了一个适合高校课程作业、小型食堂管理使用的「大学食堂学生信息录入系统」,全程用纯前端技术实现,无需复杂后端环境,双击即可运行,今天就来分享一下开发全过程、功能细节和使用技巧,适合刚…...
5分钟极简安装:免费Ghidra逆向工程工具完整配置指南
5分钟极简安装:免费Ghidra逆向工程工具完整配置指南 【免费下载链接】ghidra_installer Helper scripts to set up OpenJDK 11 and scale Ghidra for 4K on Ubuntu 18.04 / 18.10 项目地址: https://gitcode.com/gh_mirrors/gh/ghidra_installer 你是否曾因复…...
别再照搬Zynq教程了!手把手教你为Arty A7-35T配置MicroBlaze的SPI Flash启动(附时钟连接避坑指南)
别再照搬Zynq教程了!手把手教你为Arty A7-35T配置MicroBlaze的SPI Flash启动(附时钟连接避坑指南) 在FPGA开发领域,Zynq系列因其ARMFPGA的异构架构而广受欢迎,网上教程资源也最为丰富。但这也导致了一个常见陷阱——许…...
独立开发者如何借助Taotoken应对大模型API调用波动
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 独立开发者如何借助Taotoken应对大模型API调用波动 对于独立开发者而言,项目的稳定性和可控成本是生存与发展的关键。在…...
告别内存焦虑!STM32H743全系列SRAM(ITCM/DTCM/AXI)实战分配指南(MDK/IAR双环境)
STM32H743内存优化实战:从理论到精准分配的完整指南 在嵌入式系统开发中,内存管理往往是决定项目成败的关键因素之一。STM32H743作为STMicroelectronics推出的高性能微控制器系列,其复杂的内存架构既带来了性能优势,也增加了开发难…...
Nigate:让Mac与Windows硬盘和谐共处的开源桥梁
Nigate:让Mac与Windows硬盘和谐共处的开源桥梁 【免费下载链接】Free-NTFS-for-Mac Nigate: An open-source NTFS utility for Mac. It supports all Mac models (Intel and Apple Silicon), providing full read-write access, mounting, and management for NTFS …...
