mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-15 22:28:10 +00:00
Add helper functions to retrieve dragon position from the animation.
To implement proper walking, I have to respect the relative shifts defined by the sprites as opposed to apply some constant velocity. svn-id: r45714
This commit is contained in:
parent
638305fcbb
commit
f534c12289
@ -64,6 +64,11 @@ Displacement Animation::getCurrentFrameDisplacement() const {
|
||||
return dis;
|
||||
}
|
||||
|
||||
Common::Point Animation::getCurrentFramePosition() const {
|
||||
Displacement dis = getCurrentFrameDisplacement();
|
||||
return Common::Point(dis.relX, dis.relY);
|
||||
}
|
||||
|
||||
void Animation::setLooping(bool looping) {
|
||||
_looping = looping;
|
||||
debugC(7, kDraciAnimationDebugLevel, "Setting looping to %d on animation %d",
|
||||
|
@ -99,6 +99,7 @@ public:
|
||||
int getRelativeY() const { return _displacement.relY; }
|
||||
const Displacement &getDisplacement() const { return _displacement; } // displacement of the whole animation
|
||||
Displacement getCurrentFrameDisplacement() const; // displacement of the current frame (includes _shift)
|
||||
Common::Point getCurrentFramePosition() const; // with displacement and shift applied
|
||||
|
||||
int getIndex() const { return _index; }
|
||||
void setIndex(int index) { _index = index; }
|
||||
|
@ -984,7 +984,7 @@ void Game::setHeroPosition(const Common::Point &p) {
|
||||
void Game::positionHero(const Common::Point &p, SightDirection dir) {
|
||||
setHeroPosition(p);
|
||||
Common::Point mousePos(_vm->_mouse->getPosX(), _vm->_mouse->getPosY());
|
||||
playHeroAnimation(_walkingState.animationForSightDirection(dir, _hero, mousePos, WalkingPath()));
|
||||
playHeroAnimation(WalkingState::animationForSightDirection(dir, _hero, mousePos, WalkingPath()));
|
||||
}
|
||||
|
||||
Common::Point Game::findNearestWalkable(int x, int y) const {
|
||||
@ -1477,16 +1477,12 @@ void Game::positionAnimAsHero(Animation *anim) {
|
||||
// Fetch current frame
|
||||
Drawable *frame = anim->getCurrentFrame();
|
||||
|
||||
// Fetch base dimensions of the frame
|
||||
uint height = frame->getHeight();
|
||||
uint width = frame->getWidth();
|
||||
|
||||
// We naturally want the dragon to position its feet to the location of the
|
||||
// click but sprites are drawn from their top-left corner so we subtract
|
||||
// the current height of the dragon's sprite
|
||||
Common::Point p = _hero;
|
||||
p.x -= (int)(scale * width) / 2;
|
||||
p.y -= (int)(scale * height);
|
||||
p.x -= (int)(scale * frame->getWidth() / 2);
|
||||
p.y -= (int)(scale * frame->getHeight());
|
||||
|
||||
// Since _persons[] is used for placing talking text, we use the non-adjusted x value
|
||||
// so the text remains centered over the dragon.
|
||||
@ -1499,6 +1495,26 @@ void Game::positionAnimAsHero(Animation *anim) {
|
||||
anim->setRelative(p.x, p.y);
|
||||
}
|
||||
|
||||
void Game::positionHeroAsAnim(Animation *anim) {
|
||||
// Check out where the hero has moved to by composing the relative
|
||||
// shifts of the sprites.
|
||||
_hero = anim->getCurrentFramePosition();
|
||||
|
||||
// Update our hero coordinates (don't forget that our control point is
|
||||
// elsewhere).
|
||||
Drawable *frame = anim->getCurrentFrame();
|
||||
_hero.x += (int) (anim->getScaleX() * frame->getWidth() / 2);
|
||||
_hero.y += (int) (anim->getScaleY() * frame->getHeight());
|
||||
|
||||
// Clear the animation's shift so that by updating the coordinates the
|
||||
// animation will stay in place.
|
||||
anim->clearShift();
|
||||
|
||||
// Call the inverse procedure to calculate new scaling factors.
|
||||
// TODO: what about rounding errors?
|
||||
positionAnimAsHero(anim);
|
||||
}
|
||||
|
||||
void Game::pushNewRoom() {
|
||||
_pushedNewRoom = _newRoom;
|
||||
_pushedNewGate = _newGate;
|
||||
|
@ -215,6 +215,7 @@ public:
|
||||
int getHeroX() const { return _hero.x; }
|
||||
int getHeroY() const { return _hero.y; }
|
||||
void positionAnimAsHero(Animation *anim);
|
||||
void positionHeroAsAnim(Animation *anim);
|
||||
void playHeroAnimation(int anim_index);
|
||||
|
||||
int loadAnimation(uint animNum, uint z);
|
||||
|
@ -522,11 +522,16 @@ bool WalkingState::continueWalking() {
|
||||
|
||||
// We are walking in the middle of an edge. The animation phase has
|
||||
// just changed. Update the position of the hero.
|
||||
_position += 4; // TODO: compute shifts properly from the animation
|
||||
Common::Point newPos = WalkingMap::interpolate(
|
||||
_path[_segment], _path[_segment+1], _position, _length);
|
||||
_vm->_game->setHeroPosition(newPos);
|
||||
_vm->_game->positionAnimAsHero(anim);
|
||||
_vm->_game->positionHeroAsAnim(anim);
|
||||
// TODO: take the [XY] coordinate determined by the animation, update
|
||||
// the other one so that the hero stays on the edge, remove _position
|
||||
// and _length, and instead test reaching the destination by computing
|
||||
// the scalar product
|
||||
_position += 4;
|
||||
// Common::Point newPos = WalkingMap::interpolate(
|
||||
// _path[_segment], _path[_segment+1], _position, _length);
|
||||
// _vm->_game->setHeroPosition(newPos);
|
||||
// _vm->_game->positionAnimAsHero(anim);
|
||||
|
||||
// If the hero has reached the end of the edge, start transition to the
|
||||
// next phase. This will increment _segment, either immediately (if no
|
||||
@ -698,7 +703,7 @@ Movement WalkingState::transitionBetweenAnimations(Movement previous, Movement n
|
||||
}
|
||||
}
|
||||
|
||||
Movement WalkingState::animationForSightDirection(SightDirection dir, const Common::Point &hero, const Common::Point &mouse, const WalkingPath &path) const {
|
||||
Movement WalkingState::animationForSightDirection(SightDirection dir, const Common::Point &hero, const Common::Point &mouse, const WalkingPath &path) {
|
||||
switch (dir) {
|
||||
case kDirectionMouse:
|
||||
return mouse.x < hero.x ? kStopLeft : kStopRight;
|
||||
|
@ -132,7 +132,7 @@ public:
|
||||
// direction. The direction can be smart and in that case this
|
||||
// function needs to know the whole last path, the current position of
|
||||
// the hero, or the mouse position.
|
||||
Movement animationForSightDirection(SightDirection dir, const Common::Point &hero, const Common::Point &mouse, const WalkingPath &path) const;
|
||||
static Movement animationForSightDirection(SightDirection dir, const Common::Point &hero, const Common::Point &mouse, const WalkingPath &path);
|
||||
|
||||
private:
|
||||
DraciEngine *_vm;
|
||||
|
Loading…
Reference in New Issue
Block a user