cocos动作使用示例(3)

本文介绍如何创建一个自定义跟随动作,使一个精灵跟随另一个精灵的移动,详细讲解了自定义动作`MyFollow`的实现,包括延时动作、normalize函数的应用,并提供了测试代码和总结。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动作应用3

让一个精灵跟随另一个精灵的移动,自定义动作的应用

自定义跟随动作:延时动作

class MyFollow : public ActionInterval

{

public:

    static MyFollow* create(float dt, Sprite*sprite,float r) //因为是跟随另一个精灵,必须有目标精灵的参数,参数3是跟随时和目标最近距离

    {

        MyFollow* ret =new MyFollow;

        ret->init(dt, sprite, r);

        ret->autorelease();

        return ret;

    }

    ~MyFollow()

    {

        if (_dest)

            _dest->release();//把retain的目标精灵release掉

    }

 

    Sprite* _dest = nullptr; //存放目标精灵

    float _r;

    bool init(floatdt, Sprite*sprite, float r)

    {

        ActionInterval::initWithDuration(dt);

        _dest = sprite;

        _r = r;

        _dest->retain(); // 这个动作引用了sprite

        return true;

    }

    void startWithTarget(Node *target) //因为初始化设置都在init中做完了,所以这里这个函数并没有用

    {

        ActionInterval::startWithTarget(target);

    }

/*runAction */

    void update(float )

    {

        // 判断目标的引用计数器是不是只有1,如果是

        // 则表明没有其他人再对它引用,也就是说_dest对象被删掉了

        if(_dest->getReferenceCount() == 1)

        {

            _target->removeFromParent();//如果目标精灵被删,删掉跟随精灵

            return;

        }

       

        /*  如果target位置不在以_dest为中心的,半径为_r圆圈内的话,那么target要移动到这个范围内

        */

        // 取得_dest精灵的中心点位置

        Rect rc =_dest->getBoundingBox();

        Vec2 center = Vec2(rc.getMidX(),rc.getMidY());

 

        // 跟随精灵的坐标

        Vec2 pos =_target->getPosition();

 

        float dist =pos.getDistance(center); //计算距离

        if (dist > _r)

        {

//具体的移动:

方法1:计算角度移动

            float angle = (pos -center).getAngle();

            float x = sinf(angle);

            float y = cosf(angle);

            _target->setPosition(_target->getPosition()+ Vec2(x, y));

 

方法2:运用了normalize函数,这个函数将会根据当前Vec2求出其sin和cos值并覆盖到当前这个Vec2中

            Vec2 d = center - pos;

            d.normalize();

            _target->setPosition(_target->getPosition()+ d*2); //2个像素单位的移动

        }

    }

};

应用这个自定义动作:

bool init()

    {   Layer::init();

        /* 被跟随对象 */

        Sprite* sp1 = Sprite::create("Images/blocks.png");addChild(sp1);

        sp1->setTag(100);

 

        /* 跟随对象 */

        Sprite* sp2 = Sprite::create("Images/close.png");

        addChild(sp2);

 

        /* 执行跟随action,时间设置长一点以便拖动 */

        sp2->runAction(MyFollow::create(1000, sp1, 64));

 

        /*测试代码 */

        sp1->runAction(MoveBy::create(2.0f,Vec2(200, 200)));

 

/* 添加触摸拖动 */

        auto ev = EventListenerTouchOneByOne::create();

        ev->onTouchBegan = [](Touch*,Event*){returntrue; };

        ev->onTouchMoved = [&](Touch*touch, Event*)

        {

            Node* sp1 =this->getChildByTag(100);

            if (sp1 == NULL)

                return;

            sp1->setPosition(sp1->getPosition()+ touch->getDelta());

    //sp1->removeFromParent();

        };

        this->_eventDispatcher->addEventListenerWithSceneGraphPriority(ev,this);

        return true;

    }

 

总结:

1.      normalize函数的学习

2.      自定义延时动作

3.      startWithAction和init的工作内容感觉有些重复

4.      关联其他精灵的动作要考虑目标精灵的存活与否。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值