Anonymous avatar Anonymous committed aa8e8f2

split CCharacter into PlayerModel and PlayerView

Comments (0)

Files changed (24)

 border = fixed
 
 [Game]
-# intial speed (units/second)
-speed = 100.0
+# minimum speed (units/second)
+speedMin = 100.0
+# maximum speed (units/second)
+speedMax = 200.0
+# player acceleration (units/second^2)
+acceleration = 10.0
 # gravity (units/second^2)
 gravity = 650.0
 # jump acceleration (units/second^2)
 jump = 80.0
 # max jump time (seconds)
 jumpTime = 0.3
-# player acceleration (units/second^2)
-acceleration = 5.0
+
 
 [Camera]
 distance = 15

src/CMakeLists.txt

 	States/CMainMenuState.h
 	States/CGameState.h
 	States/CEditorState.h
-	GameObjects/CCharacter.h
-	GameObjects/CSindbadCharacter.h
 	GameObjects/CPivotCamera.h
 	GameObjects/COverlay.h
 	GameObjects/CProgressBar.h
 	GameObjects/LevelObjectManager.h
 	GameObjects/ObjectType.h
 	GameObjects/Geometry.h
+	GameObjects/PlayerModel.h
+	GameObjects/PlayerView.h
 	Core/Singleton.h
 	Core/CLog.h
 	testlog.h
 	States/CMainMenuState.cpp
 	States/CGameState.cpp
 	States/CEditorState.cpp
-	GameObjects/CCharacter.cpp
-	GameObjects/CSindbadCharacter.cpp
 	GameObjects/CPivotCamera.cpp	
 	GameObjects/COverlay.cpp
 	GameObjects/CProgressBar.cpp
 	GameObjects/LevelDataWriter.cpp
 	GameObjects/LevelObjects.cpp
 	GameObjects/OgreViews.cpp
+	GameObjects/PlayerModel.cpp
+	GameObjects/PlayerView.cpp
 	GameObjects/Geometry.cpp
 	main.cpp	
 )

src/GameObjects/CCharacter.cpp

-/*
- * CCharacter.cpp
- *
- *  Created on: Jul 3, 2010
- *      Author: crt
- */
-
-#include "CCharacter.h"
-
-namespace Game {
-namespace GameObjects {
-
-CCharacter::CCharacter(Ogre::SceneManager* sceneManager,
-		const std::string& ogreEntityName, const std::string& ogreMeshName)
-	: ogreBodyNode(NULL),
-	  ogreBodyEntity(NULL),
-	  fAnimationTimer(0.0),
-	  fJumpTime(0.0),
-	  bJumping(false),
-	  ogreScene(sceneManager),
-	  fVerticalVelocity(0.0),
-	  fSpeed(0.0),
-	  fJumpAcceleration(30.0),
-	  fAnimationFadeSpeed(7.5),
-	  fGravity(90.0),
-	  fMaxJumpTime(0.5)
-{
-	Constraints.bottom = Constraints.left = Constraints.right = Constraints.top = 0;
-
-	// create ogre node and entity
-	ogreBodyNode = sceneManager->getRootSceneNode()->createChildSceneNode(Ogre::Vector3::ZERO);
-	ogreBodyEntity = sceneManager->createEntity(ogreEntityName, ogreMeshName);
-	ogreBodyNode->attachObject(ogreBodyEntity);
-	ogreBodyEntity->getSkeleton()->setBlendMode(Ogre::ANIMBLEND_CUMULATIVE);
-	ogreBodyEntity->setCastShadows(true);
-
-	// setup helper arrays
-	AnimationIDs.clear();
-	AnimationIDs.push_back(animNone);
-	AnimationIDs.push_back(animIdleTop);
-	AnimationIDs.push_back(animIdleBase);
-	AnimationIDs.push_back(animRunTop);
-	AnimationIDs.push_back(animRunBase);
-	AnimationIDs.push_back(animJumpStart);
-	AnimationIDs.push_back(animJumpLoop);
-	AnimationIDs.push_back(animJumpEnd);
-	AnimationTargets.clear();
-	AnimationTargets.push_back(atTop);
-	AnimationTargets.push_back(atBase);
-
-	for (int i=0; i < AnimationIDs.size(); ++i) {
-		AnimationID id = static_cast<AnimationID>(AnimationIDs[i]);
-		Animations.insert(std::make_pair<AnimationID, std::string>(id, ""));
-		AnimationStates.insert(std::make_pair<AnimationID, Ogre::AnimationState*>(id, NULL));
-		AnimationFadeIn.insert(std::make_pair<AnimationID, bool>(id, false));
-		AnimationFadeOut.insert(std::make_pair<AnimationID, bool>(id, false));
-	}
-
-	for (int i=0; i < AnimationTargets.size(); ++i) {
-		AnimationTarget target = static_cast<AnimationTarget>(AnimationTargets[i]);
-		currentAnimations.insert(std::make_pair<AnimationTarget, AnimationID>(target, animNone));
-	}
-}
-
-void CCharacter::SetupAnimations() {
-	for (int i=0; i < AnimationIDs.size(); ++i) {
-		AnimationID id = static_cast<AnimationID>(AnimationIDs[i]);
-
-		// set default values
-		AnimationStates[id] = NULL;
-		AnimationFadeIn[id] = false;
-		AnimationFadeOut[id] = false;
-
-		// dont set animNone
-		if (id == animNone)
-			continue;
-
-		// try to get Ogre Animation State by name
-		std::string animName = Animations[id];
-		if (animName != "") {
-			Ogre::AnimationState* animState = ogreBodyEntity->getAnimationState(animName);
-			if (animState) {
-				AnimationStates[id] = animState;
-				animState->setLoop(true);
-				animState->setEnabled(false);
-			}
-		}
-	}
-
-	// rest all animation targets
-	for (int i=0; i < AnimationTargets.size(); ++i) {
-		AnimationTarget target = static_cast<AnimationTarget>(AnimationTargets[i]);
-		SetAnimation(target, animNone);
-	}
-}
-
-void CCharacter::SetAnimation(AnimationTarget target, AnimationID animation, bool reset) {
-	// fade old animation out
-	if (currentAnimations[target] != animNone) {
-		AnimationFadeIn[currentAnimations[target]] = false;
-		AnimationFadeOut[currentAnimations[target]] = true;
-	}
-
-	currentAnimations[target] = animation;
-
-	if (animation != animNone) {
-		// fade new animation in
-		if (AnimationStates[animation] != NULL) {
-			AnimationStates[animation]->setEnabled(true);
-			AnimationStates[animation]->setWeight(0);
-			if (reset) AnimationStates[animation]->setTimePosition(0);
-		}
-
-		AnimationFadeIn[animation] = true;
-		AnimationFadeOut[animation] = false;
-	}
-}
-
-void CCharacter::BeginJump() {
-	// dont start over if already jumping
-	if (bJumping)
-		return;
-
-	// setup parameters
-	fJumpTime = 0;
-	bJumping = true;
-	bJumpAccel = true;
-	fVerticalVelocity = fJumpAcceleration;
-
-	// start animation
-	SetAnimation(atBase, animJumpStart, true);
-	SetAnimation(atBase, animJumpLoop, true);
-	SetAnimation(atTop, animNone);
-	fAnimationTimer = 0;
-}
-
-void CCharacter::FinishJump() {
-	if (bJumpAccel) {
-		bJumpAccel = false;
-	}
-}
-
-PCharacter CCharacter::Create(Ogre::SceneManager* sceneManager,
-		const std::string& ogreEntityName, const std::string& ogreMeshName) {
-	CCharacter* character = new CCharacter(sceneManager, ogreEntityName, ogreMeshName);
-	PCharacter characterPtr(character);
-	character->self = characterPtr;
-	return characterPtr;
-}
-
-const float TOL = 0.00001;
-
-void CheckFloatZero(Ogre::Real& f) {
-	if (f > -TOL && f < TOL)
-		f = 0.0;
-}
-
-void CCharacter::Update(float deltaTime) {
-	Ogre::Vector2 translation;
-
-	if (!bJumping)
-		fVerticalVelocity = -fGravity*deltaTime;
-
-	// walk/jump/fall
-	if (goLevel != NULL) {
-		Game::Rectangle boundingRect;
-		Ogre::Vector3 position = GetPosition();
-		boundingRect.SetExtends(position.z - bounds.left, position.y - bounds.bottom,
-				position.z + bounds.right, position.y + bounds.top);
-
-		// make temporary levelobject (workaround)
-		GameObjects::PMovableObject temp = CMovableObject::Create();
-		temp->SetPosition(Ogre::Vector2(position.z, position.y));
-		temp->SetBoundingBox(boundingRect);
-		temp->SetParent(goLevel);
-
-		translation = Ogre::Vector2(deltaTime * fSpeed, deltaTime * fVerticalVelocity);
-		temp->Move(translation);
-
-		translation = temp->GetPosition() - Ogre::Vector2(position.z, position.y);
-
-		ogreBodyNode->translate(0.0f, translation.y, translation.x, Ogre::Node::TS_LOCAL);
-		CheckFloatZero(translation.x); CheckFloatZero(translation.y);
-	}
-
-	if (translation.x <= 0) {
-		fSpeed = 80;
-	}
-
-	// fall down
-	if (!bJumping && translation.y < 0) {
-		bJumping = true;
-		bJumpAccel = false;
-		SetAnimation(atBase, animJumpLoop, true);
-		SetAnimation(atTop, animNone);
-	}
-
-	// jump
-	if (bJumping) {
-
-		if (bJumpAccel) {
-			fJumpTime += deltaTime;
-			if (fJumpTime >= fMaxJumpTime) {
-				bJumpAccel = false;
-			}
-		}
-
-		if (fVerticalVelocity > 0 && translation.y <= 0) {
-			// collision top
-			//ogreBodyNode->translate(0, Constraints.top, 0, Ogre::Node::TS_LOCAL);
-
-			// finish jump
-			bJumpAccel = false;
-			fVerticalVelocity = 0;
-		} else if (fVerticalVelocity < 0 && translation.y >= 0) {
-			// collision bottom
-			//ogreBodyNode->translate(0, Constraints.bottom, 0, Ogre::Node::TS_LOCAL);
-
-			// finish jump
-			SetAnimation(atBase, animJumpEnd, true);
-			fAnimationTimer = 0;
-			bJumping = false;
-		} else {
-			//ogreBodyNode->translate(0, fVerticalVelocity * deltaTime, 0, Ogre::Node::TS_LOCAL);
-		}
-
-		if (!bJumpAccel)
-			fVerticalVelocity -= fGravity * deltaTime;
-
-	} else if (currentAnimations[atBase] != animJumpEnd) {
-		if (fSpeed > 0) {
-			if (currentAnimations[atTop] != animRunTop) {
-				SetAnimation(atTop, animRunTop);
-			}
-			if (currentAnimations[atBase] != animRunBase) {
-				SetAnimation(atBase, animRunBase);
-			}
-		} else {
-			if (currentAnimations[atTop] != animIdleTop) {
-				SetAnimation(atTop, animIdleTop);
-			}
-			if (currentAnimations[atBase] != animIdleBase) {
-				SetAnimation(atBase, animIdleBase);
-			}
-		}
-	}
-
-	// update animations
-	fAnimationTimer += deltaTime;
-
-	if (currentAnimations[atBase] == animJumpStart) {
-		if (fAnimationTimer >= AnimationStates[animJumpStart]->getLength()) {
-			SetAnimation(atBase, animJumpLoop, true);
-		}
-	}
-	else if (currentAnimations[atBase] == animJumpEnd) {
-		if (fAnimationTimer >= AnimationStates[animJumpEnd]->getLength()) {
-			if (fSpeed > 0) {
-				SetAnimation(atBase, animRunBase);
-				SetAnimation(atTop, animRunTop);
-			} else {
-				SetAnimation(atBase, animIdleBase);
-				SetAnimation(atTop, animIdleTop);
-			}
-		}
-	}
-
-	for (int i=0; i < AnimationTargets.size(); ++i) {
-		AnimationTarget target = static_cast<AnimationTarget>(AnimationTargets[i]);
-
-		if (currentAnimations[target] != animNone) {
-			if (AnimationStates[currentAnimations[target]] != NULL) {
-				AnimationStates[currentAnimations[target]]->addTime(deltaTime);
-			}
-		}
-	}
-
-	fadeAnimations(deltaTime);
-}
-
-void CCharacter::fadeAnimations(float deltaTime) {
-	for (int i=0; i < AnimationIDs.size(); ++i) {
-		AnimationID id = static_cast<AnimationID>(AnimationIDs[i]);
-
-		if (AnimationStates[id] == NULL)
-			continue;
-
-		if (AnimationFadeIn[id]) {
-			Ogre::Real newWeight = AnimationStates[id]->getWeight() + deltaTime * fAnimationFadeSpeed;
-			AnimationStates[id]->setWeight(Ogre::Math::Clamp<Ogre::Real>(newWeight, 0, 1));
-			if (newWeight >= 1) AnimationFadeIn[id] = false;
-		} else if (AnimationFadeOut[id]) {
-			Ogre::Real newWeight = AnimationStates[id]->getWeight() - deltaTime * fAnimationFadeSpeed;
-			AnimationStates[id]->setWeight(Ogre::Math::Clamp<Ogre::Real>(newWeight, 0, 1));
-			if (newWeight <= 0)
-			{
-				AnimationStates[id]->setEnabled(false);
-				AnimationFadeOut[id] = false;
-			}
-		}
-	}
-}
-
-CCharacter::~CCharacter() {
-}
-
-}
-}

