虽然说cocos2dx对3d的支持较unity3d来讲只是一点点皮毛的功夫,但是从上手容易度来讲要好很多,更适合我这样的没玩过3d的菜鸟。如果只是实现2.5d的一些场景,cocos2dx只要能在性能和稳定性上做得更好一点的话,想必是可以留住需要实现3d但又习惯了cocos2dx的老玩家的。
Sprite3D::create("sprite3dTest/scene01.obj");
(2). 使用不带素材的对象,自己设置素材
auto sprite = Sprite3D::create("Sprite3DTest/boss1.obj");
sprite->setScale(3.f);
sprite->setTexture("Sprite3DTest/boss.png");
(3)
auto sprite = EffectSprite3D::createFromObjfileAndTexture("Sprite3DTest/boss1.obj","Sprite3DTest/boss.png");
2. Sprite3DHitTest 拖拽 (1) 点击 在ontouchBegan 中设置透明度 target->setopacity(100);
放手在 ontouchended中还原透明度 target->setopacity(255);
(2) 移动 ontouchmoved
target->setposition(target->getposition() + touch->getDelta());
(3) addEventListenerWithSceneGraPHPriority 更具sprite的z order决定丢用先后
将具体实现封装到了Effect3DOutline中
auto sprite = EffectSprite3D::create(filename);
6. Animate3DTest 动画的播放和切换 小乌龟的demo (1) 同一个c3b既可以创建sprite也可以创建action
std::string filename ="Sprite3DTest/tortoise.c3b";
auto sprite = Sprite3D::create(filename);
sprite->setScale(0.1f);
auto s =Director::getInstance()->getWinSize();
sprite->setposition(Vec2(s.wIDth *4.f / 5.f,s.height /2.f));
addChild(sprite);
_sprite = sprite;
auto animation = Animation3D::create(filename);
(2) animation 可以通过 时间来分拆,这个时间是在3Dmax中定义的
if (animation)
{ //2个动画的时间不同,这些在3Dmax中定义
auto animate = Animate3D::create(animation,0.f,1.933f);
_swim = RepeatForever::create(animate);
sprite->runAction(_swim);
_swim->retain();
_hurt = Animate3D::create(animation,1.933f,2.8f);
_hurt->retain();
_state = State::SWIMMING;
}
(3)乌龟游到尽头 调用 reachEndCallBack
通过reverse获得相反的action
auto inverse = (Moveto*)_moveAction->reverse();
沿y轴180度转向
auto rot = RotateBy::create(1.f,Vec3(0.f,180.f,0.f));
(4)在ontouchesEnded中实现播放乌龟的 hurt动作 ,但是这里没法实现hurt动作的结束回调,所以采用_hurt->getDuration()
来获得其结束时间,并且做一个renewCallBack来回到_swim 动作
auto delay = DelayTime::create(_hurt->getDuration() - Animate3D::getTransitionTime());
auto seq = Sequence::create(delay,CallFunc::create(CC_CALLBACK_0(Animate3DTest::renewCallBack,this)),nullptr);
疑问? Animate3D::getTransitionTime() 用来干嘛
为啥会用voID Animate3DTest::update(float dt) 来维护一个中间状态 HURT_TO_SWIMMING 和SWIMMING_TO_HURT
auto sp = Sprite3D::create("Sprite3DTest/axe.c3b");
sprite->getAttachNode("Bip001 R Hand")->addChild(sp);
点击后去掉附加节点
_sprite->removeAllAttachNode();
TTFConfig ttfConfig("Fonts/arial.ttf",20);
auto label1 = Label::createWithTTF(ttfConfig,"Hair");
应该是在3dm中定义好了mesh的名称?
_girlPants[0]= "Girl_LowerBody01";
_girlPants[1]= "Girl_LowerBody02";
_girlUpperBody[0] = "Girl_UpperBody01";
_girlUpperBody[1] = "Girl_UpperBody02";
_girlShoes[0] = "Girl_Shoes01";
_girlShoes[1] = "Girl_Shoes02";
_girlHair[0]= "Girl_Hair01";
_girlHair[1]= "Girl_Hair02";
(2) 初始化的时候隐藏备选的部分,点击切换的时候再 交换显示
auto girlPants = sprite->getMeshByname(_girlPants[1]);
if(girlPants)
{
girlPants->setVisible(false);
}
1. decltype 用来获取auto的type 并且作为声明非常适用
autoobbSize =_obb.size();
for(decltype(obbSize) i =0; i < obbSize; i++)
2. ray 来将触摸点转换到3d场景中,判断是否点击到。
Rayray;
calculaterayByLocationInVIEw(&ray,location);
那么ray的射出方向会沿着camera的正中心发射吗?
3.画3d的边框
#include "DrawNode3D.h"
DrawNode3D* _drawDeBUG;
首先要画一个sprite的外框,比如得到他得obb
_drawDeBUG->clear();
Mat4 mat = _sprite->getNodetoWorldtransform();
mat.getRightVector(&_obbt._xAxis);
_obbt._xAxis.normalize();
mat.getUpVector(&_obbt._yAxis);
_obbt._yAxis.normalize();
mat.getForwardVector(&_obbt._zAxis);
_obbt._zAxis.normalize();
_obbt._center = _sprite->getposition3D();
Vec3 corners[8] = {};
_obbt.getCorners(corners);
然后获得corners,调用drawCube()函数
_drawDeBUG->drawCube(corners,color4F(0,1,1));
4. obb可以不依赖sprite独立得存在
voID Sprite3DWithOBBPerfromanceTest::addNewOBBWithCoords(Vec2 p)
{
Vec3 extents = Vec3(10,10,10);
AABB aabb(-extents,extents);
auto obb = OBB(aabb);
obb._center = Vec3(p.x,p.y,0);
_obb.push_back(obb);
}
5. 对碰撞的判断其实只很简单的一句话
_obbt.intersects(_obb[i])
sprite->setScaleX(-5); 在素材上转换
sprite->setCullFace(GL_FRONT); 在mesh上转换
Camera3DTest.cpp
camera 可以被添加到任何地方,如果一个sprite or layer想要被camera观察到,
必须要包含其flag(效果也会作用到其child)
auto sprite = Sprite::create("myfile.png");
sprite->setCameraMask(CameraFlag::USER1);
auto camera = Camera::createPerspective(60,winSize.wIDth/winSize.height,1000);
camera->setCameraFlag(CameraFlag::USER1);
scene->addChild(camera);
(1) 缩放,在点击label的时候设置标志位_bZoomOut _bZoomIn
Vec3 lookDir = _camera->getposition3D() - _sprite3D->getposition3D();
Vec3 cameraPos = _camera->getposition3D();
if(lookDir.length() <= 300)
{
cameraPos += lookDir.getnormalized();
_camera->setposition3D(cameraPos);
}
重新设置camera的位置即可
(2) 左右旋转 实际上就是沿着y轴左右旋转
Vec3 rotation3D= _camera->getRotation3D();
rotation3D.y+= 1;
_camera->setRotation3D(rotation3D);
(3) 视角切换
_cameraType来记录当前camera类型
enum class CameraType
{
FreeCamera=0,
FirstCamera=1,
ThirdCamera=2,
};
[第一人称] 实际上就是把相机放在了 角色头上
Vec3 newFaceDir;
_sprite3D->getWorldToNodetransform().getForwardVector(&newFaceDir);
newFaceDir.normalize();
_camera->setposition3D(Vec3(0,35,0) + _sprite3D->getposition3D());
_camera->lookAt(_sprite3D->getposition3D() + newFaceDir*50,Vec3(0,0));
[第三人称]
_camera->setposition3D(Vec3(0,130,130) + _sprite3D->getposition3D());
_camera->lookAt(_sprite3D->getposition3D(),0));
(4)让camera 随着角色移动
每一帧都需要更新camera的状态
voID Camera3DTestDemo::updateCamera(float fDelta)
-> move3D(fDelta);
先计算出角色需要移动多少:
①得到朝向目标的单位向量
Vec3 newFaceDir = _targetPos - curPos;
newFaceDir.y = 0.0f;
newFaceDir.normalize();
② 获得实际移动向量
Vec3 offset = newFaceDir * 25.0f * elapsedtime;
③ camera随之移动即可
Vec3 cameraPos= _camera->getposition3D();
cameraPos.x+=offset.x;
cameraPos.z+=offset.z;
_camera->setposition3D(cameraPos);
常用总结:
1. 3d 纬度的朝向设置
sprite->setRotation3D(Vec3(0,180,0));
2. sprite->setEffect() 添加特效
3.sprite->getAttachNode("Bip001 R Hand") 获取某个骨骼
4. sprite->getMeshByname(_girlPants[1]); 获取材质
5. Vec2 getnormalized() const;
Vec3Vec3::getnormalized()const;
获取向量的标准化形式. 若为零向量,返回(0,0)也可以理解为获取一个向量的单位向量
参考Cocos2d-x 3.3 的3D开发功能介绍 http://cn.cocos2d-x.org/tutorial/show?ID=1582
总结以上是内存溢出为你收集整理的cocos2dx ver3.3 的Sprite3DTest 例子中可以学到什么全部内容,希望文章能够帮你解决cocos2dx ver3.3 的Sprite3DTest 例子中可以学到什么所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)