Added player stats. Added players to level. Respawn logic in level.

This commit is contained in:
Linda Andersson 2014-02-25 11:46:05 +01:00 committed by Dander7BD
parent ba61838703
commit 4d967b995d
11 changed files with 167 additions and 125 deletions

View File

@ -108,6 +108,7 @@ Game::PlayerData* Game::CreatePlayer()
this->players[insert] = new PlayerData(freeID, 0); // user constructor with objectID and teamID
this->players[insert]->player->GetRigidBody()->SetSubscription(Game::PhysicsOnMove);
this->level->AddPlayerToGame(this->players[insert]);
return this->players[insert];
}
@ -128,6 +129,9 @@ void Game::CreateTeam()
bool Game::NewFrame()
{
// HACK need dynamic delta time
this->level->Update(this->frameTime);
for (unsigned int i = 0; i < this->players.Size(); i++)
{
if(this->players[i] && this->players[i]->player) this->players[i]->player->BeginFrame();
@ -202,4 +206,3 @@ void Game::PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer<ICustomBody>
{
if(gameInstance.onDisableFnc) gameInstance.onDisableFnc(0, 0);
}

View File

@ -45,7 +45,7 @@ namespace GameLogic
ObjectSpecialType GetObjectType() const override;
void Inactivate() override;
void Release() override;
Player* GetPlayer();
Player *player;
};
@ -63,7 +63,8 @@ namespace GameLogic
int getNrOfDynamicObj()const override;
IObjectData* GetObjectAt(int ID) const override;
void GetAllDynamicObjects(Utility::DynamicMemory::DynamicArray<IObjectData*>& mem) const override;
void Update(float deltaTime);
void AddPlayerToGame(IPlayerData *player);
Level *level;
};
@ -83,13 +84,13 @@ namespace GameLogic
void SetHpSubscription(GameEvent::ObjectHpFunction functionPointer) override;
void SetRespawnSubscription(GameEvent::ObjectRespawnedFunction functionPointer) override;
void SetDeadSubscription(GameEvent::ObjectDeadFunction functionPointer) override;
bool Initiate() override;
float GetFrameTime() const;
static void PhysicsOnMove(const Oyster::Physics::ICustomBody *object);
static void PhysicsOnDestroy(::Utility::DynamicMemory::UniquePointer<Oyster::Physics::ICustomBody> proto);
static void PhysicsOnDead(const Oyster::Physics::ICustomBody *object);
Utility::DynamicMemory::DynamicArray<PlayerData*> players;
LevelData* level;

View File

@ -117,8 +117,10 @@ namespace GameLogic
class ILevelData :public IObjectData
{
public:
virtual void Update(float deltaTime) = 0;
virtual int getNrOfDynamicObj()const = 0;
virtual IObjectData* GetObjectAt(int ID) const = 0;
virtual void AddPlayerToGame(IPlayerData *player) = 0;
virtual void GetAllDynamicObjects(Utility::DynamicMemory::DynamicArray<IObjectData*>& destMem) const = 0;
};

View File

@ -20,7 +20,8 @@ namespace GameLogic
PLAYER_STATE_WALKING = 1,
PLAYER_STATE_IDLE = 2,
PLAYER_STATE_DEAD = 4,
PLAYER_STATE_INVALID = 8,
PLAYER_STATE_DIED = 8,
PLAYER_STATE_INVALID = 16,
};
enum WEAPON_FIRE

View File

@ -54,9 +54,17 @@ IObjectData* Game::LevelData::GetObjectAt(int ID) const
void Game::LevelData::GetAllDynamicObjects(Utility::DynamicMemory::DynamicArray<IObjectData*>& mem) const
{
mem.Resize(level->dynamicObjects.Size());
for(int i = 0; i < (int)level->dynamicObjects.Size(); i++)
mem.Resize(level->GetDynamicObject().Size());
for(int i = 0; i < (int)level->GetDynamicObject().Size(); i++)
{
mem[i] = level->dynamicObjects[i];
mem[i] = level->GetDynamicObject()[i];
}
}
void Game::LevelData::Update(float deltaTime)
{
this->level->Update(deltaTime);
}
void Game::LevelData::AddPlayerToGame(IPlayerData *player)
{
this->level->AddPlayerToGame(((PlayerData*)player)->GetPlayer());
}