src/GameObjects/CCharacter.h

-/*
- * CCharacter.h
- *
- *  Created on: Jul 3, 2010
- *      Author: crt
- */
-
-#ifndef CCHARACTER_H_
-#define CCHARACTER_H_
-
-#include "LevelObjects.h"
-#include "CLevelData.h"
-
-#include "Ogre.h"
-#include <string>
-#include <map>
-#include <vector>
-
-#include "boost/smart_ptr.hpp"
-
-namespace Game {
-namespace GameObjects {
-
-class CCharacter;
-typedef boost::shared_ptr<CCharacter> PCharacter;
-typedef boost::weak_ptr<CCharacter> WPCharacter;
-
-/** Defines a Character from an Ogre Mesh with Animations
- @remarks Animations are handled automatically depending on Speed and Jump State.
-		  Manually set Animations might be overridden by a call of Update
- */
-class CCharacter {
-public:
-	enum AnimationID
-	{
-		animNone,
-		animIdleTop,
-		animIdleBase,
-		animRunTop,
-		animRunBase,
-		animJumpStart,
-		animJumpLoop,
-		animJumpEnd
-	};
-	enum AnimationTarget
-	{
-		atTop,
-		atBase
-	};
-
-	typedef std::map<AnimationID, std::string> AnimationMap;
-	typedef std::map<AnimationID, std::string>::iterator AnimationMapItor;
-
-	/** Get/Set Animation Names
-	 @remarks Call SetupAnimations() after making changes
-	 */
-	AnimationMap Animations;
-
-	/** Initializes Animations which were defined by this->Animations.
-	    Sets Animation to animNone */
-	void SetupAnimations();
-
-	/** Set Current Animation (fade out last animation, fade in new animation)
-	 @param reset Start from beginning if set
-	 @param target Specifiy top or base animation
-	 */
-	void SetAnimation(AnimationTarget target, AnimationID animation, bool reset = false);
-
-	/** Start Jump, i.e. user just pressed Space
-	 @remarks Does nothing if character is already in the Air;
-			  Character will gain height until maximum is reached.
-	 */
-	void BeginJump();
-
-	/** Stop Jump, i.e. user just released Space
-	 @remarks Stops acceleration in Y direction if not already automatically stopped.
-	 */
-	void FinishJump();
-
-	// wrappers for internal Ogre Entity
-	inline Ogre::Quaternion GetOrientation() { return ogreBodyNode->getOrientation(); }
-	inline void SetOrientation(const Ogre::Quaternion& orientation) { ogreBodyNode->setOrientation(orientation); }
-	inline Ogre::Vector3 GetPosition() { return ogreBodyNode->_getDerivedPosition(); }
-	inline void SetPosition(const Ogre::Vector3& position) { ogreBodyNode->_setDerivedPosition(position); }
-
-	/** Set Character's speed in XZ direction (units/second)
-	    Default: 17.0 */
-	inline void SetSpeed(float speed) { fSpeed = speed; }
-	inline float GetSpeed() { return fSpeed; }
-
-	/** Set Jump Acceleration (units/second^2)
-	    Default: 30.0*/
-	inline void SetJumpAcceleration(float acceleration) { fJumpAcceleration = acceleration; }
-	inline float GetJumpAcceleration() { return fJumpAcceleration; }
-
-	/** Set Animation Crossfade Speed (%weight/second)
-		Default: 7.5*/
-	inline void SetAnimationFadeSpeed(float fadespeed) { fAnimationFadeSpeed = fadespeed; }
-	inline float GetAnimationFadeSpeed() { return fAnimationFadeSpeed; }
-
-	/** Set Gravity (units/second^2)
-		Default: 90.0*/
-	inline void SetGravity(float g) { fGravity = g; }
-	inline float GetGravity() { return fGravity; }
-
-	/** Set maximum Time the character should accelerate when jumping (seconds)
-	    Default: 1.0*/
-	inline void SetMaxJumpTime(float time) { fMaxJumpTime = time; }
-	inline float GetMaxJumpTime() { return fMaxJumpTime; }
-
-	/** Set Boundaries in which character can move
-	 *  Constraints are relative to center;
-	 *  Left and Bottom must be negative; Top and Right must be positive */
-	inline void SetConstraints(const Ogre::Rectangle& constraints) { Constraints = constraints; }
-
-	inline void SetBounds(float left, float top, float right, float bottom) {
-		bounds.left = left; bounds.right = right;
-		bounds.top = top; bounds.bottom = bottom;
-	}
-
-	inline void SetLevel(PLevelData level) { goLevel = level; }
-
-	inline Ogre::SceneNode* GetSceneNode() { return ogreBodyNode; }
-
-	/** Update Character */
-	void Update(float deltaTime);
-
-	/** Factory Method; creates a new object */
-	static PCharacter Create(Ogre::SceneManager* sceneManager,
-			const std::string& ogreEntityName, const std::string& ogreMeshName);
-
-	virtual ~CCharacter();
-protected:
-	typedef std::map<AnimationID, Ogre::AnimationState*> AnimationStateMap;
-	typedef std::map<AnimationID, Ogre::AnimationState*>::iterator AnimationStateMapItor;
-
-	typedef std::map<AnimationTarget, AnimationID> AnimationTargetMap;
-	typedef std::map<AnimationTarget, AnimationID>::iterator AnimationTargetMapItor;
-
-	// helper array to make "foreach (AnimationID)" possible
-	// stores the int equivalent for each element in AnimationID
-	std::vector<int> AnimationIDs;
-
-	// same for AnimationTarget
-	std::vector<int> AnimationTargets;
-
-	// weak pointer to this
-	WPCharacter self;
-
-	// Ogre Animation States
-	AnimationStateMap AnimationStates;
-
-	// Defines which Animations are currently fading in or out
-	std::map<AnimationID, bool> AnimationFadeIn;
-	std::map<AnimationID, bool> AnimationFadeOut;
-
-	// Current Animation
-	AnimationTargetMap currentAnimations;
-
-	// Ogre Model
-	Ogre::SceneNode* ogreBodyNode;
-	Ogre::Entity* ogreBodyEntity;
-
-	// Collision Data
-	PLevelData goLevel;
-	Ogre::Rectangle bounds;
-
-	// Timer used to see how long Animations have been playing
-	// used for JumpStart, JumpEnd
-	float fAnimationTimer;
-
-	// Variables used for jumping
-	float fJumpTime;
-	bool bJumping;
-	bool bJumpAccel;
-	float fVerticalVelocity;
-	float fMaxJumpTime;
-
-	float fSpeed;
-	float fJumpAcceleration;
-	float fAnimationFadeSpeed;
-	float fGravity;
-
-	Ogre::SceneManager* ogreScene;
-
-	// boundaries for movement
-	Ogre::Rectangle Constraints;
-
-	void fadeAnimations(float deltaTime);
-
-	CCharacter(Ogre::SceneManager* sceneManager,
-			const std::string& ogreEntityName, const std::string& ogreMeshName);
-};
-
-}
-}
-
-#endif /* CCHARACTER_H_ */

