[Scummvm-cvs-logs] SF.net SVN: scummvm:[45714] scummvm/trunk/engines/draci

spalek at users.sourceforge.net spalek at users.sourceforge.net
Sat Nov 7 05:56:28 CET 2009


Revision: 45714
          http://scummvm.svn.sourceforge.net/scummvm/?rev=45714&view=rev
Author:   spalek
Date:     2009-11-07 04:56:28 +0000 (Sat, 07 Nov 2009)

Log Message:
-----------
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.

Modified Paths:
--------------
    scummvm/trunk/engines/draci/animation.cpp
    scummvm/trunk/engines/draci/animation.h
    scummvm/trunk/engines/draci/game.cpp
    scummvm/trunk/engines/draci/game.h
    scummvm/trunk/engines/draci/walking.cpp
    scummvm/trunk/engines/draci/walking.h

Modified: scummvm/trunk/engines/draci/animation.cpp
===================================================================
--- scummvm/trunk/engines/draci/animation.cpp	2009-11-07 01:54:47 UTC (rev 45713)
+++ scummvm/trunk/engines/draci/animation.cpp	2009-11-07 04:56:28 UTC (rev 45714)
@@ -64,6 +64,11 @@
 	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",

Modified: scummvm/trunk/engines/draci/animation.h
===================================================================
--- scummvm/trunk/engines/draci/animation.h	2009-11-07 01:54:47 UTC (rev 45713)
+++ scummvm/trunk/engines/draci/animation.h	2009-11-07 04:56:28 UTC (rev 45714)
@@ -99,6 +99,7 @@
 	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; }

Modified: scummvm/trunk/engines/draci/game.cpp
===================================================================
--- scummvm/trunk/engines/draci/game.cpp	2009-11-07 01:54:47 UTC (rev 45713)
+++ scummvm/trunk/engines/draci/game.cpp	2009-11-07 04:56:28 UTC (rev 45714)
@@ -984,7 +984,7 @@
 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 @@
 	// 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 @@
 	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;

Modified: scummvm/trunk/engines/draci/game.h
===================================================================
--- scummvm/trunk/engines/draci/game.h	2009-11-07 01:54:47 UTC (rev 45713)
+++ scummvm/trunk/engines/draci/game.h	2009-11-07 04:56:28 UTC (rev 45714)
@@ -215,6 +215,7 @@
 	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);

Modified: scummvm/trunk/engines/draci/walking.cpp
===================================================================
--- scummvm/trunk/engines/draci/walking.cpp	2009-11-07 01:54:47 UTC (rev 45713)
+++ scummvm/trunk/engines/draci/walking.cpp	2009-11-07 04:56:28 UTC (rev 45714)
@@ -522,11 +522,16 @@
 
 	// 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::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;

Modified: scummvm/trunk/engines/draci/walking.h
===================================================================
--- scummvm/trunk/engines/draci/walking.h	2009-11-07 01:54:47 UTC (rev 45713)
+++ scummvm/trunk/engines/draci/walking.h	2009-11-07 04:56:28 UTC (rev 45714)
@@ -132,7 +132,7 @@
 	// 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;


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list