最近《宠物联萌》在三星App上发布遇到一个问题:如果用户在锁定屏幕时解锁解到一半时取消解锁,这时用cocos2d-x开发的游戏就会出现游戏Bgm会恢复播放,但手机屏幕仍然是锁屏状态的Bug。

简述情况:

·游戏运行平台:Android

·Cocos2d-x引擎版本:cocos2d-1.0.1-x-0.13.0-beta

·问题出现操作:Android手机在锁屏状态下,玩家解锁解到一半时取消解锁(用圆环锁比较容易重现)

·是否经过测试:已测试,暂无发现问题

遇到Bug后初步分析了原因,估计是因为玩家解锁到一半时,触发了Android系统恢复游戏进程的操作,触发AppDelegate的applicationWillEnterForeground(),这个函数一般包括SimpleAudioEngine的resumeBackgroundMusic(),即游戏进程重新进入时,恢复游戏音乐。

简单来说,就是玩家解锁到一半时,游戏已经恢复到屏幕上了,但此时被手机的锁屏界面覆盖住,导致这个Bug的发生:锁屏界面下能听到游戏Bgm。

要验证这个问题很简单,当游戏进入后台时,Android系统会把纹理资源全部释放掉,之所以玩家重新进入游戏时会出现黑屏几秒的现象,是因为游戏此刻在重新加载资源,写得好的游戏控制好纹理数量其实还是可以做到“秒进”屏幕的,不过《宠物联萌》代码写得比较挫,会黑屏几秒。在这个Bug的情况下,我们在锁屏界面听到音乐后直接解锁,可以看到游戏已经显示在屏幕,并没有出现黑屏加载资源,是因为游戏已经把纹理数据都加载好显示到屏幕上了,只是被锁屏界面覆盖住了。

因为游戏其实已经恢复到屏幕上,所以想在OnEnter里面恢复游戏Bgm是不可行的,CTO给了一个解决方案:AppDelegate不作恢复音乐操作,而是由用户自己第一次点击屏幕时恢复音乐。不过这个解决方案治标不治本,而且每个CCLayer都要做这样的处理,改动太多容易产生别的Bug,而且如果玩家一直不点击屏幕,那么游戏会一直“静音”,所以觉得这个方案不太好。于是我没有用这个解决方案。

知道问题来源,简单做了个设想:假设在锁屏状态下,游戏Activity虽然恢复界面了,因为有锁屏界面,所以Activity没有被系统Focus;而当手机解锁时,锁屏界面被系统移除,然后系统会Focus Activity,如果Activity有Focus的响应函数,那么我们在失去Focus时暂停音乐,而在触发Focus时恢复游戏Bgm,不就可以了~。

带着这个假设翻了一下Android的Activity类,看看有没有这样的响应方法,幸运地发现了:public void onWindowFocusChanged(boolean hasFocus) {}。到这一步其实已经成功了,只要我们在游戏的Activity上重写该方法即可,比如:

public class TestsDemo extends Cocos2dxActivity{

 @Override

 public void onWindowFocusChanged(boolean hasFocus) {

 super.onWindowFocusChanged(hasFocus);

 MMJNIUtilities.handleOnWindowFocusChanged(hasFocus);

    }

}

public class MMJNIUtilities {

 public static native void handleOnWindowFocusChanged(boolean hasFocus);

}

note:很久没写Java,上面代码有错误请见谅。

最后通过javah生成这个MMJNIUtilities的头文件,并实现handleFocus方法即可,比如:

JNIEXPORT void JNICALL Java_org_cocos2dx_tests_MMJNIUtilities_handleOnWindowFocusChanged( JNIEnv * env, jclass jClass , jboolean hasFocus )

{

if (hasFocus)

{

SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();

SimpleAudioEngine::sharedEngine()->resumeAllEffects();

}

else

{

SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();

SimpleAudioEngine::sharedEngine()->pauseAllEffects();

}

}

漏了一点,因为现在是通过Activity的Focus来控制音乐开关,所以AppDelegate也要做相应修改:

// This function will be called when the app is inactive. When comes a phone call,it's be invoked too

void AppDelegate::applicationDidEnterBackground()

{

    CCDirector::sharedDirector()->pause();

//     SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();

// SimpleAudioEngine::sharedEngine()->pauseAllEffects();

}

// this function will be called when the app is active again

void AppDelegate::applicationWillEnterForeground()

{

    CCDirector::sharedDirector()->resume();

//     SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();

// SimpleAudioEngine::sharedEngine()->resumeAllEffects();

}

随后编个Apk在手机上测了一下,锁屏状态下没有声音了,搞定。这个解决方案感觉比较治本,而且对游戏的改动不多,不必修改整个游戏的CCLayer。不过这个方法暂时没经过测试,不保证没有任何风险,对cocos2d-x的tests做了点修改作为例子,有兴趣可以下来看看。

http://files.cnblogs.com/j1223jesus/%E4%BF%AE%E6%94%B9%E8%BF%87%E7%9A%84tests_0.13.0-beta.zip

