📄 soccerruleaspect.cpp
字号:
Vector2f(-mFieldLength/2.0 - 10, mFieldWidth/2.0 + 10.0)); // the penalty areas (exact sizes) mRightPenaltyArea = salt::AABB2(Vector2f(mFieldLength/2.0 - 8, -5.25 - mGoalWidth/2.0), Vector2f(mFieldLength/2.0 , 5.25 + mGoalWidth/2.0)); mLeftPenaltyArea = salt::AABB2(Vector2f(-mFieldLength/2.0 + 8, -5.25 - mGoalWidth/2.0), Vector2f(-mFieldLength/2.0, 5.25 + mGoalWidth/2.0));}voidSoccerRuleAspect::Broadcast(const string& message, const Vector3f& pos, int number, TTeamIndex idx){ TAgentStateList agent_states; if (! SoccerBase::GetAgentStates(*mBallState, agent_states, idx)) { return; } TAgentStateList opponent_agent_states; if (! SoccerBase::GetAgentStates(*mBallState, opponent_agent_states, SoccerBase::OpponentTeam(idx))) { return; } if (message.size() > mSayMsgSize) { return; } salt::BoundingSphere sphere(pos, mAudioCutDist); shared_ptr<Transform> transform_parent; shared_ptr<Body> agent_body; for ( TAgentStateList::const_iterator it = agent_states.begin(); it != agent_states.end(); it++ ) { if ( (*it)->GetUniformNumber() == number) { (*it)->AddSelfMessage(message); continue; } SoccerBase::GetTransformParent(*(*it), transform_parent); // call GetAgentBody with matching AgentAspect SoccerBase::GetAgentBody(transform_parent, agent_body); // if the player is in the range, send the message Vector3f new_pos = agent_body->GetPosition(); if (sphere.Contains(new_pos)) { Vector3f relPos = pos - new_pos; relPos = SoccerBase::FlipView(relPos, idx); float direction = salt::gRadToDeg(salt::gArcTan2(relPos[1], relPos[0])); (*it)->AddMessage(message, direction, true); } } for ( SoccerBase::TAgentStateList::const_iterator it = opponent_agent_states.begin(); it != opponent_agent_states.end(); it++ ) { SoccerBase::GetTransformParent(*(*it), transform_parent); // call GetAgentBody with matching AgentAspect SoccerBase::GetAgentBody(transform_parent, agent_body); // if the player is in the range, send the message Vector3f new_pos = agent_body->GetPosition(); if (sphere.Contains(new_pos)) { Vector3f relPos = pos - new_pos; relPos = SoccerBase::FlipView(relPos, SoccerBase::OpponentTeam(idx)); float direction = salt::gRadToDeg(salt::gArcTan2(relPos[1], relPos[0])); (*it)->AddMessage(message, direction, false); } }}boolSoccerRuleAspect::CheckOffside(){#if 0 shared_ptr<AgentAspect> collidingAgent; shared_ptr<AgentAspect> kickingAgent; shared_ptr<AgentAspect> agent; shared_ptr<AgentState> agentState; TTime collidingTime; TTime kickingTime; TTime time; static TTime lastCollisionTime = 0.0; if (! mLastModeWasPlayOn) { mInOffsideLeftPlayers.clear(); mInOffsideRightPlayers.clear(); } if (! mBallState->GetLastCollidingAgent(collidingAgent,collidingTime) ) { return false; } if (! mBallState->GetLastKickingAgent(kickingAgent,kickingTime) ) { return false; } if (collidingTime > kickingTime) { time = collidingTime; agent = collidingAgent; } else { time = kickingTime; agent = kickingAgent; } // if the last colliding agent is the first agent that touches the ball // after "a goal kick" or "a kick-in(FIFA: throw-in)" or "a corner kick" TTime lastModeChange = mGameState->GetLastModeChange(); if (time == lastModeChange) { mFirstCollidingAgent = true; } // only when an agent collides with the ball it maybe affect // offside, if we sometime want to consider // "interfering with an opponent" we should remove this condition if (lastCollisionTime == time) { return false; } lastCollisionTime = time; // if the second last collinding agent is the last colliding agent, // there is no offside if (mPreLastCollidingAgent == agent) { mNotOffside = true; } else { mPreLastCollidingAgent = agent; mNotOffside = false; } // find the positions of the last opponent defender and the second last one if (! SoccerBase::GetAgentState(agent,agentState)) { return false; } TTeamIndex idx = agentState->GetTeamIndex(); list<shared_ptr<AgentState> > opp_agent_states; if (! SoccerBase::GetAgentStates(*mBallState, opp_agent_states, SoccerBase::OpponentTeam(idx))) { return false; } float opp_goalkeeper_pos; float opp_defender_pos; opp_goalkeeper_pos = 0.0; opp_defender_pos = 0.0; shared_ptr<Transform> transform_parent; shared_ptr<Body> agent_body; list<shared_ptr<AgentState> >::const_iterator it; for (it = opp_agent_states.begin(); it != opp_agent_states.end(); it++) { SoccerBase::GetTransformParent(*(*it), transform_parent); SoccerBase::GetAgentBody(transform_parent, agent_body); Vector3f opp_agent_pos = agent_body->GetPosition(); if (SoccerBase::OpponentTeam(idx) == TI_LEFT) { if (opp_agent_pos[0] <= opp_goalkeeper_pos) { opp_defender_pos = opp_goalkeeper_pos; opp_goalkeeper_pos = opp_agent_pos[0]; } else if (opp_agent_pos[0] <= opp_defender_pos) { opp_defender_pos = opp_agent_pos[0]; } } else { if (opp_agent_pos[0] >= opp_goalkeeper_pos) { opp_defender_pos = opp_goalkeeper_pos; opp_goalkeeper_pos = opp_agent_pos[0]; } else if (opp_agent_pos[0] >= opp_defender_pos) { opp_defender_pos = opp_agent_pos[0]; } } } Vector3f ball_pos = mBallBody->GetPosition(); SoccerBase::GetTransformParent(*agentState, transform_parent); SoccerBase::GetAgentBody(transform_parent, agent_body); Vector3f agent_pos = agent_body->GetPosition(); if ( mFirstCollidingAgent ) { if (((idx == TI_LEFT) && (agent_pos[0] > opp_defender_pos) && (agent_pos[0] > ball_pos[0])) || ((idx == TI_RIGHT) && (agent_pos[0] < opp_defender_pos) && (agent_pos[0] < ball_pos[0]))) { mFirstCollidingAgent = true; } else { mFirstCollidingAgent = false; } } // if the agent,that touches the ball was in // offside position before the last shoot, change the mode to offside bool offside = false; if ((idx == TI_LEFT) && !mFirstCollidingAgent && !mNotOffside) { vector<int>::const_iterator it_offside; for ( it_offside = mInOffsideLeftPlayers.begin(); it_offside != mInOffsideLeftPlayers.end(); it_offside++) { if (agentState->GetUniformNumber() == *it_offside) { mGameState->SetPlayMode(PM_OFFSIDE_RIGHT); offside = true; } } if (!offside && (agent_pos[0] > opp_defender_pos)) mFirstCollidingAgent = true; } else if (!mFirstCollidingAgent && !mNotOffside) { vector<int>::const_iterator it_offside; for ( it_offside = mInOffsideRightPlayers.begin(); it_offside != mInOffsideRightPlayers.end(); it_offside++ ) { if (agentState->GetUniformNumber() == *it_offside) { mGameState->SetPlayMode(PM_OFFSIDE_LEFT); offside = true; } } if (!offside && (agent_pos[0] < opp_defender_pos)) mFirstCollidingAgent = true; } // update the list of players that are in offside poistion mInOffsideLeftPlayers.clear(); mInOffsideRightPlayers.clear(); mFreeKickPos = mBallState->GetLastValidBallPosition(); mFreeKickPos[2] = mBallRadius; list<shared_ptr<AgentState> > agent_states; if (! SoccerBase::GetAgentStates(*mBallState, agent_states, idx)) { return false; } for (it = agent_states.begin(); it != agent_states.end(); it++) { SoccerBase::GetTransformParent(*(*it), transform_parent); SoccerBase::GetAgentBody(transform_parent, agent_body); Vector3f agent_pos = agent_body->GetPosition(); if (idx == TI_LEFT) { if ((agent_pos[0] > opp_defender_pos) && (agent_pos[0] > ball_pos[0])) { mInOffsideLeftPlayers.push_back((*it)->GetUniformNumber()); } } else { if ((agent_pos[0] < opp_defender_pos) && (agent_pos[0] < ball_pos[0])) { mInOffsideRightPlayers.push_back((*it)->GetUniformNumber()); } } } return true;#endif}voidSoccerRuleAspect::UpdateOffside(TTeamIndex idx){#if 0 // do nothing for the duration of mKickInPauseTime if (mGameState->GetModeTime() < mKickInPauseTime) { return; } // move away opponent team Vector3f ball_pos = mBallBody->GetPosition(); ClearPlayers(mFreeKickPos, mFreeKickDist, mFreeKickMoveDist, SoccerBase::OpponentTeam(idx)); // if no player touched the ball for mDropBallTime, we move away // all players and set the play mode to play on if (mDropBallTime > 0 && mGameState->GetModeTime() > mDropBallTime) { DropBall(mFreeKickPos); return; } // after the first agent touches the ball move to PM_PLAY_ON. the // time when the agent last touches the ball must be after the // change to the OffsideKick mode shared_ptr<AgentAspect> agent; shared_ptr<AgentState> agentState; TTime time; if (! mBallState->GetLastCollidingAgent(agent,time)) { GetLog()->Error() << "ERROR: (SoccerRuleAspect) no agent collided yet\n"; return; } if (! SoccerBase::GetAgentState(agent,agentState)) { return; } TTeamIndex collidingAgentIdx = agentState->GetTeamIndex(); TTime lastChange = mGameState->GetLastModeChange(); if (time > lastChange && collidingAgentIdx==idx) { mGameState->SetPlayMode(PM_PlayOn); } else { // move the ball back on the free kick position MoveBall(mFreeKickPos); }#endif}voidSoccerRuleAspect::ClearPlayersWithException(const salt::Vector3f& pos, float radius, float min_dist, TTeamIndex idx, shared_ptr<AgentState> agentState){ if (idx == TI_NONE || mBallState.get() == 0) return; std::list<boost::shared_ptr<AgentState> > agent_states; if (! SoccerBase::GetAgentStates(*mBallState, agent_states, idx)) return; salt::BoundingSphere sphere(pos, radius); boost::shared_ptr<oxygen::Transform> agent_aspect; std::list<boost::shared_ptr<AgentState> >::const_iterator i; for (i = agent_states.begin(); i != agent_states.end(); ++i) { if (agentState == (*i)) continue; SoccerBase::GetTransformParent(**i, agent_aspect); // if agent is too close, move it away Vector3f new_pos = agent_aspect->GetWorldTransform().Pos(); Vector3f test_pos = new_pos; test_pos[2] = pos[2]; if (sphere.Contains(test_pos)) { float dist = salt::UniformRNG<>(min_dist, min_dist + 2.0)(); if (idx == TI_LEFT) { if (pos[0] - dist < -mFieldLength/2.0) { new_pos[1] = pos[1] < 0 ? pos[1] + dist : pos[1] - dist; } else { new_pos[0] = pos[0] - dist; } } else { if (pos[0] + dist > mFieldLength/2.0) { new_pos[1] = pos[1] < 0 ? pos[1] + dist : pos[1] - dist; } else { new_pos[0] = pos[0] + dist; } } MoveAgent(agent_aspect, new_pos); } }#if 0 if (idx == TI_NONE || mBallState.get() == 0) return; std::list<boost::shared_ptr<AgentState> > agent_states; if (! SoccerBase::GetAgentStates(*mBallState, agent_states, idx)) return; salt::BoundingSphere sphere(pos, radius); boost::shared_ptr<oxygen::Transform> transform_parent; boost::shared_ptr<oxygen::Body> agent_body; std::list<boost::shared_ptr<AgentState> >::const_iterator i; for (i = agent_states.begin(); i != agent_states.end(); ++i) { if (agentState == (*i)) continue; SoccerBase::GetTransformParent(*(*i), transform_parent); // call GetAgentBody with matching AgentAspect SoccerBase::GetAgentBody(transform_parent, agent_body); // if agent is too close, move it away Vector3f new_pos = agent_body->GetPosition(); if (sphere.Contains(new_pos)) { float dist = salt::UniformRNG<>(min_dist, min_dist + 2.0)(); if (idx == TI_LEFT) { if (pos[0] - dist < -mFieldLength/2.0) { new_pos[1] = pos[1] < 0 ? pos[1] + dist : pos[1] - dist; } else { new_pos[0] = pos[0] - dist; } } else { if (pos[0] + dist > mFieldLength/2.0) { new_pos[1] = pos[1] < 0 ? pos[1] + dist : pos[1] - dist; } else { new_pos[0] = pos[0] + dist; } } new_pos[2] = 1.0; MoveAgent(agent_body, new_pos); } }#endif}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -