cocos creater 视频控件videoplayer动态切换到canvas下面(弹幕/自定义controls/显示二次开发)
功能需求:1. 之前有videoplayer的使用 不影响之前的功能2. cocos组件 需要显示到视频上边3. android/ios/web 端实现4. cocos creater 版本 2.1.3参考链接:https://worthatry.cn/cocos-creator-ru-he-shi-bei-jing-tou-ming/设计思路:不影响原来的加载实现添加新的方法调用 swapUpT
功能需求:
1. 之前有videoplayer的使用 不影响之前的功能
2. cocos组件 需要显示到视频上边
3. android/ios/web 端实现
4. cocos creater 版本 2.1.3
参考链接:
https://worthatry.cn/cocos-creator-ru-he-shi-bei-jing-tou-ming/
设计思路:
不影响原来的加载实现
添加新的方法调用 swapUpToCanvas 在不修改原来代码的基础上。新写的代码手动调用swapUpToCanvas 使视频控件切换到 canvas 下边
方案实现:
cocos js代码修改:
// 可以添加到 main.js 游戏启动之前
// 也可以添加到 第一个场景 的js 文件中
// 开启cocos creater 的canvas 支持透明
cc.macro.ENABLE_TRANSPARENT_CANVAS = true;
cocos scene 设置
- 场景camera设置 opaque属性为true
- 设置 camera 的backgroundColor 的alpha为0
web端代码修改
// 在VideoPlayerImpl 基类里边添加如下方法
swapUpToCanvas:function swapUpToCanvas(){
this._video && (this._video.style.zIndex = -1);
},
安卓端代码修改
- 为了不影响旧代码的效果 我们不需要修改 Cocos2dxVideoHelper.java (如果没有上下切换的需求 可以直接设置取消置顶)
private void _createVideoView(int index) {
Cocos2dxVideoView videoView = new Cocos2dxVideoView(mActivity,index);
sVideoViews.put(index, videoView);
FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
mLayout.addView(videoView, lParams);
// 设置 video 置顶。 如果没有切换video 层级的需求 可以直接注释这句
videoView.setZOrderOnTop(true);
videoView.setVideoViewEventListener(videoEventListener);
}
- 修改 AppActivity.java 文件 设置渲染支持透明通道
public Cocos2dxGLSurfaceView onCreateView() {
//Log.e("--- cccccc ---", "onCreateView 111");
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
// TestCpp should reate stencil buffer
// glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
// 设置支持透明通道
glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 8);
glSurfaceView.getHolder().setFormat(PixelFormat.RGBA_8888);
glSurfaceView.setZOrderMediaOverlay(true);
return glSurfaceView;
}
- 修改 Cocos2dxVideoView.java 文件 解除原始videoPlayer 控件的点击拦击
public boolean onTouchEvent(MotionEvent event) {
if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP) {
this.sendEvent(EVENT_CLICKED);
}
// return true;
return false; // 因为video 显示到canvas下边了。所以没必要拦截点击
}
- 修改 Cocos2dxVideoHelper.java 添加方法swapUpToCanvas
// 备注 这里只写了实现方式。 具体js调用java方法 请参考: _startVideo / _pauseVideo / _stopVideo 等其余引擎代码的实现。
private void swapUpToCanvas(int index) {
Cocos2dxVideoView view = sVideoViews.get(index);
Log.d("cocosswap", "swapUpToCanvas: start");
if (view != null) {
Log.d("cocosswap", "swapUpToCanvas: success");
view.setZOrderOnTop(false);
}
}
ios端代码的修改:
- 修改CCApplication-ios.mm 渲染格式 支持透明通道
void Application::onCreateView(PixelFormat& pixelformat, DepthFormat& depthFormat, int& multisamplingCount)
{
// 修改渲染格式 支持 透明通道
pixelformat = PixelFormat::RGBA8;
depthFormat = DepthFormat::DEPTH24_STENCIL8;
multisamplingCount = 0;
}
- 修改 video 添加到 canvas 窗口下边
- 2.1 方法1 直接把cocos 的窗口的父节点创建一个两个节点。一层显示video 一层显示cocos(这种方式 调起照相机的时候 opengl会报错 具体原因未知)
// AppController.mm 文件修改如下内容
// 先添加videoView再添加cocosView
UIViewController* rvC = [[UIViewController alloc]init];
// 视频view
UIView *videoView = [[UIView alloc] initWithFrame:bounds];
videoView.tag = 10; // 通过tag找到view
[rvC.view addSubview:videoView];
// 引擎view
UIView *cocosView = _viewController.view;
cocosView.frame = bounds;//
cocosView.backgroundColor = [UIColor clearColor];
[rvC.view addSubview:cocosView];
// Set RootViewController to window
if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
{
// warning: addSubView doesn't work on iOS6
[window addSubview: rvC.view]; //新的rootView
}
else
{
// use this method on ios6
[window setRootViewController:rvC]; //新的rootView
}
// VideoPlayer-ios.mm 代码修改如下内容
// 备注 这里只写了实现方式。 具体js调用oc方法 请参考: play / pause / resume 等其余引擎代码的实现。
-(void)swapUpToCanvas{
UIWindow *window = [UIApplication sharedApplication].keyWindow;
// cocos 的父节点里 把video 的预设层级取出来 添加video
[[[eaglview superview] viewWithTag:10] addSubview:self.playerController.view];
}
- 2.2 方法2 不修改原始 cocos 的结构。 通过 keywindow 获取video节点
// 我们是项目中是 自定义的viewControl.mm里修改 (正常工程应该是 AppController.mm)文件修改如下内容 初始化修改
UIWindow *alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
alertWindow.windowLevel = UIWindowLevelAlert;
alertWindow.backgroundColor = HexRGB(0xffa86f);
alertWindow.rootViewController = self;
self.view.frame = CGRectMake(0, 0, APP_SCREEN_WIDTH, APP_SCREEN_HEIGHT);
// 视频view
UIView *videoView = [[UIView alloc] init];
videoView.backgroundColor = UIColor.blackColor;
videoView.tag = 10; // 通过tag找到view
[alertWindow addSubview:videoView];
[videoView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.bottom.right.equalTo(alertWindow);
}];
self.cocosWindow = alertWindow;
//--
self.previousWindow = [UIApplication sharedApplication].keyWindow;
// VideoPlayer-ios.mm 代码修改如下内容
// 备注 这里只写了实现方式。 具体js调用oc方法 请参考: play / pause / resume 等其余引擎代码的实现。
-(void)swapUpToCanvas{
UIWindow *window = [UIApplication sharedApplication].keyWindow;
[[window viewWithTag:10] addSubview:self.playerController.view];
}
逻辑中 代码 调用swapUpToCanvas
// 请注意调用时机。如果 不行的话 自行探索一下 我们项目组是这样调用的
if(this._player.$VideoPlayer && this._player.$VideoPlayer.swapUpToCanvas){
if (cc.sys.os == cc.sys.OS_IOS){
// ios 是 video 实例创建出来以后 才能调用
this.node.runAction(cc.sequence(cc.delayTime(1), cc.callFunc(() => {
this._player.$VideoPlayer.swapUpToCanvas()
}),
cc.delayTime(1),cc.callFunc(() => {
this._player.$VideoPlayer.swapUpToCanvas()
}),
cc.delayTime(1),cc.callFunc(() => {
this._player.$VideoPlayer.swapUpToCanvas()
}),
cc.delayTime(1),cc.callFunc(() => {
this._player.$VideoPlayer.swapUpToCanvas()
})
))
} else {
// web / android 均可以直接调用
this._player.$VideoPlayer.swapUpToCanvas()
}
}
}
至此 项目中就可以动态切换 video 和 canvas 的层级了
video 需要在canvas上边 常规写法就可以
video 需要在canvas上边 创建videoPlayer 的时候。调用一下swapUpToCanvas 即可
这里是一个专注于游戏开发的社区,我们致力于为广大游戏爱好者提供一个良好的学习和交流平台。我们的专区包含了各大流行引擎的技术博文,涵盖了从入门到进阶的各个阶段,无论你是初学者还是资深开发者,都能在这里找到适合自己的内容。除此之外,我们还会不定期举办游戏开发相关的活动,让大家更好地交流互动。加入我们,一起探索游戏开发的奥秘吧!
更多推荐
所有评论(0)