src/GameObjects/CLevelData.cpp

 namespace GameObjects {
 
 CLevelData::CLevelData() {
+	player = CPlayerModel::Create();
+	playerView = CPlayerOgreView::Create(player);
+
+	player->SetPosition(Ogre::Vector2::UNIT_Y * 5);
+	player->SetSpeedLimits(CSettingsManager::GetSingleton().get<float>("Game", "speedMin", 50.0f),
+						   CSettingsManager::GetSingleton().get<float>("Game", "speedMax", 100.0f),
+						   CSettingsManager::GetSingleton().get<float>("Game", "acceleration", 1.0f));
+
+	player->SetGravity(CSettingsManager::GetSingleton().get<float>("Game", "gravity", 90.0f));
+	player->SetJumpAcceleration(CSettingsManager::GetSingleton().get<float>("Game", "jump", 30.0f));
+	player->SetMaxJumpTime(CSettingsManager::GetSingleton().get<float>("Game", "jumpTime", 1.0f));
 }
 
 CLevelData::~CLevelData() {
 }
 
 void CLevelData::InsertObject(PLevelObject object, ObjectType type) {
+	object->SetParent(self.lock());
 	switch (type) {
 	case otStatic:
 		staticLevelData.push_back(object);
 }
 
 void CLevelData::InsertView(POgreView view, ObjectType type) {
-	ogreViews.push_back(view);
+	if (view->IsUpdateable())
+		ogreUpdateableViews.push_back(view);
+	else
+		ogreViews.push_back(view);
 }
 
 Ogre::SceneNode* CLevelData::Draw(Ogre::SceneManager* ogreScene, Ogre::SceneNode* ogreNode) {
 	for (OgreViewList::iterator it = ogreViews.begin(); it != ogreViews.end(); ++it) {
 		(*it)->SetOgreScene(ogreScene, node);
 	}
+	for (OgreViewList::iterator it = ogreUpdateableViews.begin(); it != ogreUpdateableViews.end(); ++it) {
+		(*it)->SetOgreScene(ogreScene, node);
+	}
+	playerView->SetOgreScene(ogreScene, node);
 
 	return node;
 }
 
+void CLevelData::Update(float deltaTime) {
+	for (OgreViewList::iterator it = ogreUpdateableViews.begin(); it != ogreUpdateableViews.end(); ++it) {
+		(*it)->Update(deltaTime);
+	}
+	playerView->Update(deltaTime);
+	player->Update(deltaTime);
+}
+
 typedef ILevelObjectManager::LevelObjectList LevelObjectList;
 
 ILevelObjectManager::LevelObjectList CLevelData::GetObjectRectangle(const Game::Rectangle& rect, ILevelObjectManager::LevelObjectList& list) {

src/GameObjects/CLevelData.h

 #include "LevelObjects.h"
 #include "LevelDataReader.h"
 #include "LevelObjectManager.h"
+#include "PlayerModel.h"
+#include "PlayerView.h"
 #include "../testlog.h"
 #include "../Core/CLog.h"
+#include "../Core/CSettingsManager.h"
 
 #include "Ogre.h"
 
 
 class CLevelData;
 typedef boost::shared_ptr<CLevelData> PLevelData;
+typedef boost::weak_ptr<CLevelData> WLevelData;
 
 class CLevelData : public CXMLReader::Listener, public ILevelObjectManager {
 public:
-	CLevelData();
 	virtual ~CLevelData();
 
 	/** Draw level in given ogre scene manager
 	static PLevelData Create() {
 		CLevelData* leveldata = new CLevelData();
 		PLevelData leveldataPtr(leveldata);
+		leveldata->self = leveldataPtr;
+		leveldata->player->SetParent(leveldataPtr);
 		return leveldataPtr;
 	}
 
 	virtual void ReadLevelObject(PLevelObject object, ObjectType layer) {
 		InsertObject(object, static_cast<ObjectType>(layer) );
 	}
+
 	/** Implementation of CXMLReader::Listener */
 	virtual void ReadOgreView(POgreView view, ObjectType layer) {
 		InsertView(view, layer);
 	}
+
 	/** Implementation of ILevelObjectManager */
 	virtual ILevelObjectManager::LevelObjectList GetObjectRectangle(const Game::Rectangle& rect);
+
+	void Update(float deltaTime);
+
+	PPlayerModel GetPlayer() { return player; }
+	PPlayerOgreView GetPlayerView() { return playerView; }
 private:
+	CLevelData();
+
 	typedef std::vector<POgreView> OgreViewList;
 
 	ILevelObjectManager::LevelObjectList GetObjectRectangle(const Game::Rectangle& rect, ILevelObjectManager::LevelObjectList& list);
 	ILevelObjectManager::LevelObjectList backgroundLevelData;
 	ILevelObjectManager::LevelObjectList dynamicLevelData;
 	OgreViewList ogreViews;
+	OgreViewList ogreUpdateableViews;
+
+	PPlayerModel player;
+	PPlayerOgreView playerView;
+
+	WLevelData self;
 };
 
 }

src/GameObjects/CSindbadCharacter.cpp

-/*
- * CSindbadCharacter.cpp
- *
- *  Created on: Aug 6, 2010
- *      Author: crt
- */
-
-#include "CSindbadCharacter.h"
-
-namespace Game {
-namespace GameObjects {
-
-CSindbadCharacter::CSindbadCharacter(Ogre::SceneManager* sceneManager, std::string ogreName)
-	: CCharacter(sceneManager, ogreName, "Sinbad.mesh") {
-
-	// setup animations
-	Animations[GameObjects::CCharacter::animIdleBase] = "IdleBase";
-	Animations[GameObjects::CCharacter::animIdleTop] = "IdleTop";
-
-	Animations[GameObjects::CCharacter::animRunBase] = "RunBase";
-	Animations[GameObjects::CCharacter::animRunTop] = "RunTop";
-
-	Animations[GameObjects::CCharacter::animJumpStart] = "JumpStart";
-	Animations[GameObjects::CCharacter::animJumpLoop] = "JumpLoop";
-	Animations[GameObjects::CCharacter::animJumpEnd] = "JumpEnd";
-
-	SetupAnimations();
-
-	ogreBodyEntity->getAnimationState("HandsRelaxed")->setLoop(true);
-	ogreBodyEntity->getAnimationState("HandsRelaxed")->setEnabled(true);
-}
-
-CSindbadCharacter::~CSindbadCharacter() {
-}
-
-PSindbadCharacter CSindbadCharacter::Create(Ogre::SceneManager* sceneManager, std::string ogreName) {
-	CSindbadCharacter* character = new CSindbadCharacter(sceneManager, ogreName);
-	PSindbadCharacter characterPtr(character);
-	character->self = static_cast<PCharacter>(characterPtr);
-	return characterPtr;
-}
-
-}
-}

src/GameObjects/CSindbadCharacter.h

-/*
- * CSindbadCharacter.h
- *
- *  Created on: Aug 6, 2010
- *      Author: crt
- */
-
-#ifndef CSINDBADCHARACTER_H_
-#define CSINDBADCHARACTER_H_
-
-#include "CCharacter.h"
-#include "Ogre.h"
-#include "boost/smart_ptr.hpp"
-#include <string>
-
-namespace Game {
-namespace GameObjects {
-
-class CSindbadCharacter;
-typedef boost::shared_ptr<CSindbadCharacter> PSindbadCharacter;
-
-/** Character Game Object with hardcoded Animation Names */
-class CSindbadCharacter: public CCharacter {
-public:
-	virtual ~CSindbadCharacter();
-
-	static PSindbadCharacter Create(Ogre::SceneManager* sceneManager, std::string ogreName);
-private:
-	CSindbadCharacter(Ogre::SceneManager* sceneManager, std::string ogreName);
-};
-
-}
-}
-
-#endif /* CSINDBADCHARACTER_H_ */

src/GameObjects/LevelDataReader.cpp

 	ticpp::Element* handler = node.FirstChildElement("CollisionHandler", false);
 	if (handler) {
 		std::string handlerType = ReadString(*handler, "type");
-		if (handlerType == "Coin")
-			object->SetCollisionHandler(TestHandler());
+//		if (handlerType == "Coin")
+//			object->SetCollisionHandler(TestHandler());
 	}
 }
 

src/GameObjects/LevelObjects.cpp

 	}
 }
 
