Cocos2d-x3.3RC0 Cpp-test分析之Camera3DDemo
发布时间:2020-12-14 19:28:14 所属栏目:百科 来源:网络整理
导读:1、Camera3DDemo //.h#include "cocos2d.h"#include stringUSING_NS_CC;#include stringnamespace cocos2d { class Sprite3D; class Delay;}enum State{ State_None = 0,State_Idle = 0x01,State_Move = 0x02,State_Rotate = 0x04,State_Speak = 0x08,State_
1、Camera3DDemo//.h #include "cocos2d.h" #include <string> USING_NS_CC; #include <string> namespace cocos2d { class Sprite3D; class Delay; } enum State { State_None = 0,State_Idle = 0x01,State_Move = 0x02,State_Rotate = 0x04,State_Speak = 0x08,State_MeleeAttack = 0x10,State_RemoteAttack = 0x20,State_Attack = 0x40,}; enum class CameraType { FreeCamera=0,FirstCamera=1,ThirdCamera=2,}; class Camera3DTestDemo : public Layer { public: CREATE_FUNC(Camera3DTestDemo); Camera3DTestDemo(void); virtual ~Camera3DTestDemo(void); virtual void onEnter() override; virtual void onExit() override; void addNewSpriteWithCoords(Vec3 p,std::string fileName,bool playAnimation=false,float scale=1.0f,bool bindCamera=false); void onTouchesBegan(const std::vector<Touch*>& touches,cocos2d::Event *event); void onTouchesMoved(const std::vector<Touch*>& touches,cocos2d::Event *event); void onTouchesEnded(const std::vector<Touch*>& touches,cocos2d::Event *event); void SwitchViewCallback(Ref* sender,CameraType cameraType); void updateCamera(float fDelta); void move3D(float elapsedTime); void updateState(float elapsedTime); bool isState(unsigned int state,unsigned int bit) const; bool onTouchesZoomOut(Touch* touch,Event* event); void onTouchesZoomOutEnd(Touch* touch,Event* event); bool onTouchesZoomIn(Touch* touch,Event* event); void onTouchesZoomInEnd(Touch* touch,Event* event); bool onTouchesRotateLeft(Touch* touch,Event* event); void onTouchesRotateLeftEnd(Touch* touch,Event* event); bool onTouchesRotateRight(Touch* touch,Event* event); void onTouchesRotateRightEnd(Touch* touch,Event* event); protected: std::string _title; Layer* _layer3D; Sprite3D* _sprite3D; Vec3 _targetPos; CameraType _cameraType; MenuItem* _incRot; MenuItem* _decRot; unsigned int _curState; Camera* _camera; MoveTo* _moveAction; bool _bZoomOut; bool _bZoomIn; bool _bRotateLeft; bool _bRotateRight; Label* _RotateRightlabel; Label* _RotateLeftlabel; Label* _ZoomInlabel; Label* _ZoomOutlabel; };
.cpp
#include "Camera3DDemo.h" #include <algorithm>//包含STL库的算法 #include "VisibleRect.h" class DrawLine3D: public Node { public: //静态创建函数 static DrawLine3D* create(); //画线函数,参数1:起点;参数2:终点;参数3:线段颜色 void drawLine(const Vec3 &from,const Vec3 &to,const Color4F &color); void clear() { _buffer.clear(); } //真正的绘图函数 void onDraw(const Mat4 &transform,uint32_t flags); //绘制节点 virtual void draw(Renderer *renderer,const Mat4 &transform,uint32_t flags) override; CC_CONSTRUCTOR_ACCESS: DrawLine3D() { } virtual ~DrawLine3D() { } virtual bool init(); protected: //自定义线段存放的结构体 struct V3F_C4B { Vec3 vertices;//线段端点坐标 Color4B colors; //线段颜色 }; //存放线段数据的容器 std::vector<V3F_C4B> _buffer; //启动自定义绘图 CustomCommand _customCommand; private: //CC_DISALLOW_COPY_AND_ASSIGN宏的作用是定义一个类,禁止拷贝和赋值(=)运算符重载功能。 CC_DISALLOW_COPY_AND_ASSIGN(DrawLine3D); }; DrawLine3D* DrawLine3D::create() { //nothrow创建对象失败返回0 auto ret = new (std::nothrow) DrawLine3D(); //对象创建成功 if (ret && ret->init()) return ret; //对象创建失败 CC_SAFE_DELETE(ret); return nullptr; } bool DrawLine3D::init() { //设置节点着色程序 setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_COLOR)); return true; } //画线函数 void DrawLine3D::drawLine(const Vec3 &from,const Color4F &color) { Color4B col = Color4B(color);//线段颜色 DrawLine3D::V3F_C4B vertex; vertex.vertices = from;//起点信息 vertex.colors = col; _buffer.push_back(vertex); vertex.vertices = to;//终点信息 _buffer.push_back(vertex); } //绘制节点函数 void DrawLine3D::draw(Renderer *renderer,uint32_t flags) { _customCommand.init(_globalZOrder); ////调用真正的绘图函数onDraw _customCommand.func = CC_CALLBACK_0(DrawLine3D::onDraw,this,transform,flags); //将着色器程序加入renderer对象 renderer->addCommand(&_customCommand); } //真正的调用OpenGL接口绘图,涉及OpenGL知识,暂不了解 void DrawLine3D::onDraw(const Mat4 &transform,uint32_t flags) { auto glProgram = getGLProgram();//返回当前节点的GLProgram (shader) glProgram->use();//调用glUseProgram()函数,使用shader绘图 glProgram->setUniformsForBuiltins(transform); glEnable(GL_DEPTH_TEST); glBindBuffer(GL_ARRAY_BUFFER,0); glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_POSITION); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION,3,GL_FLOAT,GL_FALSE,sizeof(V3F_C4B),&(_buffer[0].vertices)); glEnableVertexAttribArray(GLProgram::VERTEX_ATTRIB_COLOR); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR,4,GL_UNSIGNED_BYTE,GL_TRUE,&(_buffer[0].colors)); glDrawArrays(GL_LINES,static_cast<int>(_buffer.size())); glDisable(GL_DEPTH_TEST); } //////////////////////////////////////////////////////////////////////////////// enum { IDC_NEXT = 100,IDC_BACK,IDC_RESTART }; Camera3DTestDemo::Camera3DTestDemo(void) : Layer(),_camera(nullptr),_incRot(nullptr),_decRot(nullptr),_bZoomOut(false),_bZoomIn(false),_bRotateLeft(false),_bRotateRight(false) { } Camera3DTestDemo::~Camera3DTestDemo(void) { } //旋转视角回调函数 void Camera3DTestDemo::SwitchViewCallback(Ref* sender,CameraType cameraType) { //如果当前视角等于要转换的视角,则直接返回 if(_cameraType==cameraType) { return ; } _cameraType = cameraType; //如果摄像机类型等于自由视角 if(_cameraType==CameraType::FreeCamera) { _camera->setPosition3D(Vec3(0,130,130) + _sprite3D->getPosition3D()); _camera->lookAt(_sprite3D->getPosition3D(),Vec3(0,1,0)); _RotateRightlabel->setColor(Color3B::WHITE); _RotateLeftlabel->setColor(Color3B::WHITE); _ZoomInlabel->setColor(Color3B::WHITE); _ZoomOutlabel->setColor(Color3B::WHITE); } //如果摄像机类型为第一视角 else if(_cameraType==CameraType::FirstCamera) { Vec3 newFaceDir; //返回逆世界仿射变换矩阵。像素的矩阵。并获取Forward矩阵,参数为目标向量 _sprite3D->getWorldToNodeTransform().getForwardVector(&newFaceDir); //目标向量标准化,将Vec3对象的x,y,z转化为分数,且x的平方+y的平方+z的平方=1 newFaceDir.normalize(); _camera->setPosition3D(Vec3(0,35,0) + _sprite3D->getPosition3D()); //设置相机的视图矩阵,参数1:target位置,参数2:向上的向量 _camera->lookAt(_sprite3D->getPosition3D() + newFaceDir*50,0)); _RotateRightlabel->setColor(Color3B::WHITE); _RotateLeftlabel->setColor(Color3B::WHITE); _ZoomInlabel->setColor(Color3B::GRAY); _ZoomOutlabel->setColor(Color3B::GRAY); } //如果摄像机的类型为第三视角 else if(_cameraType==CameraType::ThirdCamera) { _camera->setPosition3D(Vec3(0,130) + _sprite3D->getPosition3D()); //设置相机的视图矩阵。 _camera->lookAt(_sprite3D->getPosition3D(),0)); _RotateRightlabel->setColor(Color3B::GRAY); _RotateLeftlabel->setColor(Color3B::GRAY); _ZoomInlabel->setColor(Color3B::WHITE); _ZoomOutlabel->setColor(Color3B::WHITE); } } void Camera3DTestDemo::onEnter() { Layer::onEnter(); _sprite3D=nullptr; //注册事件 auto s = Director::getInstance()->getWinSize(); auto listener = EventListenerTouchAllAtOnce::create(); listener->onTouchesBegan = CC_CALLBACK_2(Camera3DTestDemo::onTouchesBegan,this); listener->onTouchesMoved = CC_CALLBACK_2(Camera3DTestDemo::onTouchesMoved,this); listener->onTouchesEnded = CC_CALLBACK_2(Camera3DTestDemo::onTouchesEnded,this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener,this); //创建新的层,用于加载3D精灵和线段 auto layer3D=Layer::create(); addChild(layer3D,0); _layer3D=layer3D; _curState=State_None; //添加精灵参数依次为:Vec3向量,精灵文件路径,是否执行动作,缩放系数,是否绑定摄像机 addNewSpriteWithCoords( Vec3(0,0),"girl.c3b",true,0.2f,true); TTFConfig ttfConfig("fonts/arial.ttf",30); //依次添加4个Label对象到对应的Node节点上,并对4个Label对象注册监听事件 auto containerForLabel1 = Node::create(); _ZoomOutlabel = Label::createWithTTF(ttfConfig,"zoom out"); _ZoomOutlabel->setPosition(s.width-150,VisibleRect::top().y-30); containerForLabel1->addChild(_ZoomOutlabel); addChild(containerForLabel1,10); auto listener1 = EventListenerTouchOneByOne::create(); listener1->setSwallowTouches(true); listener1->onTouchBegan = CC_CALLBACK_2(Camera3DTestDemo::onTouchesZoomOut,this); listener1->onTouchEnded = CC_CALLBACK_2(Camera3DTestDemo::onTouchesZoomOutEnd,this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener1,_ZoomOutlabel); auto containerForLabel2 = Node::create(); _ZoomInlabel = Label::createWithTTF(ttfConfig,"zoom in"); _ZoomInlabel->setPosition(s.width-150,VisibleRect::top().y-100); containerForLabel2->addChild(_ZoomInlabel); addChild(containerForLabel2,10); auto listener2 = EventListenerTouchOneByOne::create(); listener2->setSwallowTouches(true); listener2->onTouchBegan = CC_CALLBACK_2(Camera3DTestDemo::onTouchesZoomIn,this); listener2->onTouchEnded = CC_CALLBACK_2(Camera3DTestDemo::onTouchesZoomInEnd,this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener2,_ZoomInlabel); auto containerForLabel3 = Node::create(); _RotateLeftlabel = Label::createWithTTF(ttfConfig,"rotate left"); _RotateLeftlabel->setPosition(s.width-150,VisibleRect::top().y-170); containerForLabel3->addChild(_RotateLeftlabel); addChild(containerForLabel3,10); auto listener3 = EventListenerTouchOneByOne::create(); listener3->setSwallowTouches(true); listener3->onTouchBegan = CC_CALLBACK_2(Camera3DTestDemo::onTouchesRotateLeft,this); listener3->onTouchEnded = CC_CALLBACK_2(Camera3DTestDemo::onTouchesRotateLeftEnd,this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener3,_RotateLeftlabel); auto containerForLabel4 = Node::create(); _RotateRightlabel = Label::createWithTTF(ttfConfig,"rotate right"); _RotateRightlabel->setPosition(s.width-150,VisibleRect::top().y-240); containerForLabel4->addChild(_RotateRightlabel); addChild(containerForLabel4,10); auto listener4 = EventListenerTouchOneByOne::create(); listener4->setSwallowTouches(true); listener4->onTouchBegan = CC_CALLBACK_2(Camera3DTestDemo::onTouchesRotateRight,this); listener4->onTouchEnded = CC_CALLBACK_2(Camera3DTestDemo::onTouchesRotateRightEnd,this); _eventDispatcher->addEventListenerWithSceneGraphPriority(listener4,_RotateRightlabel); //设置摄像机视角菜单选项,并回调转换视角函数 auto label1 = Label::createWithTTF(ttfConfig,"free "); auto menuItem1 = MenuItemLabel::create(label1,CC_CALLBACK_1(Camera3DTestDemo::SwitchViewCallback,CameraType::FreeCamera)); auto label2 = Label::createWithTTF(ttfConfig,"third person"); auto menuItem2 = MenuItemLabel::create(label2,CameraType::ThirdCamera)); auto label3 = Label::createWithTTF(ttfConfig,"first person"); auto menuItem3 = MenuItemLabel::create(label3,CameraType::FirstCamera)); auto menu = Menu::create(menuItem1,menuItem2,menuItem3,nullptr); menu->setPosition(Vec2::ZERO); menuItem1->setPosition(VisibleRect::left().x+100,VisibleRect::top().y-50); menuItem2->setPosition(VisibleRect::left().x+100,VisibleRect::top().y -100); menuItem3->setPosition(VisibleRect::left().x+100,VisibleRect::top().y -150); addChild(menu,0); //设置自定义更新器,时间间隔为0.0秒 schedule(CC_SCHEDULE_SELECTOR(Camera3DTestDemo::updateCamera),0.0f); if (_camera == nullptr) { //初始化相机 _camera=Camera::createPerspective(60,(GLfloat)s.width/s.height,1000); _camera->setCameraFlag(CameraFlag::USER1); _layer3D->addChild(_camera); } //首先执行视角切换回调函数,先切换到第三视角 SwitchViewCallback(this,CameraType::ThirdCamera); //创建3D画线类对象 DrawLine3D* line =DrawLine3D::create(); //draw x for( int j =-20; j<=20 ;j++) { //将线段信息存入vector,调用draw绘图,实质是onDraw进行绘制 line->drawLine(Vec3(-100,5*j),Vec3(100,Color4F(1,1)); } //draw z for( int j =-20; j<=20 ;j++) { //将线段信息存入vector,调用draw绘图,实质是onDraw进行绘制 line->drawLine(Vec3(5*j,-100),Vec3(5*j,100),Color4F(0,1)); } //draw y //绘制y轴方向的两条线段 line->drawLine(Vec3(0,-50,0.5,1)); line->drawLine(Vec3(0,50,1)); _layer3D->addChild(line); //设置mask,使得其对相机可见 _layer3D->setCameraMask(2); } //onExit函数,退出当前层时执行 void Camera3DTestDemo::onExit() { Layer::onExit(); if (_camera) { _camera = nullptr; } } //添加精灵,参数1:精灵坐标,参数2:精灵文件路径,参数3:是否执行动作,参数4:缩放系数,参数5:是否绑定摄像机 void Camera3DTestDemo::addNewSpriteWithCoords(Vec3 p,bool playAnimation,float scale,bool bindCamera) { //创建3D精灵 auto sprite = Sprite3D::create(fileName); _layer3D->addChild(sprite); float globalZOrder=sprite->getGlobalZOrder(); //设置精灵的坐标和全局Z轴顺序 sprite->setPosition3D( Vec3( p.x,p.y,p.z) ); sprite->setGlobalZOrder(globalZOrder); if(playAnimation) { //首先通过骨骼节点创建骨骼动画 auto animation = Animation3D::create(fileName,"Take 001"); if (animation) { //执行3D动画 auto animate = Animate3D::create(animation); sprite->runAction(RepeatForever::create(animate)); } } //如果绑定摄像机,将sprite赋值给_sprite3D对象 if(bindCamera) { _sprite3D=sprite; } sprite->setScale(scale); } //多点触摸 void Camera3DTestDemo::onTouchesBegan(const std::vector<Touch*>& touches,cocos2d::Event *event) { for ( auto &item: touches ) { auto touch = item; auto location = touch->getLocation(); } } //多点触摸移动,即点击线段区域,精灵移动过去 void Camera3DTestDemo::onTouchesMoved(const std::vector<Touch*>& touches,cocos2d::Event *event) { if(touches.size()==1) { auto touch = touches[0]; //获取第一个触摸点的OpenGL坐标系的坐标,原点在屏幕左下角。 //补充:屏幕坐标系,原点在屏幕左上角 //世界坐标系:与OpenGL坐标系一致,位于屏幕左下角 //节点坐标系:父节点的左下角,与OpenGL一致 auto location = touch->getLocation(); Point newPos = touch->getPreviousLocation()-location; if(_cameraType==CameraType::FreeCamera || _cameraType==CameraType::FirstCamera) { Vec3 cameraDir; Vec3 cameraRightDir; //返回世界仿射变换矩阵。矩阵单位是像素。并获取Forward矩阵,参数为目标向量。注意逆世界仿射变换矩阵 _camera->getNodeToWorldTransform().getForwardVector(&cameraDir); //将返回的矩阵向量规范化 cameraDir.normalize(); //将返回的矩阵向量y轴赋值为0 cameraDir.y=0; //返回正确的举证向量的世界仿射变化矩阵 _camera->getNodeToWorldTransform().getRightVector(&cameraRightDir); //向量规范化 cameraRightDir.normalize(); //向量y轴赋值0 cameraRightDir.y=0; Vec3 cameraPos= _camera->getPosition3D(); cameraPos+=cameraDir*newPos.y*0.1f; cameraPos+=cameraRightDir*newPos.x*0.1f; //重新设置摄像机的3D坐标 _camera->setPosition3D(cameraPos); //如果精灵存在,且相机的类型为第一视角,执行下面代码 if(_sprite3D && _cameraType==CameraType::FirstCamera) { //设置精灵的3D坐标,并保存当前精灵坐标值,用于更新任务运动状态 _sprite3D->setPosition3D(Vec3(_camera->getPositionX(),_camera->getPositionZ())); _targetPos=_sprite3D->getPosition3D(); } } } } //3D精灵移动 void Camera3DTestDemo::move3D(float elapsedTime) { if(_sprite3D) { //获取当前精灵的3D坐标 Vec3 curPos= _sprite3D->getPosition3D(); //计算原来坐标与新坐标的向量 Vec3 newFaceDir = _targetPos - curPos; //将y轴赋值为0,并将新向量规范化 newFaceDir.y = 0.0f; newFaceDir.normalize(); //计算偏移 Vec3 offset = newFaceDir * 25.0f * elapsedTime; curPos+=offset; //设置精灵的新坐标 _sprite3D->setPosition3D(curPos); offset.x=offset.x; offset.z=offset.z; if(_cameraType==CameraType::ThirdCamera) { //如果摄像机的类型为第三视角,同时更新摄像机的3D坐标 Vec3 cameraPos= _camera->getPosition3D(); cameraPos.x+=offset.x; cameraPos.z+=offset.z; _camera->setPosition3D(cameraPos); } } } //判断精灵的状态 void Camera3DTestDemo::updateState(float elapsedTime) { if(_sprite3D) { Vec3 curPos= _sprite3D->getPosition3D(); Vec3 curFaceDir; //返回世界仿射变换矩阵。矩阵单位是像素。并获取Forward矩阵,参数为目标向量。注意逆世界仿射变换矩阵 _sprite3D->getNodeToWorldTransform().getForwardVector(&curFaceDir); curFaceDir=-curFaceDir; curFaceDir.normalize(); Vec3 newFaceDir = _targetPos - curPos; newFaceDir.y = 0.0f; newFaceDir.normalize(); //计算两个向量的点积,通过返回的值判断精灵运动方向和是否停止 float cosAngle = std::fabs(Vec3::dot(curFaceDir,newFaceDir) - 1.0f); //返回两个向量的平方距离 float dist = curPos.distanceSquared(_targetPos); if(dist<=4.0f) { if(cosAngle<=0.01f) _curState = State_Idle; else _curState = State_Rotate; } else { if(cosAngle>0.01f) _curState = State_Rotate | State_Move; else _curState = State_Move; } } } void Camera3DTestDemo::onTouchesEnded(const std::vector<Touch*>& touches,cocos2d::Event *event) { for ( auto &item: touches ) { auto touch = item; auto location = touch->getLocationInView(); if(_camera) { if(_sprite3D && _cameraType==CameraType::ThirdCamera && _bZoomOut == false && _bZoomIn == false && _bRotateLeft == false && _bRotateRight == false) { Vec3 nearP(location.x,location.y,-1.0f),farP(location.x,1.0f); auto size = Director::getInstance()->getWinSize(); _camera->unproject(size,&nearP,&nearP); _camera->unproject(size,&farP,&farP); Vec3 dir(farP - nearP); float dist=0.0f; float ndd = Vec3::dot(Vec3(0,dir); if(ndd == 0) dist=0.0f; float ndo = Vec3::dot(Vec3(0,nearP); dist= (0 - ndo) / ndd; Vec3 p = nearP + dist * dir; if( p.x > 100) p.x = 100; if( p.x < -100) p.x = -100; if( p.z > 100) p.z = 100; if( p.z < -100) p.z = -100; _targetPos=p; } } } } void onTouchesCancelled(const std::vector<Touch*>& touches,cocos2d::Event *event) { } //更新视图 void Camera3DTestDemo::updateCamera(float fDelta) { if(_sprite3D) { if( _cameraType==CameraType::ThirdCamera) { //摄像机类型为第三视角,判断精灵的运动状态 updateState(fDelta); //如果精灵正在行走 if(isState(_curState,State_Move)) { //使精灵和相机为行走状态 move3D(fDelta); //如果行走在转身 if(isState(_curState,State_Rotate)) { Vec3 curPos = _sprite3D->getPosition3D(); Vec3 newFaceDir = _targetPos - curPos; newFaceDir.y = 0; newFaceDir.normalize(); Vec3 up; _sprite3D->getNodeToWorldTransform().getUpVector(&up); up.normalize(); Vec3 right; Vec3::cross(-newFaceDir,up,&right); right.normalize(); Vec3 pos = Vec3(0,0); Mat4 mat; mat.m[0] = right.x; mat.m[1] = right.y; mat.m[2] = right.z; mat.m[3] = 0.0f; mat.m[4] = up.x; mat.m[5] = up.y; mat.m[6] = up.z; mat.m[7] = 0.0f; mat.m[8] = newFaceDir.x; mat.m[9] = newFaceDir.y; mat.m[10] = newFaceDir.z; mat.m[11] = 0.0f; mat.m[12] = pos.x; mat.m[13] = pos.y; mat.m[14] = pos.z; mat.m[15] = 1.0f; //设置额外的节点变换矩阵 _sprite3D->setAdditionalTransform(&mat); } } } //如果执行缩小动作 if(_bZoomOut == true) { if(_camera) { //摄像机类型为第三视角 if(_cameraType == CameraType::ThirdCamera) { Vec3 lookDir = _camera->getPosition3D() - _sprite3D->getPosition3D(); Vec3 cameraPos = _camera->getPosition3D(); //求得相机与精灵的空间距离 if(lookDir.length() <= 300) { //相机位置增加,且不改变相机与精灵的相对位置 cameraPos += lookDir.getNormalized(); _camera->setPosition3D(cameraPos); } } //如果是自由视角 else if(_cameraType == CameraType::FreeCamera) { Vec3 cameraPos = _camera->getPosition3D(); if(cameraPos.length() <= 300) { //相机距离增加 cameraPos += cameraPos.getNormalized(); _camera->setPosition3D(cameraPos); } } } } //如果是放大效果 if(_bZoomIn == true) { if(_camera) { //相机是第三视角 if(_cameraType == CameraType::ThirdCamera) { Vec3 lookDir = _camera->getPosition3D() - _sprite3D->getPosition3D(); Vec3 cameraPos = _camera->getPosition3D(); if(lookDir.length() >= 50) { //相机与精灵的距离大于50,才会执行下面操作 //相机位置增加 cameraPos -= lookDir.getNormalized(); _camera->setPosition3D(cameraPos); } } //如果为自由视角 else if(_cameraType == CameraType::FreeCamera) { Vec3 cameraPos = _camera->getPosition3D(); if(cameraPos.length() >= 50) { //相机位置增加 cameraPos -= cameraPos.getNormalized(); _camera->setPosition3D(cameraPos); } } } } //如果是左转效果 if(_bRotateLeft == true) { //如果相机类型为自由视角和第一视角 if(_cameraType==CameraType::FreeCamera || _cameraType==CameraType::FirstCamera) { //y轴增加旋转 Vec3 rotation3D= _camera->getRotation3D(); rotation3D.y+= 1; _camera->setRotation3D(rotation3D); } } //如果是右转效果 if(_bRotateRight == true) { if(_cameraType==CameraType::FreeCamera || _cameraType==CameraType::FirstCamera) { //摄像机类型为自由视角和第一视角,y轴减少旋转 Vec3 rotation3D= _camera->getRotation3D(); rotation3D.y-= 1; _camera->setRotation3D(rotation3D); } } } } //判断精灵的运动状态 bool Camera3DTestDemo::isState(unsigned int state,unsigned int bit) const { return (state & bit) == bit; } //缩小触摸事件 bool Camera3DTestDemo::onTouchesZoomOut(Touch* touch,Event* event) { auto target = static_cast<Label*>(event->getCurrentTarget()); //将触摸点的位置转化为节点坐标位置 Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation()); Size s = target->getContentSize(); Rect rect = Rect(0,s.width,s.height); //如果触摸在节点内 if (rect.containsPoint(locationInNode)) { _bZoomOut = true; return true; } return false; } //缩小触摸结束 void Camera3DTestDemo::onTouchesZoomOutEnd(Touch* touch,Event* event) { _bZoomOut = false; } //放大触摸事件 bool Camera3DTestDemo::onTouchesZoomIn(Touch* touch,Event* event) { auto target = static_cast<Label*>(event->getCurrentTarget()); Vec2 locationInNode = target->convertToNodeSpace(touch->getLocation()); Size s = target->getContentSize(); Rect rect = Rect(0,s.height); //如果在节点内,设置放大判断值为true if (rect.containsPoint(locationInNode)) { _bZoomIn = true; return true; } return false; } //放大触摸结束 void Camera3DTestDemo::onTouchesZoomInEnd(Touch* touch,Event* event) { _bZoomIn = false; } //左转触摸 bool Camera3DTestDemo::onTouchesRotateLeft(Touch* touch,s.height); //设置左转触摸为true if (rect.containsPoint(locationInNode)) { _bRotateLeft = true; return true; } return false; } void Camera3DTestDemo::onTouchesRotateLeftEnd(Touch* touch,Event* event) { //左转触摸结束,恢复判断值为false _bRotateLeft = false; } //右转触摸 bool Camera3DTestDemo::onTouchesRotateRight(Touch* touch,s.height); //设置右转触摸判断值为true; if (rect.containsPoint(locationInNode)) { _bRotateRight = true; return true; } return false; } //触摸结束,恢复右转判断触摸值为false void Camera3DTestDemo::onTouchesRotateRightEnd(Touch* touch,Event* event) { _bRotateRight = false; } 2、使用
在HelloWorld的createScene中,直接创建Camera3DDemo的Layer对象,加入Scene
3、运行效果(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |