您的位置:澳门新葡萄京最大平台 > 动作小游戏 > Cocos2dx源码赏析

Cocos2dx源码赏析

发布时间:2019-10-21 00:27编辑:动作小游戏浏览(102)

    Cocos2dx源码赏析(4)之Action动作

    本篇,仍然为通过阅读源码的主意来总结赏析下Cocos2dx中Action动画的实践进度。当然,这里也只是通过这种艺术来计算下对Cocos2dx引擎的知情,还远未有达到触类旁通改换现存引擎或开垦自身的嬉戏引擎的程度。但“千里之行,始于足下”,那点滴的积淀都是更上一层楼的台阶。

    传送门:
    Cocos2dx源码赏析(1)之运维流程与主循环
    Cocos2dx源码赏析(2)之渲染
    Cocos2dx源码赏析(3)之事件分发

    1、Action说明

    Action是职能于Node节点的兼具动作的基类。通过上边这一个类承袭档次关系图,来打探下Action的具体效用:
    图片 1
    (以上图片来源Cocos官方网址)

    上边简述下Action子类的机能:
    FiniteTimeAction:
    有限时期动作类。包蕴即时动作和不仅动作。

    Follow:
    随行节点的动作。能够使layer层跟随三个节点的运动,而该节点相对地点不改变,layer层作为背景以相反方向移动。

    Speed:
    用来线性的转移二个action动作的运维速度。它包裹一个ActionInterval对象,当speed大于1时,动作一再的日子更长;当speed小于1时,动作不断的光阴越来越短。

    ActionInstant:
    随时动作。承继自FiniteTimeAction,看名称就会想到其意义,传承自该类的动作是在大器晚成帧内实践实现的动作。

    ActionInterval:
    穿梭动作。承接自FiniteTimeAction,承接自该类的动作试行进度会有最早时间和实现事件可能说有一定的持续时间(duration)。当然,它们也足以寻常运作、逆向运作,也能够变速运维。

    CallFunc:
    用来施行回调的动作。即进行该动作时,会调用作参数字传送递过去的函数。具体的兑现存分CallFunc和CallFuncN,CallFunc是实行不带参数的函数,CallFuncN是实践八个带Node参数的函数。

    FlipX和FlipY:
    将相机行事沿X轴和Y轴翻转。与安装Smart的FlipX和FlipY属性同样,包装成动作是为了方便与其他动作实行整合。

    Hide和Show:
    隐敝和展现节点。功能与安装节点的visible属性功能同样。

    Place:
    将节点放置到有些钦赐地点,与安装节点的position属性同样。

    RemoveSelf:
    移除节点。与调用节点的removeFromParentAndCleanup方法效果同样。

    ReuseGrid:
    重新网格动作。和GridAction关联应用。

    StopGrid:
    悬停网格动作。和GridAction关联应用。

    ToggleVisibility:
    切换节点的可视属性。

    CCBSetSpriteFrame:
    用坐标创设三个职分动作,用于安装Sprite的职位。

    CCBSoundEffect:
    可用来播音音响效果。

    AccelAmplitude和AccelDeccelAmplitude:
    振幅动作。

    ActionCamera:
    录制机动作。ActionCamera,不可能直接调用,因为ActionCamera未有重写update方法,只可以使用它的子类OrbitCamera。

    ActionEase:
    用以贯彻动作的速度由快到慢、速度随事件改动的匀速运动。该动作又带有5类活动:
    (1)指数缓冲:EaseExponentialIn、EaseExponentialOut、EaseExponentialInOut
    (2)Sine缓冲:EaseSineIn、EaseSineOut、EaseSineInOut
    (3)弹性缓冲:EaseElasticIn、EaseElasticOut、EaseElasticInOut
    (4)跳跃缓冲:EaseBounceIn、EaseBounceOut、EaseBounceInOut
    (5)回震缓冲:EaseBackIn、EaseBackOut、EaseBackInOut
    其间,每类动作中都有In、Out和InOut二种运动方式:
    In表示起先的时候加速
    Out代表截至的时候加快
    InOut表示开端和告竣的时候加快

    ActionTween:
    补间动作。功用的指标必得承袭ActionTweenDelegate并贯彻updateTweenAction方法。比方:渐变、缩放、位移、旋转等转移的。

    Animate:
    队列帧动画动作。

    BezierBy和BezierTo:
    贝塞尔曲线动作。在那之中By是活动的间隔,To是移动到内定地点。

    Blink:
    闪光动作。

    CardinalSplineBy和CardinalSplineTo:
    曲线路线动作。参照他事他说加以考察Cardinal spline wikipedia

    DeccelAmplitude:
    振幅动作。

    DelayTime:
    延时动作。只能在复合动作内采取

    FadeIn, FadeOut和FateTo:
    淡入淡出效果和透亮变化效果。即渐变动作。FadeIn的反转动作(reverse)是FadeOut,FadeOut的反转动作(reverse)是FadeIn,FateTo不协助反转动作(reverse)。

    GridAction:
    网格(grid)动作的基类。

    JumpBy和JumpTo:
    使节点以一定的轨迹跳跃到钦点地点。个中By是活动的间距,To是移动到内定地点。

    MoveBy和MoveTo:
    运动动作。使节点做直线运动,设置了动作时间和终端地方,在确按期间内会活动到终点。

    ProgressFromTo:
    从三个比重到另贰个比例的动作。

    ProgressTo:
    百分比速度。

    Repeat和RepeatForever:
    再也奉行动作。RepeatForever是不停的双重。

    ReverseTime:
    反转动作。

    RotateBy和RotateTo:
    旋转动作。保障周长相等。

    ScaleBy和ScaleTo:
    缩放动作。

    Sequence:
    逐后生可畏实践少年老成体系动作。

    SkewBy和SkewTo:
    偏斜动作。保障面积也等于。

    Spawn:
    再者实行多个卡通。

    TargetedAction:
    给动作钦定多个运转的靶子上。

    TintBy和TintTo:
    水彩渐变动作。

    CCBRotateXTo、CCBRotateYTo、CCBRotateTo:
    旋转动作。

    2、Action调用进程

    在Cocos2dx中享有的Action动作的治本都以由ActionManager类来保管的。那么,ActionManager的开端化实在CCDirector类中:

    bool Director::init(void)
    {
        _actionManager = new (std::nothrow) ActionManager();
        _scheduler->scheduleUpdate(_actionManager, Scheduler::PRIORITY_SYSTEM, false);
    }
    

    这里,开启了个电磁照顾计时器,来不停的更新ActionManager的逻辑:

    void ActionManager::update(float dt)
    {
        for (tHashElement *elt = _targets; elt != nullptr; )
        {
            _currentTarget = elt;
            _currentTargetSalvaged = false;
    
            if (! _currentTarget->paused)
            {
                for (_currentTarget->actionIndex = 0; _currentTarget->actionIndex < _currentTarget->actions->num;
                    _currentTarget->actionIndex++)
                {
                    _currentTarget->currentAction = static_cast<Action*>(_currentTarget->actions->arr[_currentTarget->actionIndex]);
                    if (_currentTarget->currentAction == nullptr)
                    {
                        continue;
                    }
    
                    _currentTarget->currentActionSalvaged = false;
                    _currentTarget->currentAction->step(dt);
    
                    if (_currentTarget->currentActionSalvaged)
                    {
                        _currentTarget->currentAction->release();
                    } else
                    if (_currentTarget->currentAction->isDone())
                    {
                        _currentTarget->currentAction->stop();
                        Action *action = _currentTarget->currentAction;
                        _currentTarget->currentAction = nullptr;
                        removeAction(action);
                    }
    
                    _currentTarget->currentAction = nullptr;
                }
            }
    
            elt = (tHashElement*)(elt->hh.next);
    
            if (_currentTargetSalvaged && _currentTarget->actions->num == 0)
            {
                deleteHashElement(_currentTarget);
            }
    
            else if (_currentTarget->target->getReferenceCount() == 1)
            {
                deleteHashElement(_currentTarget);
            }
        }
    
        _currentTarget = nullptr;
    }
    

    这里会遍历全体的Action,满足条件的会推行Action的step方法,由于,差相当少具有的Action动作实例都以三回九转自ActionInstant和ActionInterval,所以,这里一贯看那些类的step方法的完毕。

    void ActionInstant::step(float /*dt*/)
    {
        float updateDt = 1;
    #if CC_ENABLE_SCRIPT_BINDING
        if (_scriptType == kScriptTypeJavascript)
        {
            if (ScriptEngineManager::sendActionEventToJS(this, kActionUpdate, (void *)&updateDt))
                return;
        }
    #endif
        update(updateDt);
    }
    
    void ActionInterval::step(float dt)
    {
        if (_firstTick)
        {
            _firstTick = false;
            _elapsed = 0;
        }
        else
        {
            _elapsed += dt;
        }
    
    
        float updateDt = MAX (0,MIN(1, _elapsed / _duration));
    
        if (sendUpdateEventToScript(updateDt, this)) return;
    
        this->update(updateDt);
    }
    

    可以开掘,在step方法中,会调用Action的update方法来施行实际的立异逻辑。那么些update方法会交给Action的实例完结。

    当要施行八个Action动作时,日常会调用Node的runAction方法:

    Action * Node::runAction(Action* action)
    {
        CCASSERT( action != nullptr, "Argument must be non-nil");
        _actionManager->addAction(action, this, !_running);
        return action;
    }
    

    即这里会将实际要进行的Action实例增添到ActionManager中:

    void ActionManager::addAction(Action *action, Node *target, bool paused)
    {
        CCASSERT(action != nullptr, "action can't be nullptr!");
        CCASSERT(target != nullptr, "target can't be nullptr!");
        if(action == nullptr || target == nullptr)
            return;
    
        tHashElement *element = nullptr;
        Ref *tmp = target;
        HASH_FIND_PTR(_targets, &tmp, element);
        if (! element)
        {
            element = (tHashElement*)calloc(sizeof(*element), 1);
            element->paused = paused;
            target->retain();
            element->target = target;
            HASH_ADD_PTR(_targets, target, element);
        }
    
         actionAllocWithHashElement(element);
    
         CCASSERT(! ccArrayContainsObject(element->actions, action), "action already be added!");
         ccArrayAppendObject(element->actions, action);
    
         action->startWithTarget(target);
    }
    

    如上,轻松梳理了下Cocos2dx的Action动作的执行进度。从源码的角度来打听了下这种方式的动画片是哪些完结的,真正深远到源码的各种细节还能学到不菲东西的。

    本文由澳门新葡萄京最大平台发布于动作小游戏,转载请注明出处:Cocos2dx源码赏析

    关键词:

上一篇:产品内训课4

下一篇:微信小程序放首页