-void CMovableObject::Move(const Ogre::Vector2& translation) {
+Ogre::Vector2 CMovableObject::Move(const Ogre::Vector2& translation) {
 	PLevelObject object = self.lock();
 	PLevelObjectManager manager = parent.lock();
 	if (!object || !manager) {
 		this->SetPosition(this->GetPosition() + translation);
-		return;
+		return translation;
 	}
 	Ogre::Vector2 resolve = ResolveCollision(object, translation);
 	if (!std::isnan(resolve.x) && !std::isnan(resolve.y) && !std::isinf(resolve.x) && !std::isinf(resolve.y))
 		this->SetPosition(this->GetPosition() + resolve);
+	return resolve;
 }
 
 typedef ILevelObjectManager::LevelObjectList LevelObjectList;
 		// do more accurate intersection test for objects that are in range
 		for (LevelObjectList::iterator it = objects.begin(); it != objects.end(); ++it) {
 			const PLevelObject& obj = *it;
+			if (obj == object) continue;
+
 			// dont check non-blocking objects twice
 			if (std::find(ignoreObjects.begin(), ignoreObjects.end(), obj) != ignoreObjects.end())
 				continue;

src/GameObjects/LevelObjects.h

 	typedef std::set<PListener> ListenerList;
 	ListenerList Listeners;
 
-	void notifyPositionChanged();
-	void notifyBoundsChanged();
-	void notifyCollisionTypeChanged();
+	virtual void notifyPositionChanged();
+	virtual void notifyBoundsChanged();
+	virtual void notifyCollisionTypeChanged();
 };
 
 
 	virtual PLevelObject Copy() const;
 
 	/** Move object by translation with collision (needs Parent to be set) */
-	virtual void Move(const Ogre::Vector2& translation);
+	virtual Ogre::Vector2 Move(const Ogre::Vector2& translation);
 
 protected:
-	CMovableObject() { }
+	CMovableObject() : CLevelObject() { }
 
 	float GetTranslationFactorFromDirection(const Ogre::Vector2& translation, const Ogre::Vector2& direction);
 	Game::Polygon MakePolygon(const Game::Rectangle& rect, const Ogre::Vector2& translation);

src/GameObjects/Messaging.h

 	}
 
 	template<typename T>
-	T operator[](const std::string& key, const T& defaultValue) {
-		boost::any value = parameters[key];
-		T result;
-		try {
-			result = boost::any_cast<T>(value);
-		} catch (...) {
-			return defaultValue;
-		}
-
-		return result;
-	}
-
-	template<typename T>
 	void Set(const std::string& key, const T& value) {
 		parameters[key] = value;
 	}

src/GameObjects/PlayerModel.cpp

