📄 soccerteam.cpp
字号:
int NumAttempts = Prm.NumAttemptsToFindValidStrike;
while (NumAttempts--)
{
//choose a random position along the opponent's goal mouth. (making
//sure the ball's radius is taken into account)
ShotTarget = OpponentsGoal()->Center();
//the y value of the shot position should lay somewhere between two
//goalposts (taking into consideration the ball diameter)
int MinYVal = OpponentsGoal()->LeftPost().y + Pitch()->Ball()->BRadius();
int MaxYVal = OpponentsGoal()->RightPost().y - Pitch()->Ball()->BRadius();
ShotTarget.y = (double)RandInt(MinYVal, MaxYVal);
//make sure striking the ball with the given power is enough to drive
//the ball over the goal line.
double time = Pitch()->Ball()->TimeToCoverDistance(BallPos,
ShotTarget,
power);
//if it is, this shot is then tested to see if any of the opponents
//can intercept it.
if (time >= 0)
{
if (isPassSafeFromAllOpponents(BallPos, ShotTarget, NULL, power))
{
return true;
}
}
}
return false;
}
//--------------------- ReturnAllFieldPlayersToHome ---------------------------
//
// sends a message to all players to return to their home areas forthwith
//------------------------------------------------------------------------
void SoccerTeam::ReturnAllFieldPlayersToHome()const
{
std::vector<PlayerBase*>::const_iterator it = m_Players.begin();
for (it; it != m_Players.end(); ++it)
{
if ((*it)->Role() != PlayerBase::goal_keeper)
{
Dispatcher->DispatchMsg(SEND_MSG_IMMEDIATELY,
1,
(*it)->ID(),
Msg_GoHome,
NULL);
}
}
}
//--------------------------- Render -------------------------------------
//
// renders the players and any team related info
//------------------------------------------------------------------------
void SoccerTeam::Render()const
{
std::vector<PlayerBase*>::const_iterator it = m_Players.begin();
for (it; it != m_Players.end(); ++it)
{
(*it)->Render();
}
//show the controlling team and player at the top of the display
if (Prm.bShowControllingTeam)
{
gdi->TextColor(Cgdi::white);
if ( (Color() == blue) && InControl())
{
gdi->TextAtPos(20,3,"Blue in Control");
}
else if ( (Color() == red) && InControl())
{
gdi->TextAtPos(20,3,"Red in Control");
}
if (m_pControllingPlayer != NULL)
{
gdi->TextAtPos(Pitch()->cxClient()-150, 3, "Controlling Player: " + ttos(m_pControllingPlayer->ID()));
}
}
//render the sweet spots
if (Prm.bSupportSpots && InControl())
{
m_pSupportSpotCalc->Render();
}
//#define SHOW_TEAM_STATE
#ifdef SHOW_TEAM_STATE
if (Color() == red)
{
gdi->TextColor(Cgdi::white);
if (CurrentState() == Attacking::Instance())
{
gdi->TextAtPos(160, 20, "Attacking");
}
if (CurrentState() == Defending::Instance())
{
gdi->TextAtPos(160, 20, "Defending");
}
if (CurrentState() == PrepareForKickOff::Instance())
{
gdi->TextAtPos(160, 20, "Kickoff");
}
}
else
{
if (CurrentState() == Attacking::Instance())
{
gdi->TextAtPos(160, Pitch()->cyClient()-40, "Attacking");
}
if (CurrentState() == Defending::Instance())
{
gdi->TextAtPos(160, Pitch()->cyClient()-40, "Defending");
}
if (CurrentState() == PrepareForKickOff::Instance())
{
gdi->TextAtPos(160, Pitch()->cyClient()-40, "Kickoff");
}
}
#endif
//#define SHOW_SUPPORTING_PLAYERS_TARGET
#ifdef SHOW_SUPPORTING_PLAYERS_TARGET
if (m_pSupportingPlayer)
{
gdi->BlueBrush();
gdi->RedPen();
gdi->Circle(m_pSupportingPlayer->Steering()->Target(), 4);
}
#endif
}
//------------------------- CreatePlayers --------------------------------
//
// creates the players
//------------------------------------------------------------------------
void SoccerTeam::CreatePlayers()
{
if (Color() == blue)
{
//goalkeeper
m_Players.push_back(new GoalKeeper(this,
1,
TendGoal::Instance(),
Vector2D(0,1),
Vector2D(0.0, 0.0),
Prm.PlayerMass,
Prm.PlayerMaxForce,
Prm.PlayerMaxSpeedWithoutBall,
Prm.PlayerMaxTurnRate,
Prm.PlayerScale));
//create the players
m_Players.push_back(new FieldPlayer(this,
6,
Wait::Instance(),
Vector2D(0,1),
Vector2D(0.0, 0.0),
Prm.PlayerMass,
Prm.PlayerMaxForce,
Prm.PlayerMaxSpeedWithoutBall,
Prm.PlayerMaxTurnRate,
Prm.PlayerScale,
PlayerBase::attacker));
m_Players.push_back(new FieldPlayer(this,
8,
Wait::Instance(),
Vector2D(0,1),
Vector2D(0.0, 0.0),
Prm.PlayerMass,
Prm.PlayerMaxForce,
Prm.PlayerMaxSpeedWithoutBall,
Prm.PlayerMaxTurnRate,
Prm.PlayerScale,
PlayerBase::attacker));
m_Players.push_back(new FieldPlayer(this,
3,
Wait::Instance(),
Vector2D(0,1),
Vector2D(0.0, 0.0),
Prm.PlayerMass,
Prm.PlayerMaxForce,
Prm.PlayerMaxSpeedWithoutBall,
Prm.PlayerMaxTurnRate,
Prm.PlayerScale,
PlayerBase::defender));
m_Players.push_back(new FieldPlayer(this,
5,
Wait::Instance(),
Vector2D(0,1),
Vector2D(0.0, 0.0),
Prm.PlayerMass,
Prm.PlayerMaxForce,
Prm.PlayerMaxSpeedWithoutBall,
Prm.PlayerMaxTurnRate,
Prm.PlayerScale,
PlayerBase::defender));
}
else
{
//goalkeeper
m_Players.push_back(new GoalKeeper(this,
16,
TendGoal::Instance(),
Vector2D(0,-1),
Vector2D(0.0, 0.0),
Prm.PlayerMass,
Prm.PlayerMaxForce,
Prm.PlayerMaxSpeedWithoutBall,
Prm.PlayerMaxTurnRate,
Prm.PlayerScale));
//create the players
m_Players.push_back(new FieldPlayer(this,
9,
Wait::Instance(),
Vector2D(0,-1),
Vector2D(0.0, 0.0),
Prm.PlayerMass,
Prm.PlayerMaxForce,
Prm.PlayerMaxSpeedWithoutBall,
Prm.PlayerMaxTurnRate,
Prm.PlayerScale,
PlayerBase::attacker));
m_Players.push_back(new FieldPlayer(this,
11,
Wait::Instance(),
Vector2D(0,-1),
Vector2D(0.0, 0.0),
Prm.PlayerMass,
Prm.PlayerMaxForce,
Prm.PlayerMaxSpeedWithoutBall,
Prm.PlayerMaxTurnRate,
Prm.PlayerScale,
PlayerBase::attacker));
m_Players.push_back(new FieldPlayer(this,
12,
Wait::Instance(),
Vector2D(0,-1),
Vector2D(0.0, 0.0),
Prm.PlayerMass,
Prm.PlayerMaxForce,
Prm.PlayerMaxSpeedWithoutBall,
Prm.PlayerMaxTurnRate,
Prm.PlayerScale,
PlayerBase::defender));
m_Players.push_back(new FieldPlayer(this,
14,
Wait::Instance(),
Vector2D(0,-1),
Vector2D(0.0, 0.0),
Prm.PlayerMass,
Prm.PlayerMaxForce,
Prm.PlayerMaxSpeedWithoutBall,
Prm.PlayerMaxTurnRate,
Prm.PlayerScale,
PlayerBase::defender));
}
//register the players with the entity manager
std::vector<PlayerBase*>::iterator it = m_Players.begin();
for (it; it != m_Players.end(); ++it)
{
EntityMgr->RegisterEntity(*it);
}
}
PlayerBase* SoccerTeam::GetPlayerFromID(int id)const
{
std::vector<PlayerBase*>::const_iterator it = m_Players.begin();
for (it; it != m_Players.end(); ++it)
{
if ((*it)->ID() == id) return *it;
}
return NULL;
}
void SoccerTeam::SetPlayerHomeRegion(int plyr, int region)const
{
assert ( (plyr>=0) && (plyr<m_Players.size()) );
m_Players[plyr]->SetHomeRegion(region);
}
//---------------------- UpdateTargetsOfWaitingPlayers ------------------------
//
//
void SoccerTeam::UpdateTargetsOfWaitingPlayers()const
{
std::vector<PlayerBase*>::const_iterator it = m_Players.begin();
for (it; it != m_Players.end(); ++it)
{
if ( (*it)->Role() != PlayerBase::goal_keeper )
{
//cast to a field player
FieldPlayer* plyr = static_cast<FieldPlayer*>(*it);
if ( plyr->GetFSM()->isInState(*Wait::Instance()) ||
plyr->GetFSM()->isInState(*ReturnToHomeRegion::Instance()) )
{
plyr->Steering()->SetTarget(plyr->HomeRegion()->Center());
}
}
}
}
//--------------------------- AllPlayersAtHome --------------------------------
//
// returns false if any of the team are not located within their home region
//-----------------------------------------------------------------------------
bool SoccerTeam::AllPlayersAtHome()const
{
std::vector<PlayerBase*>::const_iterator it = m_Players.begin();
for (it; it != m_Players.end(); ++it)
{
if ((*it)->InHomeRegion() == false)
{
return false;
}
}
return true;
}
//------------------------- RequestPass ---------------------------------------
//
// this tests to see if a pass is possible between the requester and
// the controlling player. If it is possible a message is sent to the
// controlling player to pass the ball asap.
//-----------------------------------------------------------------------------
void SoccerTeam::RequestPass(FieldPlayer* requester)const
{
//maybe put a restriction here
if (RandFloat() > 0.1) return;
if (isPassSafeFromAllOpponents(ControllingPlayer()->Pos(),
requester->Pos(),
requester,
Prm.MaxPassingForce))
{
//tell the player to make the pass
//let the receiver know a pass is coming
Dispatcher->DispatchMsg(SEND_MSG_IMMEDIATELY,
requester->ID(),
ControllingPlayer()->ID(),
Msg_PassToMe,
requester);
}
}
//----------------------------- isOpponentWithinRadius ------------------------
//
// returns true if an opposing player is within the radius of the position
// given as a parameter
//-----------------------------------------------------------------------------
bool SoccerTeam::isOpponentWithinRadius(Vector2D pos, double rad)
{
std::vector<PlayerBase*>::const_iterator end = Opponents()->Members().end();
std::vector<PlayerBase*>::const_iterator it;
for (it=Opponents()->Members().begin(); it !=end; ++it)
{
if (Vec2DDistanceSq(pos, (*it)->Pos()) < rad*rad)
{
return true;
}
}
return false;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -