cocos2dx 3D战斗类游戏制作:【二】——3D运动模式小准备
上章讲了构建一个游戏的数据库基础,基于数据库,我们已经可以实现按照指定的灯光、摄像机位置、3D模型文件、3D模型位置等等构建起一个场景和其中的精灵。
作为一个游戏,让这些场景中的精灵动起来是必须的,然后你就会发现一个有趣的现象——cocos的demo里面(cpp-test),3D精灵展示用的是平面相机(2D)而不是投影相机(3D)。
继而你会发现一个蛋疼的事实——cocos 2D即便到3.3RC0目前最新版本,也没有给你封装一个3D的移动方法。还是2D的moveTo,moveBy那些,呵呵,只有XY轴的运动
想象2D使用moveTo一样,把精灵在XYZ轴都动起来怎么办??
方法有很多,先说一个更改引擎的方法,给自己的引擎加一个MoveBy3D和MoveTo3D的方法。嘿嘿。
首先,打开“盘符:cocos目录cocos2dcocos2d”下的CCActionInterval.h,添加如下代码:
//dark添加开始*********************************************************************************************************** class CC_DLL MoveBy3D : public ActionInterval { public: /** creates the action */ static MoveBy3D* create(float duration,const Vec3& deltaPosition); // // Overrides // virtual MoveBy3D* clone() const override; virtual MoveBy3D* reverse(void) const override; virtual void startWithTarget(Node *target) override; virtual void update(float time) override; CC_CONSTRUCTOR_ACCESS: MoveBy3D() {} virtual ~MoveBy3D() {} /** initializes the action */ bool initWithDuration(float duration,const Vec3& deltaPosition); protected: Vec3 _positionDelta; Vec3 _startPosition; Vec3 _previousPosition; private: CC_DISALLOW_COPY_AND_ASSIGN(MoveBy3D); }; /** Moves a Node object to the position x,y. x and y are absolute coordinates by modifying it's position attribute. Several MoveTo3D actions can be concurrently called,and the resulting movement will be the sum of individual movements. @since v2.1beta2-custom */ class CC_DLL MoveTo3D : public MoveBy3D { public: /** creates the action */ static MoveTo3D* create(float duration,const Vec3& position); // // Overrides // virtual MoveTo3D* clone() const override; virtual void startWithTarget(Node *target) override; CC_CONSTRUCTOR_ACCESS: MoveTo3D() {} virtual ~MoveTo3D() {} /** initializes the action */ bool initWithDuration(float duration,const Vec3& position); protected: Vec3 _endPosition; private: CC_DISALLOW_COPY_AND_ASSIGN(MoveTo3D); }; //dark添加到此***********************************************************************************************************
其次,打开“盘符:cocos目录cocos2dcocos2d”下的CCActionInterval.cpp,添加如下代码:
//dark添加************************************************************************************* // // MoveBy3D // MoveBy3D* MoveBy3D::create(float duration,const Vec3& deltaPosition) { MoveBy3D *ret = new (std::nothrow) MoveBy3D(); ret->initWithDuration(duration,deltaPosition); ret->autorelease(); return ret; } bool MoveBy3D::initWithDuration(float duration,const Vec3& deltaPosition) { if (ActionInterval::initWithDuration(duration)) { _positionDelta = deltaPosition; return true; } return false; } MoveBy3D* MoveBy3D::clone() const { // no copy constructor auto a = new (std::nothrow) MoveBy3D(); a->initWithDuration(_duration,_positionDelta); a->autorelease(); return a; } void MoveBy3D::startWithTarget(Node *target) { ActionInterval::startWithTarget(target); _previousPosition = _startPosition = target->getPosition3D(); } MoveBy3D* MoveBy3D::reverse() const { return MoveBy3D::create(_duration,Vec3(-_positionDelta.x,-_positionDelta.y,-_positionDelta.z)); } void MoveBy3D::update(float t) { if (_target) { #if CC_ENABLE_STACKABLE_ACTIONS Vec3 currentPos = _target->getPosition3D(); Vec3 diff = currentPos - _previousPosition; _startPosition = _startPosition + diff; Vec3 newPos = _startPosition + (_positionDelta * t); _target->setPosition3D(newPos); _previousPosition = newPos; #else _target->setPosition3D(_startPosition + _positionDelta * t); #endif // CC_ENABLE_STACKABLE_ACTIONS } } // //MoveTo3D // MoveTo3D* MoveTo3D::create(float duration,const Vec3& position) { MoveTo3D *ret = new (std::nothrow) MoveTo3D(); ret->initWithDuration(duration,position); ret->autorelease(); return ret; } bool MoveTo3D::initWithDuration(float duration,const Vec3& position) { if (ActionInterval::initWithDuration(duration)) { _endPosition = position; return true; } return false; } MoveTo3D* MoveTo3D::clone() const { // no copy constructor auto a = new (std::nothrow) MoveTo3D(); a->initWithDuration(_duration,_endPosition); a->autorelease(); return a; } void MoveTo3D::startWithTarget(Node *target) { MoveBy3D::startWithTarget(target); _positionDelta = _endPosition - target->getPosition3D(); } //dark添加到此*********************************************************************************************************** 好了,搞定。
现在你就可以在程序任意地方,直接象使用MoveTo方法一样,使用MoveTo3D方法。不过注意了,MoveTo是2D的,传入给它的参数是Vec2(x,y),而MoveTo3D,你应该给它传入Vec3(x,y,z)
当然了,把3D的运动方法加在2D目录的CCActionInterval,是有点怪怪的,最好是在cocos的3D目录下建立一个单独的3D方法类来做,不过那样涉及的事情比较多,我就懒得去介绍了,呵呵。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |