1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-03-25 21:38:59 +02:00

Fix graphical artifact in hero movement animation

This commit is contained in:
Ivan Savenko 2023-03-28 22:37:53 +03:00
parent 498c968e45
commit 2cca15c2db
3 changed files with 54 additions and 33 deletions

@ -66,16 +66,18 @@ void BasicMapView::render(Canvas & target, bool fullUpdate)
void BasicMapView::show(SDL_Surface * to) void BasicMapView::show(SDL_Surface * to)
{ {
controller->update(GH.mainFPSmng->getElapsedMilliseconds()); controller->updateBefore(GH.mainFPSmng->getElapsedMilliseconds());
Canvas target(to); Canvas target(to);
CSDL_Ext::CClipRectGuard guard(to, pos); CSDL_Ext::CClipRectGuard guard(to, pos);
render(target, false); render(target, false);
controller->updateAfter(GH.mainFPSmng->getElapsedMilliseconds());
} }
void BasicMapView::showAll(SDL_Surface * to) void BasicMapView::showAll(SDL_Surface * to)
{ {
controller->update(0); controller->updateBefore(0);
Canvas target(to); Canvas target(to);
CSDL_Ext::CClipRectGuard guard(to, pos); CSDL_Ext::CClipRectGuard guard(to, pos);

@ -88,7 +88,7 @@ std::shared_ptr<IMapRendererContext> MapViewController::getContext() const
return context; return context;
} }
void MapViewController::update(uint32_t timeDelta) void MapViewController::updateBefore(uint32_t timeDelta)
{ {
// confirmed to match H3 for // confirmed to match H3 for
// - hero embarking on boat (500 ms) // - hero embarking on boat (500 ms)
@ -116,56 +116,32 @@ void MapViewController::update(uint32_t timeDelta)
settings["adventure"]["enemyMoveTime"].Float(); settings["adventure"]["enemyMoveTime"].Float();
movementContext->progress += timeDelta / heroMoveTime; movementContext->progress += timeDelta / heroMoveTime;
movementContext->progress = std::min( 1.0, movementContext->progress);
Point positionFrom = Point(hero->convertToVisitablePos(movementContext->tileFrom)) * model->getSingleTileSize() + model->getSingleTileSize() / 2; Point positionFrom = Point(hero->convertToVisitablePos(movementContext->tileFrom)) * model->getSingleTileSize() + model->getSingleTileSize() / 2;
Point positionDest = Point(hero->convertToVisitablePos(movementContext->tileDest)) * model->getSingleTileSize() + model->getSingleTileSize() / 2; Point positionDest = Point(hero->convertToVisitablePos(movementContext->tileDest)) * model->getSingleTileSize() + model->getSingleTileSize() / 2;
Point positionCurr = vstd::lerp(positionFrom, positionDest, movementContext->progress); Point positionCurr = vstd::lerp(positionFrom, positionDest, movementContext->progress);
if(movementContext->progress >= 1.0) setViewCenter(positionCurr, movementContext->tileDest.z);
{
setViewCenter(hero->getSightCenter());
removeObject(context->getObject(movementContext->target));
addObject(context->getObject(movementContext->target));
activateAdventureContext(movementContext->animationTime);
}
else
{
setViewCenter(positionCurr, movementContext->tileDest.z);
}
} }
if(teleportContext) if(teleportContext)
{ {
teleportContext->progress += timeDelta / heroTeleportDuration; teleportContext->progress += timeDelta / heroTeleportDuration;
if(teleportContext->progress >= 1.0) teleportContext->progress = std::min( 1.0, teleportContext->progress);
{
activateAdventureContext(teleportContext->animationTime);
}
} }
if(fadingOutContext) if(fadingOutContext)
{ {
fadingOutContext->progress -= timeDelta / fadeOutDuration; fadingOutContext->progress -= timeDelta / fadeOutDuration;
fadingOutContext->progress = std::max( 0.0, fadingOutContext->progress);
if(fadingOutContext->progress <= 0.0)
{
removeObject(context->getObject(fadingOutContext->target));
activateAdventureContext(fadingOutContext->animationTime);
}
} }
if(fadingInContext) if(fadingInContext)
{ {
fadingInContext->progress += timeDelta / fadeInDuration; fadingInContext->progress += timeDelta / fadeInDuration;
fadingInContext->progress = std::min( 1.0, fadingInContext->progress);
if(fadingInContext->progress >= 1.0)
{
activateAdventureContext(fadingInContext->animationTime);
}
} }
if(adventureContext) if(adventureContext)
@ -180,6 +156,48 @@ void MapViewController::update(uint32_t timeDelta)
} }
} }
void MapViewController::updateAfter(uint32_t timeDelta)
{
if(movementContext)
{
const auto * object = context->getObject(movementContext->target);
const auto * hero = dynamic_cast<const CGHeroInstance *>(object);
const auto * boat = dynamic_cast<const CGBoat *>(object);
assert(boat || hero);
if(!hero)
hero = boat->hero;
if(movementContext->progress >= 1.0)
{
setViewCenter(hero->getSightCenter());
removeObject(context->getObject(movementContext->target));
addObject(context->getObject(movementContext->target));
activateAdventureContext(movementContext->animationTime);
}
}
if(teleportContext && teleportContext->progress >= 1.0)
{
activateAdventureContext(teleportContext->animationTime);
}
if(fadingOutContext && fadingOutContext->progress <= 0.0)
{
removeObject(context->getObject(fadingOutContext->target));
activateAdventureContext(fadingOutContext->animationTime);
}
if(fadingInContext && fadingInContext->progress >= 1.0)
{
activateAdventureContext(fadingInContext->animationTime);
}
}
bool MapViewController::isEventVisible(const CGObjectInstance * obj) bool MapViewController::isEventVisible(const CGObjectInstance * obj)
{ {
if(adventureContext == nullptr) if(adventureContext == nullptr)

@ -83,7 +83,8 @@ public:
void setViewCenter(const int3 & position); void setViewCenter(const int3 & position);
void setViewCenter(const Point & position, int level); void setViewCenter(const Point & position, int level);
void setTileSize(const Point & tileSize); void setTileSize(const Point & tileSize);
void update(uint32_t timeDelta); void updateBefore(uint32_t timeDelta);
void updateAfter(uint32_t timeDelta);
void activateAdventureContext(uint32_t animationTime); void activateAdventureContext(uint32_t animationTime);
void activateAdventureContext(); void activateAdventureContext();