+/*
+ * PlayerModel.cpp
+ *
+ *  Created on: Oct 7, 2010
+ *      Author: crt
+ */
+
+#include "PlayerModel.h"
+
+namespace Game {
+namespace GameObjects {
+
+CPlayerModel::CPlayerModel()
+	: CMovableObject(),
+	  state(stFalling),
+	  score(0),
+	  speed(0,0),
+	  fGravity(90),
+	  fMaxJumpTime(0.5),
+	  fJumpAcceleration(30),
+	  fMinSpeed(60),
+	  fMaxSpeed(100),
+	  fAcceleration(25)
+{
+	this->SetAABBSize(Ogre::Vector2(6.0f, 9.0f));
+}
+
+PPlayerModel CPlayerModel::Create() {
+	CPlayerModel* obj = new CPlayerModel();
+	PPlayerModel objPtr(obj);
+	obj->self = objPtr;
+	return objPtr;
+}
+
+PLevelObject CPlayerModel::Copy() const {
+	CPlayerModel* copy = new CPlayerModel(*this);
+	PPlayerModel copyPtr(copy);
+	copy->self = copyPtr;
+	return copyPtr;
+}
+
+void CPlayerModel::AddPlayerListener(CPlayerModel::PListener listener) {
+	if (listener)
+		PlayerListeners.insert(listener);
+}
+
+void CPlayerModel::RemovePlayerListener(CPlayerModel::PListener listener) {
+	PlayerListeners.erase(listener);
+}
+
+
+void CPlayerModel::Update(float deltaTime) {
+	if (state == stOnGround)
+		speed.y = -fGravity * deltaTime;
+
+	if (state == stJumping) {
+		jumpTime += deltaTime;
+
+		if (jumpTime > fMaxJumpTime) {
+			SetState(stFalling);
+		}
+	}
+
+	if (state == stFalling) {
+		speed.y -= fGravity * deltaTime;
+	}
+
+	speed.x += fAcceleration * deltaTime;
+	if (speed.x > fMaxSpeed)
+		speed.x = fMaxSpeed;
+
+	if (state != stDead && state != stAtGoal) {
+		Ogre::Vector2 translation = deltaTime * speed;
+		Ogre::Vector2 actualTranslation = this->Move(translation);
+
+		if (approximatelyEqual(actualTranslation.x, 0.0f)) actualTranslation.x = 0.0f;
+		if (approximatelyEqual(actualTranslation.y, 0.0f)) actualTranslation.y = 0.0f;
+
+		if (state == stOnGround && actualTranslation.y < 0.0f) {
+			SetState(stFalling);
+		}
+
+		if (actualTranslation.x <= 0.0f) {
+			speed.x = fMinSpeed;
+		}
+
+		if (state != stOnGround) {
+			if (translation.y > 0.0f && actualTranslation.y <= 0.0f) {
+				speed.y = 0.0f;
+				SetState(stFalling);
+			}
+			if (translation.y < 0.0f && actualTranslation.y >= 0.0f) {
+				SetState(stOnGround);
+			}
+		}
+	}
+}
+
+void CPlayerModel::BeginJump() {
+	if (state == stOnGround) {
+		jumpTime = 0.0f;
+		speed.y = fJumpAcceleration;
+		SetState(stJumping);
+	}
+}
+
+void CPlayerModel::FinishJump() {
+	if (state == stJumping) {
+		SetState(stFalling);
+	}
+}
+
+void CPlayerModel::ReceiveMessage(const SMessage& message) {
+	//TODO
+}
+
+void CPlayerModel::SetState(CPlayerModel::PlayerState newState) {
+	if (state != newState) {
+		state = newState;
+		notifyStateChanged();
+	}
+}
+
+void CPlayerModel::notifyPositionChanged() {
+	CLevelObject::notifyPositionChanged();
+
+	for (PlayerListenerList::iterator it = PlayerListeners.begin(); it != PlayerListeners.end(); ++it) {
+		(*it)->PositionChanged(this);
+	}
+}
+
+void CPlayerModel::notifyStateChanged() {
+	for (PlayerListenerList::iterator it = PlayerListeners.begin(); it != PlayerListeners.end(); ++it) {
+		(*it)->StateChanged(this);
+	}
+	TEST_LOG("state change: " << this->state);
+}
+
+}
+}

src/GameObjects/PlayerModel.h

+/*
+ * PlayerModel.h
+ *
+ *  Created on: Oct 7, 2010
+ *      Author: crt
+ */
+
+#ifndef PLAYERMODEL_H_
+#define PLAYERMODEL_H_
+
+#include "LevelObjects.h"
+
+namespace Game {
+namespace GameObjects {
+
+class CPlayerModel;
+typedef boost::shared_ptr<CPlayerModel> PPlayerModel;
+
+class CPlayerModel : public CMovableObject {
+public:
+	class Listener {
+	public:
+		Listener() { }
+		virtual ~Listener() { }
+
+		virtual void PositionChanged(CPlayerModel*) { }
+		virtual void StateChanged(CPlayerModel*) { }
+	};
+	typedef boost::shared_ptr<Listener> PListener;
+
+	enum PlayerState { stFalling, stOnGround, stJumping, stDead, stAtGoal };
+public:
+	virtual ~CPlayerModel() { }
+
+	/** Factory Method */
+	static PPlayerModel Create();
+	/** Copy this object */
+	virtual PLevelObject Copy() const;
+
+	virtual void AddPlayerListener(CPlayerModel::PListener listener);
+	virtual void RemovePlayerListener(CPlayerModel::PListener listener);
+
+	/** Update State, Move Player ; Called every frame */
+	virtual void Update(float deltaTime);
+
+	/** Starts Jump; every Update adds delaTime until MaxJumpTime is reached */
+	virtual void BeginJump();
+
+	/** Finishes Jump before MaxJumpTime is reached */
+	virtual void FinishJump();
+
+	/** Implementation of IMessagingObject */
+	virtual void ReceiveMessage(const SMessage& message);
+
+	virtual PlayerState GetState() const { return state; }
+
+	virtual int GetScore() const { return score; }
+
+	virtual float GetSpeed() const { return speed.x; }
+
+	/** Set Gravity (units/second^2)
+		Default: 90.0*/
+	virtual void SetGravity(float g) { fGravity = g; }
+	virtual float GetGravity() { return fGravity; }
+
+	/** Set maximum Time the character should accelerate when jumping (seconds)
+	    Default: 1.0*/
+	virtual void SetMaxJumpTime(float time) { fMaxJumpTime = time; }
+	virtual float GetMaxJumpTime() { return fMaxJumpTime; }
+
+	/** Set Jump Acceleration (units/second^2)
+	    Default: 30.0*/
+	virtual void SetJumpAcceleration(float acceleration) { fJumpAcceleration = acceleration; }
+	virtual float GetJumpAcceleration() { return fJumpAcceleration; }
+
+	/** Set Speed and Acceleration
+	 *  Player starts with minSpeed, then accelerates upto maxspeed
+	 *  Speed is reset to minspeed whenever player hits wall */
+	virtual void SetSpeedLimits(float minSpeed, float maxSpeed, float acceleration) {
+		fMinSpeed = speed.x = minSpeed;
+		fMaxSpeed = maxSpeed;
+		fAcceleration = acceleration;
+	}
+
+protected:
+	CPlayerModel();
+
+	typedef std::set<CPlayerModel::PListener> PlayerListenerList;
+	PlayerListenerList PlayerListeners;
+
+	// state
+	PlayerState state;
+	int score;
+	Ogre::Vector2 speed;
+	float jumpTime;
+
+	// settings
+	float fGravity;
+	float fMaxJumpTime;
+	float fJumpAcceleration;
+	float fMinSpeed, fMaxSpeed;
+	float fAcceleration;
+
+	virtual void notifyStateChanged();
+	virtual void notifyPositionChanged();
+
+	void SetState(PlayerState newState);
+};
+
+}
+}
+
+#endif /* PLAYERMODEL_H_ */

src/GameObjects/PlayerView.cpp

