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::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; } } } }