View File

@ -102,3 +102,7 @@ void Game::PlayerData::Release()
{
this->player->ReleaseDynamicObject();
}
Player* Game::PlayerData::GetPlayer()
{
return this->player;
}

View File

@ -12,7 +12,7 @@
using namespace GameLogic;
using namespace Utility::DynamicMemory;
using namespace Oyster::Physics;
using namespace Oyster::Math;
Level::Level(void)
{
@ -69,7 +69,7 @@ Object* Level::CreateGameObj(ObjectHeader* obj, ICustomBody* rigidBody)
break;
case ObjectSpecialType_RedExplosiveBox:
{
Oyster::Math::Float dmg = 90;
Oyster::Math::Float dmg = 120;
Oyster::Math::Float force = 500;
Oyster::Math::Float radie = 3;
gameObj = new ExplosiveCrate(rigidBody, (ObjectSpecialType)obj->specialTypeID, objID++, dmg, force, radie);
@ -393,7 +393,20 @@ void Level::AddPlayerToTeam(Player *player, int teamID)
{
this->teamManager.AddPlayerToTeam(player,teamID);
}
void Level::AddPlayerToGame(Player *player)
{
this->playerObjects.Push(player);
}
void Level::RemovePlayerFromGame(Player *player)
{
for(int i = 0; i < (int)this->playerObjects.Size(); i++)
{
if ((Player*)this->playerObjects[i] == player)
{
//this->playerObjects[i].
}
}
}
void Level::CreateTeam(int teamSize)
{
this->teamManager.CreateTeam(teamSize);
@ -401,9 +414,29 @@ void Level::CreateTeam(int teamSize)
void Level::RespawnPlayer(Player *player)
{
this->teamManager.RespawnPlayerRandom(player);
}
//this->teamManager.RespawnPlayerRandom(player);
Float3 spawnPoint = spawnPoints[0];
player->Respawn(spawnPoint);
}
void Level::Update(float deltaTime)
{
// update lvl-things
for(int i = 0; i < (int)this->playerObjects.Size(); i++)
{
if (this->playerObjects[i]->GetState() == PLAYER_STATE::PLAYER_STATE_DEAD)
{
// true when timer reaches 0
if(this->playerObjects[i]->deathTimerTick(deltaTime))
RespawnPlayer(this->playerObjects[i]);
}
else if (this->playerObjects[i]->GetState() == PLAYER_STATE::PLAYER_STATE_DIED)
{
this->playerObjects[i]->setDeathTimer(DEATH_TIMER);
((Game*)&Game::Instance())->onDeadFnc(this->playerObjects[i], DEATH_TIMER); // add killer ID
}
}
}
int Level::getNrOfDynamicObj()
{
return this->dynamicObjects.Size();
@ -417,10 +450,23 @@ Object* Level::GetObj( int ID) const
}
return NULL;
}
void Level::PhysicsOnMoveLevel(const ICustomBody *object)
{
// function call from physics update when object was moved
Object* temp = (Object*)object->GetCustomTag();
((Game*)&Game::Instance())->onMoveFnc(temp);
}
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<Player>> Level::GetPlayers()
{
return this->playerObjects;
}
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<StaticObject>> Level::GetStaticObjects()
{
return this->staticObjects;
}
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<DynamicObject>> Level::GetDynamicObject()
{
return this->dynamicObjects;
}

View File

@ -16,6 +16,7 @@
#include "DynamicArray.h"
#include "LevelLoader.h"
const int DEATH_TIMER = 5;
namespace GameLogic
{
@ -48,7 +49,8 @@ namespace GameLogic
* @param teamID: ArrayPos of the team you want to add the player to
********************************************************/
void AddPlayerToTeam(Player *player, int teamID);
void AddPlayerToGame(Player *player);
void RemovePlayerFromGame(Player *player);
/********************************************************
* Respawns a player on a random teammate
@ -64,13 +66,21 @@ namespace GameLogic
********************************************************/
static Oyster::Physics::ICustomBody::SubscriptMessage LevelCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss);
void Update(float deltaTime);
int getNrOfDynamicObj();
Object* GetObj( int ID ) const;
static void PlayerDied( Player* player );
static void PhysicsOnMoveLevel(const Oyster::Physics::ICustomBody *object);
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<Player>> GetPlayers();
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<StaticObject>> GetStaticObjects();
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<DynamicObject>> GetDynamicObject();
//private:
private:
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<Player>> playerObjects;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<Player>> deadPlayerObjects;
TeamManager teamManager;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<StaticObject>> staticObjects;
Utility::DynamicMemory::DynamicArray<Utility::DynamicMemory::SmartPointer<DynamicObject>> dynamicObjects;

View File

@ -11,36 +11,17 @@ const float KEY_TIMER = 0.03f;
Player::Player()
:DynamicObject()
{
Player::initPlayerData();
this->teamID = -1;
}
Player::Player(Oyster::Physics::ICustomBody *rigidBody, void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, int teamID)
:DynamicObject(rigidBody, EventOnCollision, type, objectID)
{
weapon = new Weapon(2,this);
AffectedObjects.Reserve(15);
this->life = 100;
Player::initPlayerData();
this->teamID = teamID;
this->playerState = PLAYER_STATE_IDLE;
this->lookDir = Oyster::Math::Float3(0,0,-1);
key_forward = 0;
key_backward = 0;
key_strafeRight = 0;
key_strafeLeft = 0;
key_jump = 0;
invincibleCooldown = 0;
this->deathTimeLeft = 0;
this->deathTime = 5;
this->previousPosition = Oyster::Math::Float3(0,0,0);
this->moveDir = Oyster::Math::Float3(0,0,0);
this->moveSpeed = 100;
this->previousMoveSpeed = Oyster::Math::Float3(0,0,0);
this->rotationUp = 0;
}
Player::Player(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustomBody::SubscriptMessage (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, int teamID)
@ -48,27 +29,8 @@ Player::Player(Oyster::Physics::ICustomBody *rigidBody, Oyster::Physics::ICustom
{
weapon = new Weapon(2,this);
AffectedObjects.Reserve(15);
this->life = 100;
Player::initPlayerData();
this->teamID = teamID;
this->playerState = PLAYER_STATE_IDLE;
this->lookDir = Oyster::Math::Float3(0,0,-1);
key_forward = 0;
key_backward = 0;
key_strafeRight = 0;
key_strafeLeft = 0;
key_jump = 0;
invincibleCooldown = 0;
this->deathTimeLeft = 0;
this->deathTime = 5;
this->previousPosition = Oyster::Math::Float3(0,0,0);
this->moveDir = Oyster::Math::Float3(0,0,0);
this->moveSpeed = 20;
this->previousMoveSpeed = Oyster::Math::Float3(0,0,0);
this->rotationUp = 0;
}
Player::~Player(void)
@ -79,10 +41,29 @@ Player::~Player(void)
weapon = NULL;
}
}
void Player::initPlayerData()
{
this->playerStats.hp = MAX_HP;
this->playerStats.movementSpeed = BASIC_SPEED;
this->playerScore.killScore = 0;
this->playerScore.deathScore = 0;
this->playerState = PLAYER_STATE_IDLE;
this->lookDir = Oyster::Math::Float3(0,0,-1);
this->key_forward = 0;
this->key_backward = 0;
this->key_strafeRight = 0;
this->key_strafeLeft = 0;
this->key_jump = 0;
this->invincibleCooldown = 0;
this->deathTimer = 0;
this->rotationUp = 0;
}
void Player::BeginFrame()
{
if( this->playerState != PLAYER_STATE_DEAD)
if( this->playerState != PLAYER_STATE_DEAD && PLAYER_STATE_DIED)
{
weapon->Update(0.002f);
@ -117,7 +98,7 @@ void Player::BeginFrame()
// Walking data
Oyster::Math::Float3 walkDirection = Oyster::Math::Float3(0.0, 0.0, 0.0);
Oyster::Math::Float walkSpeed = this->moveSpeed*0.2f;
Oyster::Math::Float walkSpeed = this->playerStats.movementSpeed*0.2f;
// Check for input
if(key_forward > 0.001)
@ -199,36 +180,15 @@ void Player::BeginFrame()
if(this->rigidBody->GetLambda() < 0.9f)
{
Oyster::Math::Float3 up = this->rigidBody->GetState().centerPos.GetNormalized();
this->rigidBody->ApplyImpulse(up*this->rigidBody->GetState().mass*20);
this->rigidBody->ApplyImpulse(up*this->rigidBody->GetState().mass * 20);
this->playerState = PLAYER_STATE::PLAYER_STATE_JUMPING;
}
}
}
else
{
// player is dead
// TODO move this logic to lvl
this->deathTimeLeft -= gameInstance->GetFrameTime();
if( this->deathTimeLeft <= 0)
{
Respawn( Oyster::Math::Float3( -50, 180, 0));
}
}
}
void Player::EndFrame()
{
//check if there are any objects that can be removed from the AffectedObjects list
for(int i = 0; i < this->AffectedObjects.Size(); i++)
{
if(this->AffectedObjects[i] && (this->AffectedObjects[i]->GetRigidBody()->GetState().previousVelocity).GetMagnitude() <= 0.1f)
{
this->AffectedObjects[i]->RemoveAffectedBy();
this->AffectedObjects.Remove(i);
}
}
}
void Player::Move(const PLAYER_MOVEMENT &movement)
@ -283,12 +243,10 @@ void Player::Respawn(Oyster::Math::Float3 spawnPoint)
{
if( this->playerState == PLAYER_STATE_DEAD)
{
this->life = 100;
this->playerState = PLAYER_STATE::PLAYER_STATE_IDLE;
//this->lookDir = Oyster::Math::Float4(1,0,0);
Player::initPlayerData();
this->rigidBody->SetPosition(spawnPoint);
this->gameInstance->onRespawnFnc( this, spawnPoint);
this->gameInstance->onDamageTakenFnc( this, this->life);
this->gameInstance->onDamageTakenFnc( this, this->playerStats.hp);
}
}
@ -349,31 +307,30 @@ PLAYER_STATE Player::GetState() const
void Player::DamageLife(int damage)
{
this->life -= damage;
this->gameInstance->onDamageTakenFnc( this, this->life);
if(this->life <= 0)
if( this->playerState != PLAYER_STATE_DEAD)
{
this->life = 0;
playerState = PLAYER_STATE_DEAD;
this->deathTimeLeft = this->deathTime;
this->gameInstance->onDeadFnc(this, this->deathTimeLeft);
this->playerStats.hp -= damage;
// send hp to client
this->gameInstance->onDamageTakenFnc( this, this->playerStats.hp);
if(this->playerStats.hp <= 0)
{
this->playerStats.hp = 0;
this->playerState = PLAYER_STATE_DIED;
}
}
}
void Player::AddAffectedObject(DynamicObject &AffectedObject)
bool Player::deathTimerTick(float dt)
{
//check if object already exists in the list, if so then do not add
for(int i = 0; i < AffectedObjects.Size(); i++)
this->deathTimer -= dt;
if( this->deathTimer <= 0)
{
if(AffectedObjects[i]->GetID() == AffectedObject.GetID())
{
//object already exists, exit function
return;
return true;
}
}
//else you add the object to the stack
AffectedObjects.Push(&AffectedObject);
return false;
}
void Player::setDeathTimer(float deathTimer)
{
this->deathTimer = deathTimer;
this->playerState = PLAYER_STATE_DEAD;
}

