了解Cocos2d-x中的声音引擎
掌握SimpleAudioEngine类
掌握音效的控制
Cocos2d-x中的事件分发机制
了解监听器
了解优先级
掌握触摸事件及其应用
其他事件
Cocos2d-x提供了一个SimpleAudioEngine类支持游戏内的音乐和音效。
它可以被用来增加背景音乐,控制游戏音效。
SimpleAudioEngine类
SimpleAudioEngine单例对象
auto audioEngine = SimpleAudioEngine->getInstance();
播放背景音乐和音效
背景音乐和音效都是异步播放的,
声音引擎做了单独的处理,因此需要分别播放
//背景音乐true表示循环播放,false表示播放一次
audioEngine->playBackgroundMusic("音乐文件Resources的相对路径",true);
//音效
audioEngine->playEffect("音乐文件Resources的相对路径",false,1.0f,1.0f,1.0f);
SimpleAudioEngine支持的音频格式
支持的音乐格式
平台 | 音乐文件格式 | 备注 |
---|---|---|
Android | mp3,mid,ogg,wav | 可以播放android、media、MediaPlayer所支持的所有格式 |
iOS | aac,caf,map3,m4a | 可以播放android、media、MediaPlayer所支持的所有格式 |
Android | mp3,mid,wav | mp3官方文档说支持的是AudioEngine在SimpleAudioEngine引擎底层做了一系列的封装,但是实际cocos2d中SimpleAudioEngine不支持的 |
支持的音效格式
平台 | 音效文件格式 | 备注 |
---|---|---|
Android | ogg,wav | 对wav的支持不完美 |
iOS | caf,m4a | 可以播放Cocos2d-iphone CocosDesion所支持的所有格式 |
Android | mid,wav | 无 |
声音的控制
注意:
1、暂停与恢复相对应,指的是播放中的音频文件暂时停止,
可以通过恢复的方式从暂停位置继续播放。
2、处于暂停中的声音可以直接被停止,停止后不可以恢复播放,只能
只能重新开始播放。
#include "SimpleAudioEngine.h"
using namespace CocosDenshion;
auto audio = SimpleAudioEngine::getInstance();
//暂停背景音乐
audio->pauseBackgroundMusic();
//暂停音效
audio->pauseEffect();
//暂停所有音效
audio->pauseAllEffects();
#include "SimpleAudioEngine.h"
using namespace CocosDenshion;
auto audio = SimpleAudioEngine::getInstance();
//停止背景音乐
audio->stopBackgroundMusic();
//停止音效
audio->stopEffect();
//停止所有音效
audio->stopAllEffects();
恢复与暂停相对应,指的是从暂停位置继续播放音频文件。
#include "SimpleAudioEngine.h"
using namespace CocosDenshion;
auto audio = SimpleAudioEngine::getInstance();
//恢复背景音乐
audio->resumeBackgroundMusic();
//恢复音效
audio->resumeEffect();
//恢复所有音效
audio->resumeAllEffects();
实现背景音乐的控制,要求:
点击按钮播放背景音乐
点击按钮暂停播放背景音乐
点击按钮恢复播放背景音乐
点击按钮停止播放背景音乐
MusicDemo.h
#pragma once
#include "cocos2d.h"
class MusicScene:public Scene
{
public:
CREATE_FUNC(MusicScene);
virtual bool init();
};
MusicDemo.cpp
#include "ui/CocosGUI.h"包含的头文件
#include "ui/UIWidget.h"
#include "ui/UILayout.h"
#include "ui/UIButton.h"
#include "ui/UICheckBox.h"
#include "ui/UIRadioButton.h"
#include "ui/UIImageView.h"
#include "ui/UIText.h"
#include "ui/UITextAtlas.h"
#include "ui/UILoadingBar.h"
#include "ui/UIScrollView.h"
#include "ui/UIListView.h"
#include "ui/UISlider.h"
#include "ui/UITextField.h"
#include "ui/UITextBMFont.h"
#include "ui/UIPageView.h"
#include "ui/UIHelper.h"
#include "ui/UIRichText.h"
#include "ui/UIHBox.h"
#include "ui/UIVBox.h"
#include "ui/UIRelativeBox.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
#include "ui/UIVideoPlayer.h"
#include "ui/UIWebView/UIWebView.h"
#endif
#include "ui/GUIExport.h"
#include "ui/UIScale9Sprite.h"
#include "ui/UIEditBox/UIEditBox.h"
#include "ui/UILayoutComponent.h"
#include "ui/UITabControl.h"
#include "editor-support/cocostudio/CocosStudioExtension.h"
#include "MusicDemo.h"
#include "ui/CocosGUI.h"
using namespace ui;
#include "SimpleAudioEngine.h"
using namespace CocosDenshion;
//CocosGUI包含了UIButton、UIImage、Textture
bool MusicScene::init()
{
if(!Scene::init())return false;
//播放按钮
Size visibleSize = Director::getInstance()->getVisibleSize();
//布局的基准点
Vec2 base = Vec2(visibleSize / 2);
//播放按钮
Button* _button = Button::create();
_button ->setTitleText("Play");
_button ->setTitleFontSize(36);
_button ->setPositionX(base.x);
_button ->setPositionY(base.y + _button->getContentSize().height * 1.5 + 15);
_button->addClickEventListener([](Ref* sender)
{
//播放音乐,true 循环播放
SimpleAudioEngine::getInstance()->playBackgroundMusic("音乐文件相对路径",true);
//控制音量 参数是浮点数 默认的是1.f 1.2f表示在原声音上放大
SimpleAudioEngine::getInstance()->setBackgroundMusicVolume(1.2f);
});
this->addChild(_button);
//暂停按钮
_button = Button::create();
_button ->setTitleText("Pause");
_button ->setTitleFontSize(36);
_button ->setPositionX(base.x);
_button ->setPositionY(base.y + _button->getContentSize().height * 0.5 + 5);
_button->addClickEventListener([](Ref* sender)
{
//暂停播放
SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
});
this->addChild(_button);
//恢复按钮
_button = Button::create();
_button ->setTitleText("Resume");
_button ->setTitleFontSize(36);
_button ->setPositionX(base.x);
_button ->setPositionY(base.y + _button->getContentSize().height * 0.5 - 5);
_button->addClickEventListener([](Ref* sender)
{
//恢复播放
SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
});
this->addChild(_button);
//停止按钮
_button = Button::create();
_button ->setTitleText("Stop");
_button ->setTitleFontSize(36);
_button ->setPositionX(base.x);
_button ->setPositionY(base.y + _button->getContentSize().height * 0.5 - 15);
_button->addClickEventListener([](Ref* sender)
{
//停止播放
SimpleAudioEngine::getInstance()->stopBackgroundMusic();
});
this->addChild(_button);
return true;
}
事件分发机制
Cocos2d-x通过事件分发机制响应用户事件
内置支持常见的事件如触摸事件,键盘事件等。
提供了创建自定义事件的方法,满足我们在游戏的开发过程中,特殊的事件响应需求。
什么是事件分发?
当事件发生(例如,用户触摸屏幕,或者敲键盘);EventDispatcher会发布
(Event objects)事件对象到合适的EventListeners,并调用你的回调。
基本元素:
事件监听器:EventListeners
事件分发器:EventDispatcher
事件对象:Event
优先级
使用一个整形的数值,数值较低的监听器比数值较高的监听器,先接收到事件。
场景图优先级
是指向节点对象的指针,z-order较高的节点中的监听器比z-order
较低的节点中的,先接收到事件。
事件的吞没
监听器接收到期望的事件
这时事件应该被吞没
触摸事件
什么是触摸事件
当你触摸移动设备的屏幕时,设备感受到被触摸,获取被触摸的位置和信息,然后反馈给你。
提示:如果需要触摸控制屏幕下层节点,可以通过优先级达成这种需求,优先级高的能先处理事件。
//创建单点事件监听器
auto listener1 = EventListenerTouchOneByOne::create();
//按住时触发事件
listener1 ->onTouchBegan = [](Touch* touch,Event* event)
{
//true表示成功触发
return true;
};
//按住滑动时触发事件
listener1 ->onTouchMoved = [](Touch* touch,Event* event){};
//释放时时触发事件
listener1 ->onTouchMoved = [=](Touch* touch,Event* event){};
//添加监听器
_eventDispatcher ->addEventListenerWithSceneGraphpriority(listenere1,this);
演示事件的触摸:
TouchLayer.h
#pragma once
#include "cocos2d.h"
class TouchLayer:public Scene
{
public:
CREATE_FUNC(TouchLayer);
virtual bool init();
};
TouchLayer.cpp
bool TouchLayer::init()
{
//设置成当前大小
this->setContentSize(Director::getInstance()->getVisibleSize());
//演示触摸事件的处理
auto listener = EventListenerTouchOneByOne::create();
//添加按下事件
listener ->onTouchBegan = [](Touch* touch,Event* event)
{
log("touch began");
//true表示成功触发
return true;
};
//添加释放事件
listener ->onTouchEnded = [](Touch* touch,Event* event)
{
log("touch end");
};
//添加移动事件
listener ->onTouchMoved = [](Touch* touch,Event* event)
{
log("touch moved");
};
//事件分发器必须要先添加事件
//添加到事件分发器中
_eventDispatcher ->addEventListenerWithSceneGraphpriority(listenere,this);
return false;
}
键盘事件
//创建键盘事件监听器
auto listener = EventListenerboard::create();
listener ->onKeyPressed = CC_CALLBACK_2(KeyBoardTest::onKeyPressed,this);
listener ->onKeyReleased = CC_CALLBACK_2(KeyBoardTest::onKeyReleased,this);
//添加键盘事件监听器
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this);
//实现键盘按键按下事件回调函数
void keyboardTest::onKeyPressed(EventKeyboard::KeyCode KeyCode,Event* event)
{
log("key with keycode %d pressed",KeyCode);
}
//实现键盘按键释放事件回调函数
void keyboardTest::onKeyReleased(EventKeyboard::KeyCode KeyCode,Event* event)
{
log("key with keycode %d released",KeyCode);
}
加速度传感器事件
一些移动设备备有加速度传感器,通过监听它的事件获取各方向的加速度。
//启用加速度传感器
Device::setAccelerometerEnabled(true);
//创建加速度传感器
auto listener = EventListenerAcceleration::create(
CC_CALLBACK_2(AccelerometerTest::onAcceleration,
this));
_eventDispatcher ->addEventListenerWithSceneGraphpriority(listenere,this);
//加速度传感器事件处理方法
void AccelerometerTest::onAcceleration(Acceleration* acc,Event* event){};
鼠标事件
创建鼠标事件
_mouseListener = EventListenerMouse::create();
_mouseListener ->onMouseMove = CC_CALLBACK_1(MouseTest::omMouseMove,this);
_mouseListener ->onMouseUp = CC_CALLBACK_1(MouseTest::onMouseUp ,this);
_mouseListener ->onMouseDown = CC_CALLBACK_1(MouseTest::onMouseDown ,this);
_mouseListener ->onMouseScroll = CC_CALLBACK_1(MouseTest::onMouseScroll,this);
_eventDispatcher ->addEventListenerWithSceneGraphpriority(_mouseListener ,this);
事件类型
//鼠标按下事件
void MouseTest::omMouseDown(Event* event){}
//鼠标释放事件
void MouseTest::omMouseUp(Event* event){}
//鼠标移动事件
void MouseTest::omMousemove(Event* event){}
//鼠标滚轮事件
void MouseTest::omMouseScroll(Event* event){}
触摸事件传递到下层,控制上层的精灵移动,要求:
上层触摸事件控制该层的左右移动
事件传递到下层
下层事件控制精灵的竖直上下移动
EventDemo.h
#pragma once
#include "cocos2d.h"
class EventScene:public Scene
{
public:
CREATE_FUNC(EventScene);
virtual bool init();
};
EventDemo.cpp
#include "TopLayer.h"
#include "BottomLayer.h"
bool EventScene::init()
{
//创建两个层容器
//第一个层容器TopLayer中添加一个背景精灵和一个控制精灵
auto topLayer = TopLayer::create();
this->addChild(topLayer);
auto bottomLayer = BottomLayer::create(topLayer->getSprite());
this->addChild(bottomLayer);
return true;
}
TopLayer.h
#pragma once
#include "cocos2d.h"
class TopLayer:public Layer
{
public:
CREATE_FUNC(TopLayer);
virtual bool init();
Sprite* getSprite();
private:
//记录受控制的精灵
Sprite* _sprite;
//记录当前坐标点
Vec2 _position;
};
TopLayer.cpp
bool TopLayer::init()
{
Size visible = Director::getInstance()->getVisibleSize();
Vec2 center = Vec2(visibleSize / 2);
//创建背景精灵
Sprite* bg = Sprite::create("图片相对路径");
bg->setPosition(bg);
this->addChild(bg);
//创建受控制精灵
_sprite = Sprite::create("图片相对路径");
_sprite ->setPosition(center);
this->addChild(_sprite);
//创建一个单点事件监听器
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [this](Touch* touch,Event* event){
//记录按下的坐标点
_position = touch->getLocation();
return true;
};
listener->onTouchMoved = [](Touch* touch,Event* event)
{
//记录顶层左右水平移动的距离
float distance = touch->getLocation().x - _position.x;
//设置TopLayer显示坐标
auto node = event->getCurrentTarget();
node->setPositionX(node->getPositionX() + distance);
//重置当前的触摸点用于下次计算
_position.x = touch->getLocation().x;
};
_eventDispatcher ->addEventListenerWithSceneGraphpriority(listener,this);
return true;
}
Sprite* TopLayer::getSprite()
{
return _sprite ;
}
BottomLayer.h
#pragma once
#include "cocos2d.h"
class BottomLayer:public Layer
{
public:
//重载一个create方法
static BottomLayer*create(Sprite * sprite);
CREATE_FUNC(BottomLayer);
virtual bool init();
private:
//顶层送控制的精灵对象
Sprite* _sprite;
//记录当前坐标点
Vec2 _position;
};
BottomLayer.cpp
bool BottomLayer::init()
{
//创建一个单点事件监听器
auto listener = EventListenerTouchOneByOne::create();
listener->onTouchBegan = [this](Touch* touch,Event* event){
//记录按下的坐标点
_position = touch->getLocation();
return true;
};
listener->onTouchMoved = [](Touch* touch,Event* event)
{
//记录精灵竖直移动的位置
float distance = touch->getLocation().y - _position.y;
//设置受控制精灵的显示坐标
_sprite->setPositionY(_sprite->getPositionY() + distance);
//重置当前的触摸点用于下次计算
_position.y = touch->getLocation().y;
};
_eventDispatcher ->addEventListenerWithSceneGraphpriority(listener,this);
return true;
}
BottomLayer * BottomLayer::create(Sprite * sprite)
{
auto layer = BottomLayer::create();
layer->_sprite = sprite;
return layer;
}
边学边写,如果有哪里不正确的地方还请小伙伴们及时指出来,码字不易还请谅解!