Creator web端运行失去焦点后画面不动了

Creator web端运行失去焦点后画面不动了,这个问题该如何处理。

mark

cc.game.canvas.addEventListener('blur', ()=>{

            console.log("失去焦点");

        });

        cc.game.canvas.addEventListener('focus', ()=>{

            console.log("获取焦点");

        });
2赞

浏览器上可以用 Web Worker 来解决这个问题。

创建一个 RunInBackground 组件来监听前后台切换:

const { ccclass, property } = cc._decorator;

/**
 * 用于在浏览器后台保持运行
 */
@ccclass
export default class RunInBackground extends cc.Component {

    @property({ displayName: CC_DEV && '脚本地址', tooltip: CC_DEV && 'Worker 脚本地址' })
    private url: string = '/worker.js';

    /** Worker 实例 */
    private worker: Worker = null;

    /**
     * 生命周期:加载
     */
    protected onLoad() {
        this.init();
        this.registerEvent();
    }

    /**
     * 生命周期:销毁
     */
    protected onDestroy() {
        this.unregisterEvent();
    }

    /**
     * 注册事件
     */
    protected registerEvent() {
        this.onVisibilityChange = this.onVisibilityChange.bind(this);
        document.addEventListener('visibilitychange', this.onVisibilityChange);
    }

    /**
     * 反注册事件
     */
    protected unregisterEvent() {
        document.removeEventListener('visibilitychange', this.onVisibilityChange);
    }

    /**
     * 初始化
     */
    private init() {
        // 设为常驻节点
        this.node.setParent(cc.director.getScene());
        cc.game.addPersistRootNode(this.node);
        // 网页调试需要在预览模板目录下放一份 worker.js
        // 如果使用编辑器自带的预览模板,还需要修改脚本地址
        // if (CC_DEBUG) {
        //     this.url = '/app/editor/static/preview-templates/worker.js';
        // }
    }

    /**
     * 页面切换回调
     */
    private onVisibilityChange() {
        // 切换到后台
        if (document.visibilityState === 'hidden') {
            // 确保引擎处于运行状态
            if (cc.game.isPaused()) {
                cc.game.resume();
            }
            // 创建工作线程
            this.worker = new Worker(this.url);
            this.worker.onmessage = () => {
                // 调用 Cocos 引擎主循环
                cc.director['mainLoop']();
            }
        }
        // 切换到前台
        else if (document.visibilityState === 'visible') {
            if (this.worker) {
                this.worker.terminate();
                this.worker = null;
            }
        }
    }

}

文件地址:assets/eazax-ccc/components/RunInBackground.ts · 陈皮皮/Eazax Cocos 示例项目 - Gitee.com

创建一个 worker.js 脚本,用来在后台驱动 Cocos 端:

const interval = 1000 / 60;

// 递归函数
function call() {
    postMessage(1);
    // 直接调用函数会有问题
    setTimeout('call()', interval);
}
call();

发布
放在 build-templates/shares/ 目录下
例如:build-templates/shares/worker.js · 陈皮皮/Eazax Cocos 示例项目 - Gitee.com

调试
放在 preview-templates/ 目录下
例如:preview-templates/worker.js · 陈皮皮/Eazax Cocos 示例项目 - Gitee.com

2赞