View File

@ -9,6 +9,8 @@
#include "DynamicObject.h"
#include "DynamicArray.h"
const float MAX_HP = 100.0f;
const float BASIC_SPEED = 30.0f;
namespace GameLogic
{
@ -16,6 +18,21 @@ namespace GameLogic
class Player : public DynamicObject
{
public:
struct PlayerStats
{
Oyster::Math::Float hp;
Oyster::Math::Float movementSpeed;
//Oyster::Math::Float resistance;
};
struct PlayerScore
{
int killScore;
int deathScore;
// int assistScore;
// int suicideScore;
};
Player(void);
Player(Oyster::Physics::ICustomBody *rigidBody, void (*EventOnCollision)(Oyster::Physics::ICustomBody *proto,Oyster::Physics::ICustomBody *deuter,Oyster::Math::Float kineticEnergyLoss), ObjectSpecialType type, int objectID, int teamID);
@ -75,20 +92,21 @@ namespace GameLogic
PLAYER_STATE GetState() const;
void DamageLife(int damage);
void setDeathTimer(float deathTimer);
bool deathTimerTick(float dt);
void BeginFrame();
void EndFrame();
static Oyster::Physics::ICustomBody::SubscriptMessage PlayerCollisionAfter(Oyster::Physics::ICustomBody *rigidBodyLevel, Oyster::Physics::ICustomBody *obj, Oyster::Math::Float kineticEnergyLoss);
private:
void Jump();
void initPlayerData();
private:
Utility::DynamicMemory::DynamicArray<DynamicObject*> AffectedObjects;
Oyster::Math::Float life;
int teamID;
Weapon *weapon;
PLAYER_STATE playerState;
@ -100,18 +118,15 @@ namespace GameLogic
float key_jump;
Oyster::Math::Float3 previousPosition;
Oyster::Math::Float3 moveDir;
Oyster::Math::Float moveSpeed;
Oyster::Math::Float3 previousMoveSpeed;
Oyster::Math::Float rotationUp;
float deathTime;
float deathTimeLeft;
float deathTimer;
bool hasTakenDamage;
float invincibleCooldown;
PlayerStats playerStats;
PlayerScore playerScore;
};
}
#endif

