示例#1
0
void CritterObject::think()
{
    if (movementQueue()->size() > 0)
    {
        if (!_moving)
        {
            _moving = true;

            delete _ui;
            _orientation = hexagon()->orientationTo(movementQueue()->back());
            auto animation = _generateMovementAnimation();
            animation->setActionFrame(_running ? 2 : 4);
            animation->addEventHandler("actionFrame",    std::bind(&CritterObject::onMovementAnimationEnded, this, std::placeholders::_1));
            animation->addEventHandler("animationEnded", std::bind(&CritterObject::onMovementAnimationEnded, this, std::placeholders::_1));
            animation->play();
            _ui = animation;
        }
    }
    else
    {
        auto anim = (UI::Animation*)ui();
        if (!_moving && (!anim || !anim->playing()))
        {
            if (SDL_GetTicks() > _nextIdleAnim)
            {
                setActionAnimation("aa");
                _setupNextIdleAnim();
            }
        }
    }
    Object::think();
}
void GameCritterObject::think()
{
    if (movementQueue()->size() > 0)
    {
        if (!_moving)
        {
            _moving = true;

            delete _ui;
            _orientation = hexagon()->orientationTo(movementQueue()->back());
            auto animation = _generateMovementAnimation();
            animation->setActionFrame(_running ? 2 : 4);
            animation->addEventHandler("actionFrame",    std::bind(&GameCritterObject::onMovementAnimationEnded, this, std::placeholders::_1));
            animation->addEventHandler("animationEnded", std::bind(&GameCritterObject::onMovementAnimationEnded, this, std::placeholders::_1));
            animation->play();
            _ui = animation;
        }
    }
    GameObject::think();
}
void GameCritterObject::onMovementAnimationEnded(Event* event)
{
    auto hexagon = movementQueue()->back();
    movementQueue()->pop_back();
    Game::getInstance()->locationState()->moveObjectToHexagon(this, hexagon);
    auto animation = dynamic_cast<Animation*>(ui());

    if (movementQueue()->size() == 0)
    {
        _moving = false;
        animation->stop();
        setActionAnimation("aa");
        return;
    }

    auto newHexagon = movementQueue()->back();
    auto newOrientation = this->hexagon()->orientationTo(newHexagon);
    
    if (event->name() == "animationEnded" || (int)newOrientation != orientation())
    {
        _orientation = newOrientation;
        auto newAnimation = _generateMovementAnimation();
        if (event->name() == "actionFrame") 
        {
            newAnimation->setCurrentFrame(animation->currentFrame());
            newAnimation->setActionFrame(animation->actionFrame());
        }
        else
        {
            newAnimation->setActionFrame(_running ? 2 : 4);
        }
        newAnimation->addEventHandler("actionFrame",    std::bind(&GameCritterObject::onMovementAnimationEnded, this, std::placeholders::_1));
        newAnimation->addEventHandler("animationEnded", std::bind(&GameCritterObject::onMovementAnimationEnded, this, std::placeholders::_1));
        newAnimation->play();
        delete _ui;
        _ui = animation = newAnimation;
    }

    if (event->name() == "actionFrame")
    {
        // at each action frame critter switches to the next hex and frame positions are offset relative to the action frame offsets
        auto actionFrame = animation->frames()->at(animation->actionFrame());
        for (auto it = animation->frames()->rbegin(); it != animation->frames()->rend(); ++it)
        {
            auto frame = (*it);
            frame->setXOffset(frame->xOffset() - actionFrame->xOffset());
            frame->setYOffset(frame->yOffset() - actionFrame->yOffset());
            if (frame == actionFrame) break;
        }

        if (_running)
        {
            switch (animation->actionFrame())
            {
                // those frame numbers were guessed to make seamless running animation
                case 2:
                    animation->setActionFrame(4);
                    break;
                case 4:
                    animation->setActionFrame(6);
                    break;
                case 5:
                    animation->setActionFrame(7);
                    break;
            }
        }
    }
}