+/*
+ * PlayerView.cpp
+ *
+ *  Created on: Oct 7, 2010
+ *      Author: crt
+ */
+
+#include "PlayerView.h"
+
+namespace Game {
+namespace GameObjects{
+
+CPlayerOgreView::CPlayerOgreView(PPlayerModel model)
+	: IOgreView(model),
+	  oEntity(NULL),
+	  fAnimationFadeSpeed(7.5),
+	  fAnimationTimer(0.0)
+{
+	// setup helper arrays
+	AnimationIDs.clear();
+	AnimationIDs.push_back(animNone);
+	AnimationIDs.push_back(animIdleTop);
+	AnimationIDs.push_back(animIdleBase);
+	AnimationIDs.push_back(animRunTop);
+	AnimationIDs.push_back(animRunBase);
+	AnimationIDs.push_back(animJumpStart);
+	AnimationIDs.push_back(animJumpLoop);
+	AnimationIDs.push_back(animJumpEnd);
+	AnimationTargets.clear();
+	AnimationTargets.push_back(atTop);
+	AnimationTargets.push_back(atBase);
+
+	Animations[animIdleBase] = "IdleBase";
+	Animations[animIdleTop] = "IdleTop";
+	Animations[animRunBase] = "RunBase";
+	Animations[animRunTop] = "RunTop";
+	Animations[animJumpStart] = "JumpStart";
+	Animations[animJumpLoop] = "JumpLoop";
+	Animations[animJumpEnd] = "JumpEnd";
+
+	SetupAnimations();
+}
+
+PPlayerOgreView CPlayerOgreView::Create(PPlayerModel model) {
+	CPlayerOgreView* obj = new CPlayerOgreView(model);
+	PPlayerOgreView objPtr(obj);
+	model->AddPlayerListener(objPtr);
+	obj->self = objPtr;
+	return objPtr;
+}
+
+POgreView CPlayerOgreView::Copy(PPlayerModel model) {
+	CPlayerOgreView* copy = new CPlayerOgreView(model);
+	PPlayerOgreView copyPtr( copy );
+	copy->self = copyPtr;
+	model->AddPlayerListener(copyPtr);
+	copy->fAnimationFadeSpeed = this->fAnimationFadeSpeed;
+	return copyPtr;
+}
+
+
+void CPlayerOgreView::SetupAnimations() {
+	for (int i=0; i < AnimationIDs.size(); ++i) {
+		AnimationID id = AnimationIDs[i];
+
+		// set default values
+		AnimationStates[id] = NULL;
+		AnimationFadeIn[id] = false;
+		AnimationFadeOut[id] = false;
+
+		// dont setup animNone
+		if (id == animNone)
+			continue;
+
+		// try to get Ogre Animation State by name
+		if (oEntity) {
+			std::string animName = Animations[id];
+			if (animName != "") {
+				Ogre::AnimationState* animState = oEntity->getAnimationState(animName);
+				if (animState) {
+					AnimationStates[id] = animState;
+					animState->setLoop(true);
+					animState->setEnabled(false);
+				}
+			}
+		}
+	}
+
+	// rest all animation targets
+	for (int i=0; i < AnimationTargets.size(); ++i) {
+		AnimationTarget target = AnimationTargets[i];
+		SetAnimation(target, animNone);
+	}
+}
+
+void CPlayerOgreView::SetAnimation(AnimationTarget target, AnimationID animation, bool reset) {
+	// fade old animation out
+	if (currentAnimations[target] != animNone) {
+		AnimationFadeIn[currentAnimations[target]] = false;
+		AnimationFadeOut[currentAnimations[target]] = true;
+	}
+
+	currentAnimations[target] = animation;
+
+	if (animation != animNone) {
+		// fade new animation in
+		if (AnimationStates[animation] != NULL) {
+			AnimationStates[animation]->setEnabled(true);
+			AnimationStates[animation]->setWeight(0);
+			if (reset)
+				AnimationStates[animation]->setTimePosition(0);
+		}
+
+		AnimationFadeIn[animation] = true;
+		AnimationFadeOut[animation] = false;
+	}
+}
+
+void CPlayerOgreView::fadeAnimations(float deltaTime) {
+	for (int i=0; i < AnimationIDs.size(); ++i) {
+		AnimationID id = AnimationIDs[i];
+
+		if (AnimationStates[id] == NULL)
+			continue;
+
+		if (AnimationFadeIn[id]) {
+			Ogre::Real newWeight = AnimationStates[id]->getWeight() + deltaTime * fAnimationFadeSpeed;
+			AnimationStates[id]->setWeight(Ogre::Math::Clamp<Ogre::Real>(newWeight, 0, 1));
+			if (newWeight >= 1)
+				AnimationFadeIn[id] = false;
+		} else if (AnimationFadeOut[id]) {
+			Ogre::Real newWeight = AnimationStates[id]->getWeight() - deltaTime * fAnimationFadeSpeed;
+			AnimationStates[id]->setWeight(Ogre::Math::Clamp<Ogre::Real>(newWeight, 0, 1));
+			if (newWeight <= 0)
+			{
+				AnimationStates[id]->setEnabled(false);
+				AnimationFadeOut[id] = false;
+			}
+		}
+	}
+}
+
+void CPlayerOgreView::UpdateGeometry() {
+	PLevelObject model = Model.lock();
+	Ogre::Vector2 position(0,0);
+	if (model) {
+		position = model->GetPosition();
+	}
+
+	if (oScene) {
+		if (!oParentNode) {
+			oParentNode = oScene->getRootSceneNode();
+		}
+		if (!oNode) {
+			oNode = oParentNode->createChildSceneNode(Ogre::Vector3::ZERO);
+		}
+		if (!oEntity) {
+			oEntity = oScene->createEntity("sinbad.mesh");
+			oNode->attachObject(oEntity);
+			oEntity->getSkeleton()->setBlendMode(Ogre::ANIMBLEND_CUMULATIVE);
+			oEntity->setCastShadows(true);
+			oEntity->getAnimationState("HandsRelaxed")->setLoop(true);
+			oEntity->getAnimationState("HandsRelaxed")->setEnabled(true);
+			SetupAnimations();
+		}
+		oNode->setPosition(Ogre::Vector3(0.0f, position.y, position.x));
+	}
+}
+
+void CPlayerOgreView::SetOgreScene(Ogre::SceneManager* ogreScene, Ogre::SceneNode* ogreNode) {
+	this->oScene = ogreScene;
+	this->oParentNode = ogreNode;
+	this->oNode = NULL;
+	this->oEntity = NULL;
+	UpdateGeometry();
+}
+
+void CPlayerOgreView::PositionChanged(CPlayerModel*) {
+	UpdateGeometry();
+}
+
+void CPlayerOgreView::StateChanged(CPlayerModel*) {
+	PLevelObject model = Model.lock();
+	if (!model) return;
+
+	if (!oEntity) return;
+
+	PPlayerModel player = boost::static_pointer_cast<CPlayerModel>(model);
+	CPlayerModel::PlayerState newState = player->GetState();
+
+	if (newState == CPlayerModel::stFalling) {
+		if (currentAnimations[atTop] != animNone) {
+			SetAnimation(atTop, animNone);
+		}
+		if (currentAnimations[atBase] != animJumpLoop) {
+			SetAnimation(atBase, animJumpLoop, true);
+		}
+	}
+
+	if (newState == CPlayerModel::stOnGround) {
+		if (currentAnimations[atBase] != animRunBase) {
+			if (currentAnimations[atBase] != animJumpEnd) {
+				SetAnimation(atBase, animJumpEnd, true);
+				fAnimationTimer = 0;
+			} else if (fAnimationTimer >= AnimationStates[animJumpEnd]->getLength()) {
+				SetAnimation(atTop, animRunTop);
+				SetAnimation(atBase, animRunBase);
+			}
+		}
+	}
+
+	if (newState == CPlayerModel::stJumping) {
+		if (currentAnimations[atBase] != animJumpLoop) {
+			if (currentAnimations[atBase] != animJumpStart) {
+				SetAnimation(atBase, animJumpStart, true);
+				fAnimationTimer = 0;
+			} else if (fAnimationTimer >= AnimationStates[animJumpStart]->getLength()) {
+				SetAnimation(atBase, animJumpLoop, true);
+			}
+		}
+	}
+}
+
+void CPlayerOgreView::Update(float deltaTime) {
+	fAnimationTimer += deltaTime;
+
+	if (!oEntity)
+		return;
+
+	if (currentAnimations[atBase] == animJumpStart) {
+		if (fAnimationTimer >= AnimationStates[animJumpStart]->getLength()) {
+			SetAnimation(atBase, animJumpLoop, true);
+		}
+	}
+
+	if (currentAnimations[atBase] == animJumpEnd) {
+		if (fAnimationTimer >= AnimationStates[animJumpEnd]->getLength()) {
+			SetAnimation(atBase, animRunBase);
+			SetAnimation(atTop, animRunTop);
+		}
+	}
+
+	for (int i=0; i < AnimationTargets.size(); ++i) {
+		AnimationTarget target = static_cast<AnimationTarget>(AnimationTargets[i]);
+
+		if (currentAnimations[target] != animNone) {
+			if (AnimationStates[currentAnimations[target]] != NULL) {
+				AnimationStates[currentAnimations[target]]->addTime(deltaTime);
+			}
+		}
+	}
+
+	fadeAnimations(deltaTime);
+}
+
+}
+}

src/GameObjects/PlayerView.h