View File

@ -188,7 +188,6 @@ using namespace DanBias;
break;
case protocol_Gameplay_PlayerShot: this->Gameplay_PlayerShot ( Protocol_PlayerShot (p), c );
break;
case protocol_Gameplay_ObjectPickup: this->Gameplay_ObjectPickup ( Protocol_ObjectPickup (p), c );
break;
case protocol_Gameplay_ObjectDamage: this->Gameplay_ObjectDamage ( Protocol_ObjectDamage (p), c );
@ -201,7 +200,6 @@ using namespace DanBias;
break;
case protocol_Gameplay_ObjectCreate: this->Gameplay_ObjectCreate ( Protocol_ObjectCreate (p), c );
break;
case protocol_General_Status: this->General_Status ( Protocol_General_Status (p), c );
break;
case protocol_General_Text: this->General_Text ( Protocol_General_Text (p), c );
@ -242,11 +240,8 @@ using namespace DanBias;
{
if(p.secondaryPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_SECONDARY_PRESS);
if(p.primaryPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_PRIMARY_PRESS);
if(p.utilityPressed) c->GetPlayer()->UseWeapon(GameLogic::WEAPON_USE_UTILLITY_PRESS);
}
void GameSession::Gameplay_ObjectPickup ( Protocol_ObjectPickup& p, DanBias::GameClient* c )
{