1、.h头文件@H_502_1@
#include "cocos2d.h"
#include "ui/CocosGUI.h"
#include "VisibleRect.h"
USING_NS_CC;
using namespace ui;
class BillBoardDemo : public cocos2d::Layer
{
public:
CREATE_FUNC(BillBoardDemo);
virtual bool init();
virtual void update(float dt) override;
void addNewBillBoardWithCoords(Vec3 p);
void addNewAniBillBoardWithCoords(Vec3 p);
void rotateCameraCallback(Ref* sender,float value);
void onTouchesMoved(const std::vector<Touch*>& touches,Event* event);
void menuCallback_orientedPoint(Ref* sender);
void menuCallback_orientedPlane(Ref* sender);
BillBoardDemo();
virtual ~BillBoardDemo();
protected:
Camera* _camera;
Layer* _layerBillBoard;
std::vector<BillBoard*> _billboards;
};
2、.cpp文件@H_502_1@
#include "BillBoardTest.h"
BillBoardDemo::BillBoardDemo()
:_camera(nullptr)
{
}
bool BillBoardDemo::init()
{
bool bRet = false;
do{
CC_BREAK_IF(!Layer::init());
//注册事件监听
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesMoved = CC_CALLBACK_2(BillBoardDemo::onTouchesMoved,this);//事件回调
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(listener,this);
//添加层
auto layer3D = Layer::create();
addChild(layer3D,0);
_layerBillBoard = layer3D;
auto winSize = Director::getInstance()->getWinSize();
//创建摄像机
if(_camera == nullptr)
{
//参数1:透视相机的视野。参数2:相机的长宽比。参数3:近点平面距离。参数4:远点平面距离
_camera = Camera::createPerspective(60,(GLfloat)winSize.width / winSize.height,1,500);
_camera->setCameraFlag(CameraFlag::USER1);//设置相机Flag,便于相机识别节点
_layerBillBoard->addChild(_camera);//相机加入层
}
std::string imgs[3] = {"Icon.png","r2.png"};
for(unsigned int i = 0; i < 4; i++)
{
Layer* layer = Layer::create();
//随机创建BillBoard对象
auto billboard = BillBoard::create(imgs[(unsigned int)(CCRANDOM_0_1()*1+0.5)]);
billboard->setScale(0.5);//设置缩放
//CCRANDOM_MINUS1_1返回一个-1到1的float值
billboard->setPosition3D(Vec3(0.0f,0.0f,CCRANDOM_MINUS1_1()*150.0f));//设置3D坐标
//ALPHA_NON_PREMULTIPLIED混合方式 {GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA}
//源因子使用源颜色的透明度,目标因子使用减去源颜色的透明度
billboard->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);//设置颜色混合
billboard->setOpacity(CCRANDOM_0_1()*128+128);//设置可见性
_billboards.push_back(billboard);
layer->addChild(billboard);
//1,层对象加入层
_layerBillBoard->addChild(layer);//加入层
layer->runAction(RepeatForever::create(RotateBy::create(CCRANDOM_0_1(),Vec3(0.0f,45.0f,0.0f))));//层执行翻转动作
}
{
auto billboard = BillBoard::create("Icon.png");
billboard->setScale(0.2f);
billboard->setPosition3D(Vec3(0.0f,30.0f,0.0f));
auto billboard2 = BillBoard::create("r2.png");
billboard2->setPosition3D(Vec3(0.0f,100.0f));
billboard->addChild(billboard2);
_billboards.push_back(billboard);
_billboards.push_back(billboard2);
auto sprite3D = Sprite3D::create("orc.c3t");
sprite3D->setScale(2.0f);
sprite3D->addChild(billboard);
sprite3D->runAction(RepeatForever::create(RotateBy::create(10.0f,360.0f,0.0f))));
//2,Sprite3D对象加入层
_layerBillBoard->addChild(sprite3D);
}
//添加新的billboard
addNewBillBoardWithCoords(Vec3(20,5,0));
addNewBillBoardWithCoords(Vec3(60,0));
addNewBillBoardWithCoords(Vec3(100,0));
addNewBillBoardWithCoords(Vec3(140,0));
addNewBillBoardWithCoords(Vec3(180,0));
addNewAniBillBoardWithCoords(Vec3(-20,0));
addNewAniBillBoardWithCoords(Vec3(-60,0));
addNewAniBillBoardWithCoords(Vec3(-100,0));
addNewAniBillBoardWithCoords(Vec3(-140,0));
addNewAniBillBoardWithCoords(Vec3(-180,0));
_camera->setPosition3D(Vec3(0,100,230));//设置相机的3D位置
_camera->lookAt(Vec3(0,0),Vec3(0,0));//设置相机的,参数1:目标的中心位置,参数2:向上的向量
//添加菜单
TTFConfig ttfConfig("fonts/arial.ttf",30);
auto label1 = Label::createWithTTF(ttfConfig,"rotate+");
auto menuItem1 = MenuItemLabel::create(label1,CC_CALLBACK_1(BillBoardDemo::rotateCameraCallback,this,10));
auto label2 = Label::createWithTTF(ttfConfig,"rotate-");
auto menuItem2 = MenuItemLabel::create(label2,-10));
auto menu = Menu::create(menuItem1,menuItem2,nullptr);
menu->setPosition(Vec2::ZERO);
menuItem1->setPosition(Vec2(winSize.width - 80,VisibleRect::top().y - 160));
menuItem2->setPosition(Vec2(winSize.width - 80,VisibleRect::top().y - 190));
addChild(menu,0);
_layerBillBoard->setCameraMask(2);//设置mask使得对相机可见
//设置billboard观察模式
label1 = Label::createWithTTF(ttfConfig,"Point Oriented");
menuItem1 = MenuItemLabel::create(label1,CC_CALLBACK_1(BillBoardDemo::menuCallback_orientedPoint,this));
label2 = Label::createWithTTF(ttfConfig,"Plane Oriented");
menuItem2 = MenuItemLabel::create(label2,CC_CALLBACK_1(BillBoardDemo::menuCallback_orientedPlane,this));
menuItem1->setPosition(Vec2(winSize.width -80,VisibleRect::top().y - 100));
menuItem2->setPosition(Vec2(winSize.width -80,VisibleRect::top().y - 130));
menu = Menu::create(menuItem1,nullptr);
menu->setPosition(Vec2::ZERO);
this->addChild(menu,10);
menuCallback_orientedPoint(nullptr);
bRet = true;
}while(0);
return bRet;
}
void BillBoardDemo::menuCallback_orientedPoint(cocos2d::Ref *sender)
{
for(auto& billboard : _billboards)
{
billboard->setMode(BillBoard::Mode::VIEW_POINT_ORIENTED);
}
}
void BillBoardDemo::menuCallback_orientedPlane(cocos2d::Ref *sender)
{
for(auto& billboard : _billboards)
{
billboard->setMode(BillBoard::Mode::VIEW_PLANE_ORIENTED);
}
}
BillBoardDemo::~BillBoardDemo()
{
if(_camera)
{
_camera = nullptr;
}
}
//创建新的BillBoard
void BillBoardDemo::addNewBillBoardWithCoords(Vec3 p)
{
std::string imgs[3] = {"Icon.png","r2.png"};
for(unsigned int i = 0; i < 10; i++)
{
//随机图片
auto billboard = BillBoard::create(imgs[(unsigned int)(CCRANDOM_0_1()*1+0.5)]);
billboard->setScale(0.5f);
billboard->setPosition3D(Vec3(p.x,p.y,-150.0f+30*i));//Z轴值越来越大
billboard->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);//设置颜色混合方式
billboard->setOpacity(CCRANDOM_0_1()*128+128);
_layerBillBoard->addChild(billboard);//3,加入新的billboard对象
_billboards.push_back(billboard);
}
}
//创建新的BillBoard
void BillBoardDemo::addNewAniBillBoardWithCoords(cocos2d::Vec3 p)
{
for(unsigned i = 0; i < 10; i++)
{
auto billboardAni = BillBoard::create("grossini.png");
billboardAni->setScale(0.5);
billboardAni->setPosition3D(Vec3(p.x,-150.0f+30*i));
_layerBillBoard->addChild(billboardAni);//4,加入新的billboard对象
//使用帧动画
auto animation = Animation::create();
for(int i = 1; i < 15; i++)
{
char szName1[100] = {0};
sprintf(szName1,"grossini_dance_%02d.png",i);
animation->addSpriteFrameWithFile(szName1);
}
animation->setDelayPerUnit(2.8f/14.0f);//设置一帧的时间
animation->setRestoreOriginalFrame(true);//重复播放
auto action = Animate::create(animation);
billboardAni->runAction(RepeatForever::create(action));
billboardAni->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);//设置颜色混合方式
billboardAni->setOpacity(CCRANDOM_0_1()*128+128);
_billboards.push_back(billboardAni);
}
}
void BillBoardDemo::update(float dt)
{
}
//触摸事件,改变摄像机的坐标
void BillBoardDemo::onTouchesMoved(const std::vector<Touch *> &touches,cocos2d::Event *event)
{
if(touches.size() == 1)
{
auto touch = touches[0];
auto location = touch->getLocation();
auto PrevIoUsLocation = touch->getPrevIoUsLocation();
Vec2 newPos = PrevIoUsLocation - location;
Vec3 cameraDir;
Vec3 cameraRightDir;
_camera->getNodeToWorldTransform().getForwardVector(&cameraDir);
cameraDir.normalize();
cameraDir.y = 0;
_camera->getNodeToWorldTransform().getRightVector(&cameraRightDir);
cameraRightDir.normalize();
cameraRightDir.y = 0;
Vec3 cameraPos = _camera->getPosition3D();
cameraPos+= cameraDir*newPos.y*0.5;
cameraPos+= cameraRightDir*newPos.x*0.5;
_camera->setPosition3D(cameraPos);
}
}
//翻转摄像机
void BillBoardDemo::rotateCameraCallback(cocos2d::Ref *sender,float value)
{
Vec3 rotation3D = _camera->getRotation3D();
rotation3D.y += value;
_camera->setRotation3D(rotation3D);
}
3、使用@H_502_1@
HelloWorldScene中的createScene中创建BillBoardDemo层,加入scene。
#include "cocos2d.h" #include "ui/CocosGUI.h" #include "VisibleRect.h" USING_NS_CC; using namespace ui; class BillBoardDemo : public cocos2d::Layer { public: CREATE_FUNC(BillBoardDemo); virtual bool init(); virtual void update(float dt) override; void addNewBillBoardWithCoords(Vec3 p); void addNewAniBillBoardWithCoords(Vec3 p); void rotateCameraCallback(Ref* sender,float value); void onTouchesMoved(const std::vector<Touch*>& touches,Event* event); void menuCallback_orientedPoint(Ref* sender); void menuCallback_orientedPlane(Ref* sender); BillBoardDemo(); virtual ~BillBoardDemo(); protected: Camera* _camera; Layer* _layerBillBoard; std::vector<BillBoard*> _billboards; };
2、.cpp文件@H_502_1@
#include "BillBoardTest.h"
BillBoardDemo::BillBoardDemo()
:_camera(nullptr)
{
}
bool BillBoardDemo::init()
{
bool bRet = false;
do{
CC_BREAK_IF(!Layer::init());
//注册事件监听
auto listener = EventListenerTouchAllAtOnce::create();
listener->onTouchesMoved = CC_CALLBACK_2(BillBoardDemo::onTouchesMoved,this);//事件回调
Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(listener,this);
//添加层
auto layer3D = Layer::create();
addChild(layer3D,0);
_layerBillBoard = layer3D;
auto winSize = Director::getInstance()->getWinSize();
//创建摄像机
if(_camera == nullptr)
{
//参数1:透视相机的视野。参数2:相机的长宽比。参数3:近点平面距离。参数4:远点平面距离
_camera = Camera::createPerspective(60,(GLfloat)winSize.width / winSize.height,1,500);
_camera->setCameraFlag(CameraFlag::USER1);//设置相机Flag,便于相机识别节点
_layerBillBoard->addChild(_camera);//相机加入层
}
std::string imgs[3] = {"Icon.png","r2.png"};
for(unsigned int i = 0; i < 4; i++)
{
Layer* layer = Layer::create();
//随机创建BillBoard对象
auto billboard = BillBoard::create(imgs[(unsigned int)(CCRANDOM_0_1()*1+0.5)]);
billboard->setScale(0.5);//设置缩放
//CCRANDOM_MINUS1_1返回一个-1到1的float值
billboard->setPosition3D(Vec3(0.0f,0.0f,CCRANDOM_MINUS1_1()*150.0f));//设置3D坐标
//ALPHA_NON_PREMULTIPLIED混合方式 {GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA}
//源因子使用源颜色的透明度,目标因子使用减去源颜色的透明度
billboard->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);//设置颜色混合
billboard->setOpacity(CCRANDOM_0_1()*128+128);//设置可见性
_billboards.push_back(billboard);
layer->addChild(billboard);
//1,层对象加入层
_layerBillBoard->addChild(layer);//加入层
layer->runAction(RepeatForever::create(RotateBy::create(CCRANDOM_0_1(),Vec3(0.0f,45.0f,0.0f))));//层执行翻转动作
}
{
auto billboard = BillBoard::create("Icon.png");
billboard->setScale(0.2f);
billboard->setPosition3D(Vec3(0.0f,30.0f,0.0f));
auto billboard2 = BillBoard::create("r2.png");
billboard2->setPosition3D(Vec3(0.0f,100.0f));
billboard->addChild(billboard2);
_billboards.push_back(billboard);
_billboards.push_back(billboard2);
auto sprite3D = Sprite3D::create("orc.c3t");
sprite3D->setScale(2.0f);
sprite3D->addChild(billboard);
sprite3D->runAction(RepeatForever::create(RotateBy::create(10.0f,360.0f,0.0f))));
//2,Sprite3D对象加入层
_layerBillBoard->addChild(sprite3D);
}
//添加新的billboard
addNewBillBoardWithCoords(Vec3(20,5,0));
addNewBillBoardWithCoords(Vec3(60,0));
addNewBillBoardWithCoords(Vec3(100,0));
addNewBillBoardWithCoords(Vec3(140,0));
addNewBillBoardWithCoords(Vec3(180,0));
addNewAniBillBoardWithCoords(Vec3(-20,0));
addNewAniBillBoardWithCoords(Vec3(-60,0));
addNewAniBillBoardWithCoords(Vec3(-100,0));
addNewAniBillBoardWithCoords(Vec3(-140,0));
addNewAniBillBoardWithCoords(Vec3(-180,0));
_camera->setPosition3D(Vec3(0,100,230));//设置相机的3D位置
_camera->lookAt(Vec3(0,0),Vec3(0,0));//设置相机的,参数1:目标的中心位置,参数2:向上的向量
//添加菜单
TTFConfig ttfConfig("fonts/arial.ttf",30);
auto label1 = Label::createWithTTF(ttfConfig,"rotate+");
auto menuItem1 = MenuItemLabel::create(label1,CC_CALLBACK_1(BillBoardDemo::rotateCameraCallback,this,10));
auto label2 = Label::createWithTTF(ttfConfig,"rotate-");
auto menuItem2 = MenuItemLabel::create(label2,-10));
auto menu = Menu::create(menuItem1,menuItem2,nullptr);
menu->setPosition(Vec2::ZERO);
menuItem1->setPosition(Vec2(winSize.width - 80,VisibleRect::top().y - 160));
menuItem2->setPosition(Vec2(winSize.width - 80,VisibleRect::top().y - 190));
addChild(menu,0);
_layerBillBoard->setCameraMask(2);//设置mask使得对相机可见
//设置billboard观察模式
label1 = Label::createWithTTF(ttfConfig,"Point Oriented");
menuItem1 = MenuItemLabel::create(label1,CC_CALLBACK_1(BillBoardDemo::menuCallback_orientedPoint,this));
label2 = Label::createWithTTF(ttfConfig,"Plane Oriented");
menuItem2 = MenuItemLabel::create(label2,CC_CALLBACK_1(BillBoardDemo::menuCallback_orientedPlane,this));
menuItem1->setPosition(Vec2(winSize.width -80,VisibleRect::top().y - 100));
menuItem2->setPosition(Vec2(winSize.width -80,VisibleRect::top().y - 130));
menu = Menu::create(menuItem1,nullptr);
menu->setPosition(Vec2::ZERO);
this->addChild(menu,10);
menuCallback_orientedPoint(nullptr);
bRet = true;
}while(0);
return bRet;
}
void BillBoardDemo::menuCallback_orientedPoint(cocos2d::Ref *sender)
{
for(auto& billboard : _billboards)
{
billboard->setMode(BillBoard::Mode::VIEW_POINT_ORIENTED);
}
}
void BillBoardDemo::menuCallback_orientedPlane(cocos2d::Ref *sender)
{
for(auto& billboard : _billboards)
{
billboard->setMode(BillBoard::Mode::VIEW_PLANE_ORIENTED);
}
}
BillBoardDemo::~BillBoardDemo()
{
if(_camera)
{
_camera = nullptr;
}
}
//创建新的BillBoard
void BillBoardDemo::addNewBillBoardWithCoords(Vec3 p)
{
std::string imgs[3] = {"Icon.png","r2.png"};
for(unsigned int i = 0; i < 10; i++)
{
//随机图片
auto billboard = BillBoard::create(imgs[(unsigned int)(CCRANDOM_0_1()*1+0.5)]);
billboard->setScale(0.5f);
billboard->setPosition3D(Vec3(p.x,p.y,-150.0f+30*i));//Z轴值越来越大
billboard->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);//设置颜色混合方式
billboard->setOpacity(CCRANDOM_0_1()*128+128);
_layerBillBoard->addChild(billboard);//3,加入新的billboard对象
_billboards.push_back(billboard);
}
}
//创建新的BillBoard
void BillBoardDemo::addNewAniBillBoardWithCoords(cocos2d::Vec3 p)
{
for(unsigned i = 0; i < 10; i++)
{
auto billboardAni = BillBoard::create("grossini.png");
billboardAni->setScale(0.5);
billboardAni->setPosition3D(Vec3(p.x,-150.0f+30*i));
_layerBillBoard->addChild(billboardAni);//4,加入新的billboard对象
//使用帧动画
auto animation = Animation::create();
for(int i = 1; i < 15; i++)
{
char szName1[100] = {0};
sprintf(szName1,"grossini_dance_%02d.png",i);
animation->addSpriteFrameWithFile(szName1);
}
animation->setDelayPerUnit(2.8f/14.0f);//设置一帧的时间
animation->setRestoreOriginalFrame(true);//重复播放
auto action = Animate::create(animation);
billboardAni->runAction(RepeatForever::create(action));
billboardAni->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);//设置颜色混合方式
billboardAni->setOpacity(CCRANDOM_0_1()*128+128);
_billboards.push_back(billboardAni);
}
}
void BillBoardDemo::update(float dt)
{
}
//触摸事件,改变摄像机的坐标
void BillBoardDemo::onTouchesMoved(const std::vector<Touch *> &touches,cocos2d::Event *event)
{
if(touches.size() == 1)
{
auto touch = touches[0];
auto location = touch->getLocation();
auto PrevIoUsLocation = touch->getPrevIoUsLocation();
Vec2 newPos = PrevIoUsLocation - location;
Vec3 cameraDir;
Vec3 cameraRightDir;
_camera->getNodeToWorldTransform().getForwardVector(&cameraDir);
cameraDir.normalize();
cameraDir.y = 0;
_camera->getNodeToWorldTransform().getRightVector(&cameraRightDir);
cameraRightDir.normalize();
cameraRightDir.y = 0;
Vec3 cameraPos = _camera->getPosition3D();
cameraPos+= cameraDir*newPos.y*0.5;
cameraPos+= cameraRightDir*newPos.x*0.5;
_camera->setPosition3D(cameraPos);
}
}
//翻转摄像机
void BillBoardDemo::rotateCameraCallback(cocos2d::Ref *sender,float value)
{
Vec3 rotation3D = _camera->getRotation3D();
rotation3D.y += value;
_camera->setRotation3D(rotation3D);
}
3、使用@H_502_1@
#include "BillBoardTest.h" BillBoardDemo::BillBoardDemo() :_camera(nullptr) { } bool BillBoardDemo::init() { bool bRet = false; do{ CC_BREAK_IF(!Layer::init()); //注册事件监听 auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesMoved = CC_CALLBACK_2(BillBoardDemo::onTouchesMoved,this);//事件回调 Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraPHPriority(listener,this); //添加层 auto layer3D = Layer::create(); addChild(layer3D,0); _layerBillBoard = layer3D; auto winSize = Director::getInstance()->getWinSize(); //创建摄像机 if(_camera == nullptr) { //参数1:透视相机的视野。参数2:相机的长宽比。参数3:近点平面距离。参数4:远点平面距离 _camera = Camera::createPerspective(60,(GLfloat)winSize.width / winSize.height,1,500); _camera->setCameraFlag(CameraFlag::USER1);//设置相机Flag,便于相机识别节点 _layerBillBoard->addChild(_camera);//相机加入层 } std::string imgs[3] = {"Icon.png","r2.png"}; for(unsigned int i = 0; i < 4; i++) { Layer* layer = Layer::create(); //随机创建BillBoard对象 auto billboard = BillBoard::create(imgs[(unsigned int)(CCRANDOM_0_1()*1+0.5)]); billboard->setScale(0.5);//设置缩放 //CCRANDOM_MINUS1_1返回一个-1到1的float值 billboard->setPosition3D(Vec3(0.0f,0.0f,CCRANDOM_MINUS1_1()*150.0f));//设置3D坐标 //ALPHA_NON_PREMULTIPLIED混合方式 {GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA} //源因子使用源颜色的透明度,目标因子使用减去源颜色的透明度 billboard->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);//设置颜色混合 billboard->setOpacity(CCRANDOM_0_1()*128+128);//设置可见性 _billboards.push_back(billboard); layer->addChild(billboard); //1,层对象加入层 _layerBillBoard->addChild(layer);//加入层 layer->runAction(RepeatForever::create(RotateBy::create(CCRANDOM_0_1(),Vec3(0.0f,45.0f,0.0f))));//层执行翻转动作 } { auto billboard = BillBoard::create("Icon.png"); billboard->setScale(0.2f); billboard->setPosition3D(Vec3(0.0f,30.0f,0.0f)); auto billboard2 = BillBoard::create("r2.png"); billboard2->setPosition3D(Vec3(0.0f,100.0f)); billboard->addChild(billboard2); _billboards.push_back(billboard); _billboards.push_back(billboard2); auto sprite3D = Sprite3D::create("orc.c3t"); sprite3D->setScale(2.0f); sprite3D->addChild(billboard); sprite3D->runAction(RepeatForever::create(RotateBy::create(10.0f,360.0f,0.0f)))); //2,Sprite3D对象加入层 _layerBillBoard->addChild(sprite3D); } //添加新的billboard addNewBillBoardWithCoords(Vec3(20,5,0)); addNewBillBoardWithCoords(Vec3(60,0)); addNewBillBoardWithCoords(Vec3(100,0)); addNewBillBoardWithCoords(Vec3(140,0)); addNewBillBoardWithCoords(Vec3(180,0)); addNewAniBillBoardWithCoords(Vec3(-20,0)); addNewAniBillBoardWithCoords(Vec3(-60,0)); addNewAniBillBoardWithCoords(Vec3(-100,0)); addNewAniBillBoardWithCoords(Vec3(-140,0)); addNewAniBillBoardWithCoords(Vec3(-180,0)); _camera->setPosition3D(Vec3(0,100,230));//设置相机的3D位置 _camera->lookAt(Vec3(0,0),Vec3(0,0));//设置相机的,参数1:目标的中心位置,参数2:向上的向量 //添加菜单 TTFConfig ttfConfig("fonts/arial.ttf",30); auto label1 = Label::createWithTTF(ttfConfig,"rotate+"); auto menuItem1 = MenuItemLabel::create(label1,CC_CALLBACK_1(BillBoardDemo::rotateCameraCallback,this,10)); auto label2 = Label::createWithTTF(ttfConfig,"rotate-"); auto menuItem2 = MenuItemLabel::create(label2,-10)); auto menu = Menu::create(menuItem1,menuItem2,nullptr); menu->setPosition(Vec2::ZERO); menuItem1->setPosition(Vec2(winSize.width - 80,VisibleRect::top().y - 160)); menuItem2->setPosition(Vec2(winSize.width - 80,VisibleRect::top().y - 190)); addChild(menu,0); _layerBillBoard->setCameraMask(2);//设置mask使得对相机可见 //设置billboard观察模式 label1 = Label::createWithTTF(ttfConfig,"Point Oriented"); menuItem1 = MenuItemLabel::create(label1,CC_CALLBACK_1(BillBoardDemo::menuCallback_orientedPoint,this)); label2 = Label::createWithTTF(ttfConfig,"Plane Oriented"); menuItem2 = MenuItemLabel::create(label2,CC_CALLBACK_1(BillBoardDemo::menuCallback_orientedPlane,this)); menuItem1->setPosition(Vec2(winSize.width -80,VisibleRect::top().y - 100)); menuItem2->setPosition(Vec2(winSize.width -80,VisibleRect::top().y - 130)); menu = Menu::create(menuItem1,nullptr); menu->setPosition(Vec2::ZERO); this->addChild(menu,10); menuCallback_orientedPoint(nullptr); bRet = true; }while(0); return bRet; } void BillBoardDemo::menuCallback_orientedPoint(cocos2d::Ref *sender) { for(auto& billboard : _billboards) { billboard->setMode(BillBoard::Mode::VIEW_POINT_ORIENTED); } } void BillBoardDemo::menuCallback_orientedPlane(cocos2d::Ref *sender) { for(auto& billboard : _billboards) { billboard->setMode(BillBoard::Mode::VIEW_PLANE_ORIENTED); } } BillBoardDemo::~BillBoardDemo() { if(_camera) { _camera = nullptr; } } //创建新的BillBoard void BillBoardDemo::addNewBillBoardWithCoords(Vec3 p) { std::string imgs[3] = {"Icon.png","r2.png"}; for(unsigned int i = 0; i < 10; i++) { //随机图片 auto billboard = BillBoard::create(imgs[(unsigned int)(CCRANDOM_0_1()*1+0.5)]); billboard->setScale(0.5f); billboard->setPosition3D(Vec3(p.x,p.y,-150.0f+30*i));//Z轴值越来越大 billboard->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);//设置颜色混合方式 billboard->setOpacity(CCRANDOM_0_1()*128+128); _layerBillBoard->addChild(billboard);//3,加入新的billboard对象 _billboards.push_back(billboard); } } //创建新的BillBoard void BillBoardDemo::addNewAniBillBoardWithCoords(cocos2d::Vec3 p) { for(unsigned i = 0; i < 10; i++) { auto billboardAni = BillBoard::create("grossini.png"); billboardAni->setScale(0.5); billboardAni->setPosition3D(Vec3(p.x,-150.0f+30*i)); _layerBillBoard->addChild(billboardAni);//4,加入新的billboard对象 //使用帧动画 auto animation = Animation::create(); for(int i = 1; i < 15; i++) { char szName1[100] = {0}; sprintf(szName1,"grossini_dance_%02d.png",i); animation->addSpriteFrameWithFile(szName1); } animation->setDelayPerUnit(2.8f/14.0f);//设置一帧的时间 animation->setRestoreOriginalFrame(true);//重复播放 auto action = Animate::create(animation); billboardAni->runAction(RepeatForever::create(action)); billboardAni->setBlendFunc(cocos2d::BlendFunc::ALPHA_NON_PREMULTIPLIED);//设置颜色混合方式 billboardAni->setOpacity(CCRANDOM_0_1()*128+128); _billboards.push_back(billboardAni); } } void BillBoardDemo::update(float dt) { } //触摸事件,改变摄像机的坐标 void BillBoardDemo::onTouchesMoved(const std::vector<Touch *> &touches,cocos2d::Event *event) { if(touches.size() == 1) { auto touch = touches[0]; auto location = touch->getLocation(); auto PrevIoUsLocation = touch->getPrevIoUsLocation(); Vec2 newPos = PrevIoUsLocation - location; Vec3 cameraDir; Vec3 cameraRightDir; _camera->getNodeToWorldTransform().getForwardVector(&cameraDir); cameraDir.normalize(); cameraDir.y = 0; _camera->getNodeToWorldTransform().getRightVector(&cameraRightDir); cameraRightDir.normalize(); cameraRightDir.y = 0; Vec3 cameraPos = _camera->getPosition3D(); cameraPos+= cameraDir*newPos.y*0.5; cameraPos+= cameraRightDir*newPos.x*0.5; _camera->setPosition3D(cameraPos); } } //翻转摄像机 void BillBoardDemo::rotateCameraCallback(cocos2d::Ref *sender,float value) { Vec3 rotation3D = _camera->getRotation3D(); rotation3D.y += value; _camera->setRotation3D(rotation3D); }
3、使用@H_502_1@
HelloWorldScene中的createScene中创建BillBoardDemo层,加入scene。