+/*
+ * PlayerView.h
+ *
+ *  Created on: Oct 7, 2010
+ *      Author: crt
+ */
+
+#ifndef PLAYERVIEW_H_
+#define PLAYERVIEW_H_
+
+#include "OgreViews.h"
+#include "PlayerModel.h"
+
+namespace Game {
+namespace GameObjects {
+
+class CPlayerOgreView;
+typedef boost::shared_ptr<CPlayerOgreView> PPlayerOgreView;
+typedef boost::weak_ptr<CPlayerOgreView> WPlayerOgreView;
+
+class CPlayerOgreView : public IOgreView, public CPlayerModel::Listener {
+public:
+	virtual ~CPlayerOgreView() { }
+
+	static PPlayerOgreView Create(PPlayerModel model);
+
+	virtual POgreView Copy(PPlayerModel model);
+
+	/** Implementation of IOgreView */
+	virtual void SetOgreScene(Ogre::SceneManager* ogreScene, Ogre::SceneNode* ogreNode = NULL);
+
+	/** Set Animation Crossfade Speed (%weight/second)
+		Default: 7.5*/
+	virtual void SetAnimationFadeSpeed(float fadespeed) { fAnimationFadeSpeed = fadespeed; }
+	virtual float GetAnimationFadeSpeed() { return fAnimationFadeSpeed; }
+
+	/** Implementation of IOgreView */
+	virtual bool IsUpdateable() const { return true; }
+
+	/** Implementation of IOgreView */
+	virtual void Update(float deltaTime);
+
+	/** Implementation of CPlayerModel::Listener */
+	virtual void PositionChanged(CPlayerModel*);
+
+	/** Implementation of CPlayerModel::Listener */
+	virtual void StateChanged(CPlayerModel*);
+
+protected:
+	CPlayerOgreView(PPlayerModel model);
+
+	POgreView Copy(PLevelObject model) { return POgreView(); }
+
+	enum AnimationID
+	{
+		animNone,
+		animIdleTop,
+		animIdleBase,
+		animRunTop,
+		animRunBase,
+		animJumpStart,
+		animJumpLoop,
+		animJumpEnd
+	};
+	enum AnimationTarget
+	{
+		atTop,
+		atBase
+	};
+
+	typedef std::map<AnimationID, std::string> AnimationMap;
+	typedef std::map<AnimationID, Ogre::AnimationState*> AnimationStateMap;
+	typedef std::map<AnimationTarget, AnimationID> AnimationTargetMap;
+
+	// helper arrays
+	std::vector<AnimationID> AnimationIDs;
+	std::vector<AnimationTarget> AnimationTargets;
+
+	// stores names for each animation id
+	AnimationMap Animations;
+
+	// Ogre Animation States
+	AnimationStateMap AnimationStates;
+
+	// Defines which Animations are currently fading in or out
+	std::map<AnimationID, bool> AnimationFadeIn;
+	std::map<AnimationID, bool> AnimationFadeOut;
+
+	AnimationTargetMap currentAnimations;
+
+	// pointer to ogre entity
+	Ogre::Entity* oEntity;
+
+	float fAnimationFadeSpeed;
+	float fAnimationTimer;
+
+	void UpdateGeometry();
+	void SetupAnimations();
+	void SetAnimation(AnimationTarget target, AnimationID animation, bool reset = false);
+	void fadeAnimations(float deltaTime);
+};
+
+}
+}
+
+#endif /* PLAYERVIEW_H_ */

src/States/CEditorState.cpp

 	goCamera->Yaw(-90);
 	goCamera->MoveToGoal();
 
-	goHero = GameObjects::CSindbadCharacter::Create(ogreScene, "SinbadBody");
-	goHero->SetPosition(Ogre::Vector3::UNIT_Y * 5);
-	goHero->SetSpeed(0);
+//	goHero = GameObjects::CSindbadCharacter::Create(ogreScene, "SinbadBody");
+//	goHero->SetPosition(Ogre::Vector3::UNIT_Y * 5);
+//	goHero->SetSpeed(0);
 	Ogre::Rectangle nullRect;
 	nullRect.left = nullRect.top = nullRect.right = nullRect.bottom = 0.0f;
