cocos2dx ver3.3 的Sprite3DTest 例子中可以学到什么

cocos2dx ver3.3 的Sprite3DTest 例子中可以学到什么,第1张

概述虽然说cocos2dx对3d的支持较unity3d来讲只是一点点皮毛的功夫,但是从上手容易度来讲要好很多,更适合我这样的没玩过3d的菜鸟。如果只是实现2.5d的一些场景,cocos2dx只要能在性能和稳定性上做得更好一点的话,想必是可以留住需要实现3d但又习惯了cocos2dx的老玩家的。 1. Sprite3DBasicTest  Sprite3D 两种基本创建方式 (1). 直接使用一个带有素

虽然说cocos2dx对3d的支持较unity3d来讲只是一点点皮毛的功夫,但是从上手容易度来讲要好很多,更适合我这样的没玩过3d的菜鸟。如果只是实现2.5d的一些场景,cocos2dx只要能在性能和稳定性上做得更好一点的话,想必是可以留住需要实现3d但又习惯了cocos2dx的老玩家的。

@H_419_4@

1. Sprite3DBasicTest Sprite3D 两种基本创建方式 (1). 直接使用一个带有素材的obj (3dmax对象) @H_419_4@ Sprite3D::create("sprite3dTest/scene01.obj"); @H_419_4@ @H_419_4@ (2). 使用不带素材的对象,自己设置素材 @H_419_4@ auto sprite = Sprite3D::create("Sprite3DTest/boss1.obj"); @H_419_4@ sprite->setScale(3.f); @H_419_4@ sprite->setTexture("Sprite3DTest/boss.png"); @H_419_4@ (3) @H_419_4@ auto sprite = EffectSprite3D::createFromObjfileAndTexture("Sprite3DTest/boss1.obj","Sprite3DTest/boss.png"); @H_419_4@ @H_419_4@ 2. Sprite3DHitTest 拖拽 (1) 点击 在ontouchBegan 中设置透明度 target->setopacity(100); @H_419_4@ 放手在 ontouchended中还原透明度 target->setopacity(255); @H_419_4@ (2) 移动 ontouchmoved @H_419_4@ target->setposition(target->getposition() + touch->getDelta()); @H_419_4@ @H_419_4@

(3) addEventListenerWithSceneGraPHPriority 更具sprite的z order决定丢用先后

@H_419_4@

3. Sprite3DEffectTest 一些shader 的运用例子

将具体实现封装到了Effect3DOutline中

@H_419_4@

4.加载3dmax导出的文件,使用fbx-conv.exe转化 std::string filename = "Sprite3DTest/orc.c3b"; @H_419_4@

auto sprite = EffectSprite3D::create(filename);

@H_419_4@

