aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Špalek2009-11-07 12:20:27 +0000
committerRobert Špalek2009-11-07 12:20:27 +0000
commit9f1a756576ccbfaa01521697142a1e715fe57a5d (patch)
tree469b7f970678b2fa642479eb4023a6f3d532194b
parent72157e1077b48d4454819eac330be0ccc4f4c0ff (diff)
downloadscummvm-rg350-9f1a756576ccbfaa01521697142a1e715fe57a5d.tar.gz
scummvm-rg350-9f1a756576ccbfaa01521697142a1e715fe57a5d.tar.bz2
scummvm-rg350-9f1a756576ccbfaa01521697142a1e715fe57a5d.zip
Gradual walking implemented.
It is not fully smooth yet due to rounding errors. However, it otherwise does what it is supposed to including perspective correction. svn-id: r45727
-rw-r--r--engines/draci/walking.cpp26
1 files changed, 21 insertions, 5 deletions
diff --git a/engines/draci/walking.cpp b/engines/draci/walking.cpp
index af64daf522..51b77cb049 100644
--- a/engines/draci/walking.cpp
+++ b/engines/draci/walking.cpp
@@ -514,6 +514,7 @@ bool WalkingState::continueWalking() {
const int animPhase = anim->currentFrameNum();
const bool wasUpdated = animPhase != _lastAnimPhase;
if (!wasUpdated) {
+ debugC(4, kDraciWalkingDebugLevel, "Waiting for an animation phase change: still %d", animPhase);
return true;
}
@@ -527,8 +528,8 @@ bool WalkingState::continueWalking() {
Common::Point newHero = hero;
const bool reachedEnd = alignHeroToEdge(_path[_segment], _path[_segment+1], &newHero);
- debugC(3, kDraciWalkingDebugLevel, "Continuing walking in segment %d and position [%d,%d] projected to [%d,%d]",
- _segment, hero.x, hero.y, newHero.x, newHero.y);
+ debugC(3, kDraciWalkingDebugLevel, "Continuing walking in segment %d: phase %d and position [%d,%d] projected to [%d,%d]",
+ _segment, animPhase, hero.x, hero.y, newHero.x, newHero.y);
// Update the hero position to the projected one. The animation number
// is not changing, so this will just move the sprite and return the
@@ -549,9 +550,24 @@ bool WalkingState::continueWalking() {
}
bool WalkingState::alignHeroToEdge(const Common::Point &p1, const Common::Point &p2, Common::Point *hero) {
- // TODO
- *hero = p2;
- return true;
+ const Common::Point heroDiff(hero->x - p1.x, hero->y - p1.y);
+ const Common::Point p2Diff(p2.x - p1.x, p2.y - p1.y);
+ const int scalarProduct = p2Diff.x * heroDiff.x + p2Diff.y * heroDiff.y;
+ const int p2DiffSqNorm = p2Diff.x * p2Diff.x + p2Diff.y * p2Diff.y;
+ double fraction = ((double) scalarProduct) / p2DiffSqNorm;
+ bool reachedEnd = false;
+ if (fraction >= 1.0) {
+ fraction = 1.0;
+ reachedEnd = true;
+ }
+ hero->x = p1.x + (int) (fraction * p2Diff.x + 0.5);
+ hero->y = p1.y + (int) (fraction * p2Diff.y + 0.5);
+ // TODO: unfortunately, the left-right walking animation jumps up and
+ // down by two pixels instead of going exactly horizontally, which
+ // means that the projection algorithm screws the vertical "shaking" as
+ // well as rounds horizontal positions improperly. Fix it by better
+ // rounding or different projection.
+ return reachedEnd;
}
void WalkingState::turnForTheNextSegment() {