-	goHero->SetConstraints(nullRect);
+//	goHero->SetConstraints(nullRect);
 
 
 	goHud = GameObjects::COverlay::Create("Editor/HUD", "hud", 100);
 
 void CEditorState::Stop() {
 	goHud.reset();
-	goHero.reset();
+//	goHero.reset();
 	goCamera.reset();
 
 	Ogre::OverlayManager::getSingleton().destroy(oCursorLayer);
 	goCamera->SetPivot(vPivot);
 	goCamera->Update(CTimerTask::dT);
 
-	goHero->Update(CTimerTask::dT);
+//	goHero->Update(CTimerTask::dT);
 }
 
 void CEditorState::ClearLevelData() {

src/States/CEditorState.h

 #include "../GameObjects/ObjectType.h"
 #include "../GameObjects/LevelObjects.h"
 #include "../GameObjects/OgreViews.h"
-#include "../GameObjects/CSindbadCharacter.h"
+#include "../GameObjects/PlayerModel.h"
+#include "../GameObjects/PlayerView.h"
 #include "Ogre.h"
 #include "boost/smart_ptr.hpp"
 #include <math.h>
 	typedef std::vector<GameObjects::POgreBoundsView> OgreBoundsViewList;
 	typedef std::map<GameObjects::POgreEntityView, GameObjects::POgreBoundsView> OgreViewBoundsMap;
 	typedef std::pair<GameObjects::PLevelObject, GameObjects::POgreEntityView> ObjectViewPair;
-	typedef std::map<GameObjects::PLevelData, ObjectViewPair> ObjectPairMap;
+	typedef std::map<GameObjects::PLevelObject, ObjectViewPair> ObjectPairMap;
 	typedef std::map<GameObjects::POgreEntityView, ObjectViewPair> ViewObjectViewPairMap;
 	typedef std::map<std::string, ObjectViewPair> StringObjectPairMap;
 	typedef std::deque<ObjectViewPair> OgreObjectViewPairQueue;
 
 	GameObjects::POverlay goHud;
 	GameObjects::PPivotCamera goCamera;
-	GameObjects::PSindbadCharacter goHero;
+//	GameObjects::PSindbadCharacter goHero;
 
 	Ogre::Overlay* oCursorLayer;
 	Ogre::OverlayContainer* oCursor;

src/States/CGameState.cpp

 	light->setShadowFarDistance(500);
 	light->setShadowNearClipDistance(0.1);
 
-/*
-	Ogre::Entity* dragon = ogreScene->createEntity("dragon.mesh" );
-	dragonNode = ogreScene->getRootSceneNode()->createChildSceneNode(Ogre::Vector3(-60,-30, 0));
-	dragonNode->attachObject( dragon );
-	dragonNode->scale(0.5, 0.5, -0.5);
-
-	dragonNode->rotate(Ogre::Vector3::UNIT_X, Ogre::Degree(45), Ogre::Node::TS_LOCAL);
-*/
-
-
 	goLevel = GameObjects::CLevelData::Create();
 
 	GameObjects::CXMLReader xmlReader;
 
 	goLevel->Draw(ogreScene);
 
-	goHero = GameObjects::CSindbadCharacter::Create(ogreScene, "SinbadBody");
-	goHero->SetPosition(Ogre::Vector3::UNIT_Y * 5 /*+ Ogre::Vector3::UNIT_Z*(-45)*/);
-	goHero->SetSpeed(CSettingsManager::GetSingleton().get<float>("Game", "speed", 50.0f));
-	goHero->SetGravity(CSettingsManager::GetSingleton().get<float>("Game", "gravity", 90.0f));
-	goHero->SetJumpAcceleration(CSettingsManager::GetSingleton().get<float>("Game", "jump", 30.0f));
-	goHero->SetMaxJumpTime(CSettingsManager::GetSingleton().get<float>("Game", "jumpTime", 1.0f));
-
-	fAcceleration = CSettingsManager::GetSingleton().get<float>("Game", "acceleration", 1.0f);
-
-	goHero->SetBounds(1.5f, 4.0f, 1.5f, 5.0f);
-	goHero->SetLevel(goLevel);
-
 	goHud = GameObjects::COverlay::Create("Main/HUD", "hud", 100);
-	//goHud->SetValue("Score", 0);
-	goHud->SetText("Score", "Test 1234");
+	goHud->SetValue<int>("Score", 0);
 
 	goCamera = GameObjects::CPivotCamera::Create(ogreCamera, CSettingsManager::GetSingleton().get<float>("Camera", "distance", 15.0f));
-	goCamera->SetPivot(goHero->GetPosition());
+	Ogre::Vector2 pos = goLevel->GetPlayer()->GetPosition();
+	goCamera->SetPivot(Ogre::Vector3(0.0f, pos.y, pos.x));
 	goCamera->Zoom(CSettingsManager::GetSingleton().get<float>("Camera", "zoom", 5.0f));
 	goCamera->Yaw(CSettingsManager::GetSingleton().get<float>("Camera", "yaw", -90));
 	goCamera->SetSpeed(CSettingsManager::GetSingleton().get<float>("Camera", "speed", 9.0f));
 	goCamera->MoveToGoal();
 	//goCamera->GetCameraNode()->attachObject(light);
 
-	Ogre::SceneNode* rNode = goHero->GetSceneNode()->createChildSceneNode();
+	Ogre::SceneNode* rNode = goLevel->GetPlayerView()->GetOgreNode()->createChildSceneNode();
 	rNode->translate(0,250,150);
 	rNode->attachObject(pSys);
 	// Fast-forward the rain so it looks more natural
 
 void CGameState::Stop() {
 	goHud.reset();
-	goHero.reset();
 	goCamera.reset();
 	goLevel.reset();
 
 }
 
 void CGameState::keyReleased( const OIS::KeyEvent &e ) {
-	if (e.key == OIS::KC_RIGHT || e.key == OIS::KC_D) goHero->SetSpeed(0);
-	else if (e.key == OIS::KC_SPACE) goHero->FinishJump();
+	if (e.key == OIS::KC_SPACE) goLevel->GetPlayer()->FinishJump();
 	else if (e.key == OIS::KC_F) bRotateCamera = false;
 	else if (e.key == OIS::KC_ESCAPE) CStateManager::GetSingleton().ChangeState("MainMenu");
 	else if (e.key == OIS::KC_RETURN) CStateManager::GetSingleton().ChangeState("MainMenu");
 }
 
 void CGameState::keyPressed( const OIS::KeyEvent &e ) {
-	if (e.key == OIS::KC_RIGHT || e.key == OIS::KC_D) goHero->SetSpeed(15);
-	else if (e.key == OIS::KC_F) bRotateCamera = true;
-	else if (e.key == OIS::KC_SPACE) goHero->BeginJump();
+	if (e.key == OIS::KC_F) bRotateCamera = true;
+	else if (e.key == OIS::KC_SPACE) goLevel->GetPlayer()->BeginJump();
 
 	if (e.key == OIS::KC_L)
 		ogreScene->setAmbientLight(Ogre::ColourValue(0.6, 0.6, 0.8));
 
 	float deltaTime = ((float)(thisFrameIndex-lastFrameIndex))/1000.0f;
 
+	goLevel->Update(deltaTime);
+
 	if (bLightning && lLightningStarted+200 <= thisFrameIndex) {
 		ogreScene->setAmbientLight(Ogre::ColourValue(0.1, 0.1, 0.1));
 		bLightning = false;
 
 	}
 
-/*
-	Ogre::Rectangle heroRect;
-	heroRect.left = goHero->GetPosition().z - 1.5f;
-	heroRect.right = goHero->GetPosition().z + 1.5f + CTimerTask::dT * goHero->GetSpeed();
-	heroRect.top = goHero->GetPosition().y + 4.0f;
-	heroRect.bottom = goHero->GetPosition().y - 5.0f;
-
-	goHero->SetConstraints(goLevel->Collision(heroRect, 10.0f));
-*/
-
-	goHero->SetSpeed(goHero->GetSpeed() + deltaTime * fAcceleration);
-	goHero->Update(deltaTime);
-
-//	dragonNode->translate(0,0,goHero->GetSpeed() * CTimerTask::dT * 1.01f, Ogre::Node::TS_WORLD);
-
-	goCamera->SetPivot(goHero->GetPosition());
+	Ogre::Vector2 pos = goLevel->GetPlayer()->GetPosition();
+	goCamera->SetPivot(Ogre::Vector3(0.0f, pos.y, pos.x));
 	goCamera->Update(deltaTime);
 
 	goHud->SetValue<float>("Score", CVideoTask::ogreRenderWindow->getAverageFPS());
 
-	// rotate sky
-	//fSkyRotation += goHero->GetSpeed()*CTimerTask::dT;
-	//ogreScene->setSkyBox(true, "Textures/SkyBox", 5000, true, Ogre::Quaternion(Ogre::Degree(fSkyRotation), Ogre::Vector3::UNIT_Y));
-
-//	goHud->SetText("Score", this->iScore);
-
-	//if (goHero->GetPosition().z > 55.0f) {
-	//	GameOver();
-	//}
 }
 
 void CGameState::GameOver() {

src/States/CGameState.h

 #include "../Tasks/CTimerTask.h"
 #include "../Tasks/CVideoTask.h"
 #include "../Core/CStateManager.h"
-#include "../GameObjects/CSindbadCharacter.h"
 #include "../GameObjects/CPivotCamera.h"
 #include "../GameObjects/COverlay.h"
 #include "../GameObjects/CLevelData.h"
 	bool bSkipOneFrame;
 
 	GameObjects::POverlay goHud;
-	GameObjects::PSindbadCharacter goHero;
 	GameObjects::PPivotCamera goCamera;
 	GameObjects::PLevelData goLevel;
 

src/States/CMainMenuState.cpp

 		ogreLight->setPosition(-10, 40, 20);
 		ogreLight->setSpecularColour(Ogre::ColourValue::White);
 
-		character = GameObjects::CSindbadCharacter::Create(ogreScene, "SindbadBody");
-		character->SetSpeed(1.0f);
-		character->SetPosition(Ogre::Vector3::UNIT_Y * 2);
-
 		ogreCamera->setNearClipDistance(0.1);
 		ogreCamera->setFarClipDistance(100);
 		ogreCamera->setPosition(0,2,15);
 
 void CMainMenuState::Stop() {
 	overlay.reset();
-	character.reset();
+
 
 	ogreScene->clearScene();
 	CVideoTask::ogreRoot->destroySceneManager(ogreScene);
 }
 
 void CMainMenuState::Update() {
-	character->Update(CTimerTask::dT);
 
 	// follow character
 	ogreCamera->setPosition(ogreCamera->getPosition() + Ogre::Vector3::UNIT_Z*CTimerTask::dT);

src/States/CMainMenuState.h

 #include "../Core/CStateManager.h"
 #include "../Core/CTaskManager.h"
 #include "../Core/CLog.h"
-#include "../GameObjects/CSindbadCharacter.h"
 #include "../GameObjects/COverlay.h"
 #include "CGameState.h"
 
 
 	Ogre::Light* ogreLight;
 
-	GameObjects::PSindbadCharacter character;
 	GameObjects::POverlay overlay;
 
 

test/CMakeLists.txt

 	../src/Core/CSettingsManager.cpp	
 	../src/GameObjects/LevelObjects.cpp
 	../src/GameObjects/OgreViews.cpp
+	../src/GameObjects/PlayerModel.cpp
+	../src/GameObjects/PlayerView.cpp
 	../src/GameObjects/CLevelData.cpp	
 	../src/GameObjects/Geometry.cpp	
 )

test/CollisionTest.cpp

 #include "test.h"
 #include "../src/GameObjects/CLevelData.h"
 #include "../src/GameObjects/LevelObjects.h"
+#include "../src/Core/CSettingsManager.h"
 #include "Ogre.h"
 
 using namespace Ogre;
 
 BOOST_AUTO_TEST_CASE( collision_test )
 {
+	new Game::CSettingsManager();
+
 	// create 2x2x2 cube with center in origin
 	Vector2 position(0,0);
 	Vector2 size(2,2);
 
 	PMovableObject collider = CMovableObject::Create();
 
-	PLevelData leveldata(new CLevelData());
+	PLevelData leveldata = CLevelData::Create();
 	leveldata->InsertObject(cube, otStatic);
 
 	collider->SetParent(leveldata);
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.