[cocos2d-x·解Bug]关于cocos2d-x游戏在android锁屏状态下播放Bgm的解决方法的更多相关文章

  1. Centos7解压.tar.bz2提示tar (child): bzip2: Cannot exec: No such file or directory解决方法

    Centos7解压.tar.bz2提示tar (child): bzip2: Cannot exec: No such file or directory解决方法 原因是因为该centos没有bzip ...

  2. [Bug]转:使用jquery的 uploadify,在谷歌浏览器上总会崩溃的解决方法

    最近做的项目使用了jquery的uploadify,但是在谷歌浏览器测试总是会出现崩溃.如: 因为是java项目. 解决的办法是: 给引入的js加上一个参数,时间戳就可以,防止缓存,使每一次都请求.( ...

  3. Mac系统下的zip压缩包解压到Windows下出现乱码的解决方法

    环境变量 环境变量是具有特殊名字的一个特定对象,包含了一个或多个应用程序运行所需的信息.(例如PATH,可执行程序的搜索路径,当要求系统运行一个程序,而没告诉系统它的具体路径时,系统就要在PTAH值的 ...

  4. ie6,ie7,ie8 css bug兼容解决方法

    IE浏览器以不支持大量的css 属性出名,同时也因其支持的css属性中存在大量bug. 这里收集了好多的bug以及其解决的办法,都在这个文章里面记录下来了!希望以后解决类似问题的时候能够快速解决,也希 ...

  5. 解Bug之路-TCP粘包Bug

    解Bug之路-TCP粘包Bug - 无毁的湖光-Al的个人空间 - 开源中国 https://my.oschina.net/alchemystar/blog/880659 解Bug之路-TCP粘包Bu ...

  6. 老程序员解Bug的通用套路

    千万不要当程序员面说有bug 对于新手程序员而言,在复杂代码中找BUG是一个难点.下面我们总结下老从程序员解Bug的通用套路,希望对大家有帮助. 1.IDE调试 根据项目特点和语言特点选择一个最合适的 ...

  7. 解Bug之路-记一次中间件导致的慢SQL排查过程

    解Bug之路-记一次中间件导致的慢SQL排查过程 前言 最近发现线上出现一个奇葩的问题,这问题让笔者定位了好长时间,期间排查问题的过程还是挺有意思的,正好博客也好久不更新了,就以此为素材写出了本篇文章 ...

  8. 解Bug之路-记一次存储故障的排查过程

    解Bug之路-记一次存储故障的排查过程 高可用真是一丝细节都不得马虎.平时跑的好好的系统,在相应硬件出现故障时就会引发出潜在的Bug.偏偏这些故障在应用层的表现稀奇古怪,很难让人联想到是硬件出了问题, ...

  9. 解Bug之路-记一次JVM堆外内存泄露Bug的查找

    解Bug之路-记一次JVM堆外内存泄露Bug的查找 前言 JVM的堆外内存泄露的定位一直是个比较棘手的问题.此次的Bug查找从堆内内存的泄露反推出堆外内存,同时对物理内存的使用做了定量的分析,从而实锤 ...

随机推荐

  1. angular入门系列教程3

    主题: 本篇主要目的就是继续完善home页,增加tab导航的三个页index index1 index2 效果图: 细节: 初始化的JS就是咱们的home.js,仔细来看. angular的route ...

  2. FZU 2016 summer train I. Approximating a Constant Range 单调队列

    题目链接: 题目 I. Approximating a Constant Range time limit per test:2 seconds memory limit per test:256 m ...

  3. log4j安装与简介

    问题描述:     在应用程序中添加日志记录总的来说基于三个目的:    (1) 监视代码中变量的变化情况,周期性的记录到文件中供其他应用进行统计分析工作:     (2) 跟踪代码运行时轨迹,作为日 ...

  4. 2-Highcharts曲线图之折线图

    示例图片,在网上下载一张图片如图:其中数据自定义 引入上节模版配置  在script标签中写代码:具体代码如下   信息将在代码中解释. 分析:“五省收益趋势”是标题: x坐标为[2011年-2016 ...

  5. hdoj 1102 Constructing Roads

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1102 分析:看到这题给出的都是矩阵形式,就知道了可以用Prim算法求MST. #include <i ...

  6. 1009 FatMouse' Trade

    FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  7. Session过期,跳出iframe等框架

    //在你想控制跳转的页面,如login.jsp中的<head>与</head>之间加入以下代码:    if(window != top){        //解决Sessio ...

  8. codeforces div.1 A

    A. Efim and Strange Grade time limit per test 1 second memory limit per test 256 megabytes input sta ...

  9. Project Euler 99:Largest exponential 最大的幂

    Largest exponential Comparing two numbers written in index form like 211 and 37 is not difficult, as ...

  10. springmvc环境的搭建

    最近应公司要求,用了2天时间学了springmvc的搭建,就简单总结一下: springmvc和struts2的比较,因为我是学过struts的,它们都是基于mvc模式而设计的web层框架 它们最大的 ...