Cocos2d-x学习笔记(二)——各种错误和遇到问题整理(不断更新)
来源:互联网 发布:常用数据分析工具 编辑:程序博客网 时间:2024/06/04 19:29
本文用于记录在Cocos2d-x项目开发过程中遇到的困难,及对应的解决方法。
1、AppDelegate.h找不到新添加的MyScene.h
用vs2010打开HelloCC工程后,在AppDelegate.h文件中#include "MyScene.h",会提示找不到MyScene.h,看了一下,新建类后MyScene.h,MyScene.cpp的生成位置是在Cocos2d-x-2.2.5\projects\HelloCC\proj.win32中,再看一下AppDelegate.cpp的属性 -> C/C++常规 -> 附加包含目录:
可以发现$(ProjectDir)代表Cocos2d-x-2.2.5\projects\HelloCC\proj.win32,这里却没有包含$(ProjectDir)的路径,于是也就找不到在该路径下的MyScene.h了。
解决方法:手动添加$(ProjectDir)至附加包含目录。
2、Eclipse工作空间(Workspace)修改之后,HelloCC项目配置不见
默认的Eclipse工作空间是在C:\Users\Richard\Workspace,今天打开Eclipse的时候,把它修改到了Eclipse安装位置下的projects文件夹下,启动后发现之前import的项目HelloCC消失。最笨的方法,是重新import一遍,但是这样就要对项目重新配置一遍,由于配置的过程(前一篇笔记中有详细描述)很繁琐,所以另寻方法。
解决方法:这个Eclipse是随SDK一起的,到目前只import过HelloCC一个项目,工作空间很干净,而且我在import项目的时候没有copy项目至工作空间,所以,原来工作空间中的文件应该保存了所有导入项目的配置。于是定位到C:\Users\Richard\Workspace,下面只有一个文件:.metadata(2.57 MB),再看一下新的工作空间,里面也有一个.metadata,几百kb,很明显,这就是保存配置信息的文件了,于是把C:\Users\Richard\Workspace目录下的./metadata拷贝至D:\Program_Files\adt-bundle-windows-x86-20131030\eclipse\projects,全部覆盖。重启Eclipse,发现HelloCC项目已经在左侧的包资源管理器中,再检查一下所有项目配置,完好。
3、Classes文件夹中添加自己的源文件后,在Cygwin中执行./build_native.sh编译时出错
目前只新加了MyScene类,两个新文件,MyScene.h和MyScene.cpp。观察一下Cocos2d-x-2.2.5\projects\HelloCC的目录结构,发现一堆proj文件,一个Classes文件夹(其中包含了创建HelloCC工程时的所有源文件),一个Resources文件夹(包含所有可以在工程中被使用的资源文件),不同平台的工程互相独立,但是共用Classes和Resources文件夹。于是我把\HelloCC\proj.win32下的MyScene.h和MyScene.cpp拷贝至Classes文件中,然后运行Cygwin,定位到\projects\HelloCC\proj.android文件夹下,运行build_native.sh,却出现如下错误:
AppDelegate.cpp找不到MyScene::scene()的引用,第一个直觉是,NDK不认识USING_NS_CC; 所以MyScene类对CCLayer的继承应该写完整:class MyScene : public cocos2d::CCLayer,改完之后,却发现还是报同样的错误。之后又陆续修改添加#ifndef等细节,以使MyScene.h和MyScene.cpp与原生的HelloWorldScene.h和HelloWorldScene.cpp保持一致,直到修改为完全一致,却依然报错。这样就确定了问题不是出在源文件上,而应该是编译配置上。
解决方法:定位到\HelloCC\proj.android\jni\Android.mk,在LOCAL_SRC_FILES中添加MyScene.cpp。
编译通过:
4、关于背景音乐和音效(cocos2d-x中的play-stop和resume-pause)
前两天在学习音乐和音效的时候,遇到一些问题。我单独写了一个设置界面类,通过开始界面的“设置”按钮进入。设置中首先添加的是背景音乐和音效,起初我想实现的功能是:进入游戏后,音乐和音效是默认播放,用户可以在设置界面关闭音乐或调整音量,背景音乐在暂停以后,玩家再次开启时,应该接着往下播放,而不是从头开始,另外,背景音乐应该循环播放。
先说第一个问题:音乐关闭与开启。我在AppDelegate类中加载背景音乐,在pDirector->runWithScene(pScene)语句之后添加了SimpleAudioEngine::sharedEngine()->playBackgroundMusic(BGMUSIC, true),这样一进入游戏就会默认播放背景音乐。另外,我在SettingScene类中简单地用CCMenuItemToggle类的createWithTarget函数做了一个开关按钮,On表示音乐开启,Off表示音乐关闭,那么我想应该使用pause和resume。做完后测试时却发现了问题:一是开关状态显示错误,二是音乐有时候不会循环播放。错误出现场景:进入设置界面把音乐开关设为Off,再点一次,变为On,这时候返回开始界面,再次进入设置界面时,发现音乐开关状态为Off,停留在设置界面把音乐听完,发现不会循环播放。我用于设置音乐开关显示的代码如下:
CCMenuItemFont::setFontName("Consolas");CCMenuItemFont::setFontSize(30);CCMenuItemFont *On = CCMenuItemFont::create("On");CCMenuItemFont *Off = CCMenuItemFont::create("Off");CCMenuItemToggle *music = CCMenuItemToggle::createWithTarget(this,menu_selector(SettingScene::menuMusicCallback),On, Off, NULL);music->setPosition(ccp(winSize.width/2, winSize.height/2));if(SimpleAudioEngine::sharedEngine()->isBackgroundMusicPlaying())music->setSelectedIndex(0);elsemusic->setSelectedIndex(1);
代码是没问题的,问题是音乐明明在播放,SimpleAudioEngine::sharedEngine()->isBackgroundMusicPlaying()却返回了false,也就是它认为音乐已经停止了,于是执行了else语句,把开关设置为Off。我查看了这个函数的实现,一直追踪到MciPlayer类,stop的实现会执行m_bPlaying = false,而pause不会,所以是没什么问题的。既然函数实现没什么问题,那唯一的解释就是音乐确实“停止”了,而在播放的部分只是内存中尚未用完的部分,这也就解释了为什么背景音乐只是播放完一遍,没有循环播放。
解决方法:在音乐按钮的效果中,用play-stop实现,代替resume-pause。于是效果就变为:停止后再次开启音乐,音乐会从头开始播放,但循环播放没问题。之后我找了很多游戏看这个功能,却发现它们实现的功能也都是停止后再开启,会使音乐从头播放。
关于resume-pause为何出现错误,我想是因为pause的使用,干扰了AppDelegate中的循环播放设置,所以造成上述情况:系统认为音乐停止了,所以置Off,音乐也没有再循环播放。场景切换时,每次都会执行init函数来初始化场景,而StartScene类和SettingScene类并没有play的命令,所以在设置界面暂停音乐后,回到开始界面再回去,循环播放设置没有被再次加载到内存中(保持被干扰的状态),于是系统判定播放完不再继续。因此,如果要做到“继续播放”,必须在这两个类中使用play,这样却违背了play-stop和resume-pause搭配的原则,具体方法也有待研究。
第二个问题,是我在win32下对音量的设置无效,网上很多教程,都是流于表面,只是介绍函数功能却没有提出这个问题,直到我今晚看到这篇文章(http://www.zaojiahua.com/sound.html)中说的,win32下无法改变音量,但在android上是可以的,经过测试,确实能在android上体现出音量变化,关于win32下为何不能改变音量,还有待研究。
5、背景音乐和音效的音量调节(cocos2d-x版本:2.2.5)
这个问题在4中已经提出,今天再次遇到这个问题,无论怎么设置(set)音量,音量的返回值(get)始终是1.0,当然直观的感受——音量也没有丝毫变化,并最终找到了原因和解决方法(http://blog.csdn.net/u012855000/article/details/20841943)。
这里涉及到cocos2d-x提供的四个获取和调节背景音乐音效音量的函数,它们定义在SimpleAudioEngine.h中:
// properties /** @brief The volume of the background music max value is 1.0,the min value is 0.0 @js getMusicVolume */ float getBackgroundMusicVolume();//获取背景音乐音量 /** @brief set the volume of background music @param volume must be in 0.0~1.0 @js setMusicVolume */ void setBackgroundMusicVolume(float volume);//设置背景音乐音量 /** @brief The volume of the effects max value is 1.0,the min value is 0.0 */ float getEffectsVolume();//获取音效音量 /** @brief set the volume of sound effecs @param volume must be in 0.0~1.0 */ void setEffectsVolume(float volume);//设置音效音量打开SimpleAudioEngine.cpp寻找这几个函数的实现,却看到如下一幕:
根本没有实现这四个函数,而getBackgroundMusicVolume()和getEffectVolume()则直接返回了1.0的结果,难怪无论怎么设置(set)音量,音量始终“显示”1.0。
解决方法:为上述四个函数添加实现。
在MciPlayer.h中添加两个函数声明:
// @volume value ranges from 0 .. 1000void Volume(UINT volume);// @return value ranges from 0 .. 1000UINT MciPlayer::Volume() const;
void MciPlayer::Volume(UINT volume){if (!m_hDev) return;MCI_DGV_SETAUDIO_PARMS mciParams = {0};mciParams.dwItem = MCI_DGV_SETAUDIO_VOLUME;mciParams.dwValue = volume;mciSendCommand(m_hDev, MCI_SETAUDIO, MCI_DGV_SETAUDIO_ITEM | MCI_DGV_SETAUDIO_VALUE, (DWORD)&mciParams);}UINT MciPlayer::Volume() const{if (!m_hDev) return 0;MCI_STATUS_PARMS mciParams = {0};mciParams.dwItem = MCI_DGV_STATUS_VOLUME;mciSendCommand(m_hDev, MCI_STATUS, MCI_STATUS_ITEM, (DWORD)&mciParams);return mciParams.dwReturn;}
//////////////////////////////////////////////////////////////////////////// volume interface//////////////////////////////////////////////////////////////////////////float SimpleAudioEngine::getBackgroundMusicVolume(){ //return 1.0;return sharedMusic().Volume() / 1000.0f;}void SimpleAudioEngine::setBackgroundMusicVolume(float volume){sharedMusic().Volume((UINT)(volume * 1000.0));}float SimpleAudioEngine::getEffectsVolume(){ //return 1.0; //return sharedList().at(0)->Volume() / 1000.0f;//vs2010下出错 return sharedList().begin()->second->Volume() /1000.0f;}void SimpleAudioEngine::setEffectsVolume(float volume){EffectList::iterator iter;for (iter = sharedList().begin(); iter != sharedList().end(); iter++){iter->second->Volume((UINT) (volume * 1000.0));}}
全部保存之后,对libCocosDenshion重新生成,然后就可以改变和获取背景音乐和音效的音量了。
- Cocos2d-x学习笔记(二)——各种错误和遇到问题整理(不断更新)
- OpenCV学习笔记(4)——VS环境下调试遇到的问题整理(不断更新……)
- Cocos2d-x学习笔记(二)Cocos2d-x整体框架
- Cocos2D-X学习笔记(二)
- cocos2d-x+cocosbuilder 学习笔记 (二)
- Cocos2d-x学习笔记(二)
- Cocos2d-x学习笔记(二)------HelloWorld
- cocos2d-x Physics 学习笔记(二)
- Cocos2d-x学习笔记(二)——Cocos2d的基本框架认识
- cocos2d x 入门学习(二)Star Fighter项目交叉编译时遇到的问题
- Android开发遇到的各种问题的解决办法(不断更新!!!)
- cocos2d-x 遇到的各种问题汇总
- Cocos2d-x jsb + Cocos2d-html5 跨平台游戏开发(二)—— 遇到的坑
- Cocos2d-x jsb + Cocos2d-html5 跨平台游戏开发(二)—— 遇到的坑
- Cocos2d-x基本概念整理(二)CCAction
- c++学习笔记序列之错误码整理(不断更新中)
- cocos2d-x学习笔记(二)浅入动画教程。
- cocos2d-x学习笔记(二)--场景切换
- c/c++标准预定义宏
- 两种文件配置项设置方法及C程序处理的比较
- C++11新特性
- 第八周项目6本月有几天
- C调用lua
- Cocos2d-x学习笔记(二)——各种错误和遇到问题整理(不断更新)
- Android ActionBar完全解析,使用官方推荐的最佳导航栏(上)
- (Delphi中处理字符串)截取中文字符和英文字符,去除所有数字
- hybris学习笔记:New Extension
- 求字符串中满足所有字符个数相等的最长子串长度
- Android ActionBar完全解析,使用官方推荐的最佳导航栏(下)
- Android平台下使用lua调用Java代码经验总结
- 网易新闻IOS客户端
- 矩阵构造方法汇总(结合递推)