1、.h头文件
#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文件
#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、使用
HelloWorldScene中的createScene中创建BillBoardDemo层,加入scene。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。