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;


在MciPlayer.cpp文件开头加上#include<Digitaly.h>,并添加上述两个函数的实现:

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;}


SimpleAudioEngine.cpp中修改SimpleAudioEngine.h中声明了却没有实现的四个函数(Line 233):

//////////////////////////////////////////////////////////////////////////// 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重新生成,然后就可以改变和获取背景音乐和音效的音量了。

0 0
原创粉丝点击