www.pudn.com > BucklandSimpleSoccer.rar > FieldPlayer.cpp
#include "FieldPlayer.h" #include "PlayerBase.h" #include "SteeringBehaviors.h" #include "2D/Transformations.h" #include "2D/Geometry.h" #include "misc/Cgdi.h" #include "2D/C2DMatrix.h" #include "Goal.h" #include "Game/Region.h" #include "game/EntityFunctionTemplates.h" #include "ParamLoader.h" #include "SoccerTeam.h" #include "time/Regulator.h" #include "Debug/DebugConsole.h" #includeusing std::vector; //------------------------------- dtor --------------------------------------- //---------------------------------------------------------------------------- FieldPlayer::~FieldPlayer() { delete m_pKickLimiter; delete m_pStateMachine; } //----------------------------- ctor ------------------------------------- //------------------------------------------------------------------------ FieldPlayer::FieldPlayer(SoccerTeam* home_team, int home_region, State * start_state, Vector2D heading, Vector2D velocity, double mass, double max_force, double max_speed, double max_turn_rate, double scale, player_role role): PlayerBase(home_team, home_region, heading, velocity, mass, max_force, max_speed, max_turn_rate, scale, role) { //set up the state machine m_pStateMachine = new StateMachine (this); if (start_state) { m_pStateMachine->SetCurrentState(start_state); m_pStateMachine->SetPreviousState(start_state); m_pStateMachine->SetGlobalState(GlobalPlayerState::Instance()); m_pStateMachine->CurrentState()->Enter(this); } m_pSteering->SeparationOn(); //set up the kick regulator m_pKickLimiter = new Regulator(Prm.PlayerKickFrequency); } //------------------------------ Update ---------------------------------- // // //------------------------------------------------------------------------ void FieldPlayer::Update() { //run the logic for the current state m_pStateMachine->Update(); //calculate the combined steering force m_pSteering->Calculate(); //if no steering force is produced decelerate the player by applying a //braking force if (m_pSteering->Force().isZero()) { const double BrakingRate = 0.8; m_vVelocity = m_vVelocity * BrakingRate; } //the steering force's side component is a force that rotates the //player about its axis. We must limit the rotation so that a player //can only turn by PlayerMaxTurnRate rads per update. double TurningForce = m_pSteering->SideComponent(); Clamp(TurningForce, -Prm.PlayerMaxTurnRate, Prm.PlayerMaxTurnRate); //rotate the heading vector Vec2DRotateAroundOrigin(m_vHeading, TurningForce); //make sure the velocity vector points in the same direction as //the heading vector m_vVelocity = m_vHeading * m_vVelocity.Length(); //and recreate m_vSide m_vSide = m_vHeading.Perp(); //now to calculate the acceleration due to the force exerted by //the forward component of the steering force in the direction //of the player's heading Vector2D accel = m_vHeading * m_pSteering->ForwardComponent() / m_dMass; m_vVelocity += accel; //make sure player does not exceed maximum velocity m_vVelocity.Truncate(m_dMaxSpeed); //update the position m_vPosition += m_vVelocity; //enforce a non-penetration constraint if desired if(Prm.bNonPenetrationConstraint) { EnforceNonPenetrationContraint(this, AutoList ::GetAllMembers()); } } //-------------------- HandleMessage ------------------------------------- // // routes any messages appropriately //------------------------------------------------------------------------ bool FieldPlayer::HandleMessage(const Telegram& msg) { return m_pStateMachine->HandleMessage(msg); } //--------------------------- Render ------------------------------------- // //------------------------------------------------------------------------ void FieldPlayer::Render() { gdi->TransparentText(); gdi->TextColor(Cgdi::grey); //set appropriate team color if (Team()->Color() == SoccerTeam::blue){gdi->BluePen();} else{gdi->RedPen();} //render the player's body m_vecPlayerVBTrans = WorldTransform(m_vecPlayerVB, Pos(), Heading(), Side(), Scale()); gdi->ClosedShape(m_vecPlayerVBTrans); //and 'is 'ead gdi->BrownBrush(); if (Prm.bHighlightIfThreatened && (Team()->ControllingPlayer() == this) && isThreatened()) gdi->YellowBrush(); gdi->Circle(Pos(), 6); //render the state if (Prm.bStates) { gdi->TextColor(0, 170, 0); gdi->TextAtPos(m_vPosition.x, m_vPosition.y -20, std::string(m_pStateMachine->GetNameOfCurrentState())); } //show IDs if (Prm.bIDs) { gdi->TextColor(0, 170, 0); gdi->TextAtPos(Pos().x-20, Pos().y-20, ttos(ID())); } if (Prm.bViewTargets) { gdi->RedBrush(); gdi->Circle(Steering()->Target(), 3); gdi->TextAtPos(Steering()->Target(), ttos(ID())); } }