5. Sprite3DWithSkinOutlineTest shader特效在c3b的运用 @H_419_4@ 6. Animate3DTest 动画的播放和切换 小乌龟的demo (1) 同一个c3b既可以创建sprite也可以创建action @H_419_4@ std::string filename ="Sprite3DTest/tortoise.c3b"; @H_419_4@ auto sprite = Sprite3D::create(filename); @H_419_4@ sprite->setScale(0.1f); @H_419_4@ auto s =Director::getInstance()->getWinSize(); @H_419_4@ sprite->setposition(Vec2(s.wIDth *4.f / 5.f,s.height /2.f)); @H_419_4@ addChild(sprite); @H_419_4@ _sprite = sprite; @H_419_4@ auto animation = Animation3D::create(filename); @H_419_4@ @H_419_4@ (2) animation 可以通过 时间来分拆,这个时间是在3Dmax中定义的 @H_419_4@ if (animation) @H_419_4@ { //2个动画的时间不同,这些在3Dmax中定义 @H_419_4@ auto animate = Animate3D::create(animation,0.f,1.933f); @H_419_4@ _swim = RepeatForever::create(animate); @H_419_4@ sprite->runAction(_swim); @H_419_4@ _swim->retain(); @H_419_4@ _hurt = Animate3D::create(animation,1.933f,2.8f); @H_419_4@ _hurt->retain(); @H_419_4@ _state = State::SWIMMING; @H_419_4@ } @H_419_4@ @H_419_4@ (3)乌龟游到尽头 调用 reachEndCallBack @H_419_4@ 通过reverse获得相反的action @H_419_4@ auto inverse = (Moveto*)_moveAction->reverse(); @H_419_4@ 沿y轴180度转向 @H_419_4@ auto rot = RotateBy::create(1.f,Vec3(0.f,180.f,0.f)); @H_419_4@ @H_419_4@ (4)在ontouchesEnded中实现播放乌龟的 hurt动作 ,但是这里没法实现hurt动作的结束回调,所以采用_hurt->getDuration() @H_419_4@ 来获得其结束时间,并且做一个renewCallBack来回到_swim 动作 @H_419_4@ auto delay = DelayTime::create(_hurt->getDuration() - Animate3D::getTransitionTime()); @H_419_4@ auto seq = Sequence::create(delay,CallFunc::create(CC_CALLBACK_0(Animate3DTest::renewCallBack,this)),nullptr); @H_419_4@ @H_419_4@ 疑问? Animate3D::getTransitionTime() 用来干嘛 @H_419_4@

为啥会用voID Animate3DTest::update(float dt) 来维护一个中间状态 HURT_TO_SWIMMING 和SWIMMING_TO_HURT

@H_419_4@

7. AttachmentTest 装武器 获取某个骨骼,Bip001 R Hand是在3Dmax定义的 @H_419_4@ auto sp = Sprite3D::create("Sprite3DTest/axe.c3b"); @H_419_4@ sprite->getAttachNode("Bip001 R Hand")->addChild(sp); @H_419_4@ @H_419_4@ 点击后去掉附加节点 @H_419_4@

_sprite->removeAllAttachNode();

@H_419_4@

8. Sprite3DReskinTest 皮肤换装,动态更换材质(mesh) (1)字号字体 @H_419_4@ TTFConfig ttfConfig("Fonts/arial.ttf",20); @H_419_4@ auto label1 = Label::createWithTTF(ttfConfig,"Hair"); @H_419_4@ @H_419_4@ 应该是在3dm中定义好了mesh的名称? @H_419_4@ _girlPants[0]= "Girl_LowerBody01"; @H_419_4@ _girlPants[1]= "Girl_LowerBody02"; @H_419_4@ _girlUpperBody[0] = "Girl_UpperBody01"; @H_419_4@ _girlUpperBody[1] = "Girl_UpperBody02"; @H_419_4@ _girlShoes[0] = "Girl_Shoes01"; @H_419_4@ _girlShoes[1] = "Girl_Shoes02"; @H_419_4@ _girlHair[0]= "Girl_Hair01"; @H_419_4@ _girlHair[1]= "Girl_Hair02"; @H_419_4@ @H_419_4@ (2) 初始化的时候隐藏备选的部分,点击切换的时候再 交换显示 @H_419_4@ auto girlPants = sprite->getMeshByname(_girlPants[1]); @H_419_4@ if(girlPants) @H_419_4@ { @H_419_4@ girlPants->setVisible(false); @H_419_4@

}

@H_419_4@

9.Sprite3DWithOBBPerfromanceTest 包围盒与3D模型碰撞的实现

1. decltype 用来获取auto的type 并且作为声明非常适用

autoobbSize =_obb.size();

for(decltype(obbSize) i =0; i < obbSize; i++)

2. ray 来将触摸点转换到3d场景中,判断是否点击到。

Rayray;

calculaterayByLocationInVIEw(&ray,location);

@H_419_4@

那么ray的射出方向会沿着camera的正中心发射吗?

3.画3d的边框@H_419_4@ #include "DrawNode3D.h"@H_419_4@ DrawNode3D* _drawDeBUG;@H_419_4@ 首先要画一个sprite的外框,比如得到他得obb@H_419_4@@H_419_4@@H_419_4@ _drawDeBUG->clear();@H_419_4@ Mat4 mat = _sprite->getNodetoWorldtransform();@H_419_4@ mat.getRightVector(&_obbt._xAxis);@H_419_4@ _obbt._xAxis.normalize();@H_419_4@ mat.getUpVector(&_obbt._yAxis);@H_419_4@ _obbt._yAxis.normalize();@H_419_4@ mat.getForwardVector(&_obbt._zAxis);@H_419_4@ _obbt._zAxis.normalize();@H_419_4@ _obbt._center = _sprite->getposition3D();@H_419_4@ Vec3 corners[8] = {};@H_419_4@ _obbt.getCorners(corners);@H_419_4@@H_419_4@@H_419_4@ 然后获得corners,调用drawCube()函数@H_419_4@ _drawDeBUG->drawCube(corners,color4F(0,1,1));@H_419_4@@H_419_4@@H_419_4@ 4. obb可以不依赖sprite独立得存在@H_419_4@ voID Sprite3DWithOBBPerfromanceTest::addNewOBBWithCoords(Vec2 p)@H_419_4@ {@H_419_4@ Vec3 extents = Vec3(10,10,10);@H_419_4@ AABB aabb(-extents,extents);@H_419_4@ auto obb = OBB(aabb);@H_419_4@ obb._center = Vec3(p.x,p.y,0);@H_419_4@ _obb.push_back(obb);@H_419_4@ }@H_419_4@@H_419_4@@H_419_4@ 5. 对碰撞的判断其实只很简单的一句话@H_419_4@ _obbt.intersects(_obb[i])@H_419_4@

@H_419_4@

10.Sprite3DMirrorTest 3D模型的镜像

sprite->setScaleX(-5); 在素材上转换

sprite->setCullFace(GL_FRONT); 在mesh上转换

@H_419_4@

11. Camera3DTestDemo

Camera3DTest.cpp@H_419_4@@H_419_4@ camera 可以被添加到任何地方,如果一个sprite or layer想要被camera观察到,@H_419_4@ 必须要包含其flag(效果也会作用到其child)@H_419_4@ auto sprite = Sprite::create("myfile.png");@H_419_4@ sprite->setCameraMask(CameraFlag::USER1);@H_419_4@ auto camera = Camera::createPerspective(60,winSize.wIDth/winSize.height,1000);@H_419_4@ camera->setCameraFlag(CameraFlag::USER1);@H_419_4@ scene->addChild(camera);@H_419_4@@H_419_4@@H_419_4@ (1) 缩放,在点击label的时候设置标志位_bZoomOut _bZoomIn

Vec3 lookDir = _camera->getposition3D() - _sprite3D->getposition3D();@H_419_4@ Vec3 cameraPos = _camera->getposition3D();@H_419_4@ if(lookDir.length() <= 300)@H_419_4@ {@H_419_4@ cameraPos += lookDir.getnormalized();@H_419_4@ _camera->setposition3D(cameraPos);@H_419_4@ }@H_419_4@ 重新设置camera的位置即可@H_419_4@@H_419_4@@H_419_4@ (2) 左右旋转 实际上就是沿着y轴左右旋转@H_419_4@ Vec3 rotation3D= _camera->getRotation3D();@H_419_4@ rotation3D.y+= 1;@H_419_4@ _camera->setRotation3D(rotation3D);@H_419_4@@H_419_4@@H_419_4@ (3) 视角切换

_cameraType来记录当前camera类型@H_419_4@ enum class CameraType@H_419_4@ {@H_419_4@ FreeCamera=0,@H_419_4@ FirstCamera=1,@H_419_4@ ThirdCamera=2,@H_419_4@ };

[第一人称] 实际上就是把相机放在了 角色头上@H_419_4@ Vec3 newFaceDir;@H_419_4@ _sprite3D->getWorldToNodetransform().getForwardVector(&newFaceDir);@H_419_4@ newFaceDir.normalize();@H_419_4@ _camera->setposition3D(Vec3(0,35,0) + _sprite3D->getposition3D());@H_419_4@ _camera->lookAt(_sprite3D->getposition3D() + newFaceDir*50,Vec3(0,0));

@H_419_4@ [第三人称]@H_419_4@ _camera->setposition3D(Vec3(0,130,130) + _sprite3D->getposition3D());@H_419_4@ _camera->lookAt(_sprite3D->getposition3D(),0));@H_419_4@@H_419_4@ (4)让camera 随着角色移动@H_419_4@@H_419_4@ 每一帧都需要更新camera的状态@H_419_4@ voID Camera3DTestDemo::updateCamera(float fDelta)@H_419_4@ -> move3D(fDelta);@H_419_4@@H_419_4@ 先计算出角色需要移动多少:@H_419_4@@H_419_4@ ①得到朝向目标的单位向量@H_419_4@ Vec3 newFaceDir = _targetPos - curPos;@H_419_4@ newFaceDir.y = 0.0f;@H_419_4@ newFaceDir.normalize();@H_419_4@@H_419_4@ ② 获得实际移动向量@H_419_4@ Vec3 offset = newFaceDir * 25.0f * elapsedtime;@H_419_4@@H_419_4@ ③ camera随之移动即可@H_419_4@ Vec3 cameraPos= _camera->getposition3D();@H_419_4@ cameraPos.x+=offset.x;@H_419_4@ cameraPos.z+=offset.z;@H_419_4@ _camera->setposition3D(cameraPos);@H_419_4@

@H_419_4@

常用总结:@H_419_4@ 1. 3d 纬度的朝向设置 @H_419_4@ sprite->setRotation3D(Vec3(0,180,0));@H_419_4@@H_419_4@ 2. sprite->setEffect() 添加特效@H_419_4@@H_419_4@ 3.sprite->getAttachNode("Bip001 R Hand") 获取某个骨骼@H_419_4@@H_419_4@ 4. sprite->getMeshByname(_girlPants[1]); 获取材质@H_419_4@

5. Vec2 getnormalized() const;

Vec3Vec3::getnormalized()const;

获取向量的标准化形式. 若为零向量,返回(0,0) @H_419_4@ 也可以理解为获取一个向量的单位向量 @H_419_4@

@H_419_4@

参考Cocos2d-x 3.3 的3D开发功能介绍 http://cn.cocos2d-x.org/tutorial/show?ID=1582

总结

以上是内存溢出为你收集整理的cocos2dx ver3.3 的Sprite3DTest 例子中可以学到什么全部内容,希望文章能够帮你解决cocos2dx ver3.3 的Sprite3DTest 例子中可以学到什么所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1015898.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存