コード例 #1
0
void SoccerFormation::update_defend_formation(SoccerTeam *team) {
	SoccerBall *ball = team->get_match()->get_ball();

	int ball_x = (int) ball->get_pos().x;
	int ball_y = (int) ball->get_pos().y;

	/* 后防线的基準座標 */
	double index_x;
	/* 是否已經進入禁區了 */
	int is_hot = 0;
	/* 球在大禁區的之內 */
	if (ball_x <= A_FORBIDDEN_AREA_X) {
		index_x = MIDDLE_CIRCLE_B;
	} else if (ball_x <= (39.5 * 12) && ball_x > A_FORBIDDEN_AREA_X) {
		index_x = DEFEND_LINE_SEC;
	} else if (ball_x > (39.5 * 12) && ball_x <= DEFEND_LINE_SEC) {
		index_x = (((ball_x - 39.5 * 12) / (26 * 12)) * ((B_FORBIDDEN_AREA_X
				- 3 * METER_TO_POINT) - DEFEND_LINE_SEC)) + DEFEND_LINE_SEC;
	} else if (ball_x > DEFEND_LINE_SEC && ball_x <= B_FORBIDDEN_AREA_X) {
		index_x = (((ball_x - DEFEND_LINE_SEC) / (B_FORBIDDEN_AREA_X
				- DEFEND_LINE_SEC)) * (6 * METER_TO_POINT))
				+ B_FORBIDDEN_AREA_X;
		is_hot = 1;
	} else if (ball_x > B_FORBIDDEN_AREA_X && ball_x <= PITCH_WIDTH) {
		index_x = PITCH_WIDTH - (ball_x - B_FORBIDDEN_AREA_X) / (PITCH_WIDTH
				- B_FORBIDDEN_AREA_X) * 11 * METER_TO_POINT;
		is_hot = 1;
	}
	if(index_x > (PITCH_WIDTH - OUTSIDE_WIDTH - 2 * METER_TO_POINT)){
		index_x = PITCH_WIDTH - OUTSIDE_WIDTH - 2 * METER_TO_POINT;
	}

	
	if(index_x < (MIDDLE_CIRCLE_B)){
		index_x = MIDDLE_CIRCLE_B;
	}


	int mod_y = 0;
	mod_y = (((ball_y - PITCH_HEIGHT / 2) * 216) / (PITCH_HEIGHT / 2));

	int ball_left_or_right = 0;
	if (ball_y < A_FORBIDDEN_AREA_Y) {
		ball_left_or_right = 1;
	} else if (ball_y > (A_GOAL_HEIGHT + FORBIDDEN_AREA_HEIGHT / 2)) {
		ball_left_or_right = -1;
	}

	int player_dis = 10;
	//TODO 如果球队喊话中有散开的话,三条线拉开12米(不影响进攻),横向7米
	if(team->check_coach_speak(SPEAK_MORE_SPACE)){
			player_dis = player_dis + 12/3;
	}else if(team->check_coach_speak(SPEAK_LESS_SPACE)){//三条线拉开8米(不影响进攻),横向5米
			player_dis = player_dis + 8/3;
	}

	for (int i = 0; i < team->get_players_on_pitch_count(); ++i) {
		SoccerPlayer *pPlayer = team->get_player_on_pitch(i);

		int region_id = _position[i] - 1;
		SoccerRegion region = _region[region_id];
		int region_width = (int) (region.x2 - region.x1);
		int region_height = (int) (region.y2 - region.y1);

		SoccerRegion tmpRegion;
		Vector2D vecPos;
		vecPos.x = (index_x - ((team->getBackLine()
				- (pPlayer->get_formation_pos() - 1) / 5) * player_dis
				* METER_TO_POINT));
		vecPos.y = pPlayer->_init_pos.y + mod_y;

		if (ball_left_or_right == 0) {
			if (pPlayer->get_formation_pos() == 26
					|| pPlayer->get_formation_pos() == 30) {
				vecPos.x = vecPos.x - 2 * METER_TO_POINT;
			}
		} else if (ball_left_or_right == 1) {
			if (pPlayer->get_formation_pos() % 5 == 1) {
				vecPos.x = vecPos.x - 5 * METER_TO_POINT;
			}
		} else if (ball_left_or_right == -1) {
			if (pPlayer->get_formation_pos() % 5 == 0) {
				vecPos.x = vecPos.x - 5 * METER_TO_POINT;
			}
		}

		/* 假如突入大禁區,像中間收縮 */
		if (is_hot == 1) {
			if (pPlayer->get_formation_pos() == 26) {
				vecPos.y = vecPos.y - 8 * METER_TO_POINT;
			} else if (pPlayer->get_formation_pos() == 27) {
				vecPos.y = vecPos.y - 5 * METER_TO_POINT;
			} else if (pPlayer->get_formation_pos() == 28) {
				vecPos.y = vecPos.y + 0 * METER_TO_POINT;
			} else if (pPlayer->get_formation_pos() == 29) {
				vecPos.y = vecPos.y + 5 * METER_TO_POINT;
			} else if (pPlayer->get_formation_pos() == 30) {
				vecPos.y = vecPos.y + 8 * METER_TO_POINT;
			}
		}

		region.x1 = vecPos.x - region_width / 2;
		region.x2 = vecPos.x + region_width / 2;

		region.x1 = vecPos.x - region_width / 2;
		region.x2 = vecPos.x + region_width / 2;

		region.y1 = vecPos.y - region_height / 2;
		region.y2 = vecPos.y + region_height / 2;
		region.fix_to_pitch();
		pPlayer->set_home(region);

		tmpRegion.x1 = pPlayer->get_pos().x - 80;
		tmpRegion.x2 = pPlayer->get_pos().x + 30;
		tmpRegion.y1 = pPlayer->get_pos().y - 1 * 60;
		tmpRegion.y2 = pPlayer->get_pos().y + 1 * 60;
		tmpRegion.fix_to_pitch();
		team->get_player_on_pitch(i)->set_markArea(tmpRegion);

		tmpRegion.x1 = pPlayer->get_pos().x - 17 * METER_TO_POINT;
		tmpRegion.x2 = pPlayer->get_pos().x + 3 * METER_TO_POINT;
		tmpRegion.y1 = pPlayer->get_pos().y - 7 * METER_TO_POINT;
		tmpRegion.y2 = pPlayer->get_pos().y + 7 * METER_TO_POINT;
		tmpRegion.fix_to_pitch();
		team->get_player_on_pitch(i)->set_mindArea(tmpRegion);
	}
	player_modifer_formation_speak(team);
}
コード例 #2
0
void BallGoalFlyState::execute(SoccerBall &b){
	b.set_motion_type(SoccerBall::GOAL_FLY);
	b.move();
}
コード例 #3
0
void SoccerFormation::update_attack_formation(SoccerTeam *team) {
//	static double x_offset_factor[] = { 0, 0.5, 0.5, 0.5, 0, 0.8, 0.75, 0.75, 0.75,
//			0.8, 1, 0.5, 0.6, 0.5, 1, 1, 1.2, 1.2, 1.2, 1, 1.75, 0.75, 0.75,
//			0.75, 1.75, 1.5, 0.5, 0.5, 0.5, 1.5, 0, 0.5, 0.5, 0.5, 0 };
	static double x_offset_factor[] = { 0, 0.25, 0.25, 0.25, 0,
										0.4, 0.3, 0.3, 0.3, 0.4,
										0.5, 0.25, 0.3, 0.25, 0.5,
										0.5, 0.5, 0.5, 0.5, 0.5,
										1, 0.75, 0.75,0.75, 1,
										1.5, 0.5, 0.5, 0.5, 1.5,
										0, 0.5, 0.5, 0.5, 0 };

	SoccerBall *ball = team->get_match()->get_ball();
	int ball_x = (int) ball->get_pos().x;
	int ball_y = (int) ball->get_pos().y;

	double tmp = PITCH_WIDTH / 2;
	//拿到最后一个后卫线
	for (int i = 0; i < team->get_players_on_pitch_count(); ++i) {
		SoccerPlayer *pPlayer = team->get_player_on_pitch(i);
		if (_position[i] >= 27 && _position[i] <= 29) {
			if (tmp > pPlayer->get_pos().x) {
				tmp = pPlayer->get_pos().x;
			}
		} else if ((_position[i] >= 32 && _position[i] <= 34)) {
			if (tmp > pPlayer->get_pos().x) {
				tmp = pPlayer->get_pos().x;
			}
		}
	}

	double dx = ball_x - tmp;//ball to last defense line
	double dy = ball_y - PITCH_HEIGHT / 2;

	for (int i = 0; i < team->get_players_on_pitch_count(); ++i) {
		SoccerPlayer *pPlayer = team->get_player_on_pitch(i);
		int region_id = _position[i] - 1;
		SoccerRegion region = _region[region_id];
		int region_width = (int) (region.x2 - region.x1);
		int region_height = (int) (region.y2 - region.y1);

		region.x1 += (dx * x_offset_factor[region_id]);
		region.x2 += (dx * x_offset_factor[region_id]);

		if (_position[i] == 21) {
			region.x1 = tmp + 15 * METER_TO_POINT;
			region.x2 = tmp + 25 * METER_TO_POINT;
		} else if (_position[i] == 25) {
			region.x1 = tmp + 15 * METER_TO_POINT;
			region.x2 = tmp + 25 * METER_TO_POINT;
		} else if (_position[i] == 26) {
			region.x1 = tmp + 10 * METER_TO_POINT;
			region.x2 = tmp + 20 * METER_TO_POINT;
		} else if (_position[i] == 30) {
			region.x1 = tmp + 10 * METER_TO_POINT;
			region.x2 = tmp + 20 * METER_TO_POINT;
		}

		if (region.x2 > PITCH_WIDTH - OUTSIDE_WIDTH) {
			region.x2 = PITCH_WIDTH - OUTSIDE_WIDTH;
			region.x1 = region.x2 - region_width;
		} else if (region.x1 < OUTSIDE_WIDTH) {
			region.x1 = OUTSIDE_WIDTH;
			region.x2 = region.x1 + region_width;
		}

		//进攻球员根据move typ偏移
		fix_formation_by_move_order(pPlayer->get_formation_pos(), region);

		//120是球员之间间距的合理值
		region.y1 += ((dy / (PITCH_HEIGHT / 2)) * 100);
		region.y2 += ((dy / (PITCH_HEIGHT / 2)) * 100);

		if (region.y2 > PITCH_HEIGHT - OUTSIDE_HEIGHT) {
			region.y2 = PITCH_HEIGHT - OUTSIDE_HEIGHT;
			region.y1 = region.y2 - region_height;
		} else if (region.y1 < OUTSIDE_HEIGHT) {
			region.y1 = OUTSIDE_HEIGHT;
			region.y2 = region.y1 + region_height;
		}
		double y = pPlayer->get_middle_modifer();
		region.y1 += y;
		region.y2 += y;

		pPlayer->set_home(region);
	}

	player_modifer_formation_speak(team);
}
コード例 #4
0
//////////////////////////////
// BallCrossState
void BallCrossState::execute(SoccerBall &b)
{
    b.move();
}
コード例 #5
0
void BallDribbledState::execute(SoccerBall &b)
{
	b.move();
}
コード例 #6
0
//////////////////////////////
//FreeState
void FreeState::execute(SoccerBall &b)
{
    b.move_free();
}
コード例 #7
0
//////////////////////////////
//CornerState
void CornerState::execute(SoccerBall &b)
{
    b.move_corner();
}
コード例 #8
0
//////////////////////////////
// PenaltyState
void PenaltyState::execute(SoccerBall &b)
{
    b.move_penalty();
}
コード例 #9
0
//////////////////////////////
// BallRollState
void BallRollState::execute(SoccerBall &b)
{
    b.move();
}
コード例 #10
0
void GlobalBallState::on_message(SoccerBall &b, Telegram *message)
{
    BallTelegram *ball_msg = (BallTelegram *)message;
    switch (ball_msg->message)
    {
		case TELE_BALL_KICK:
		{
			b.kick(ball_msg->speed, ball_msg->heading);
			b.set_state(BallRollState::alloc());
		}
		break;
		case TELE_BALL_CROSS:
		{
			b.cross(ball_msg->speed, ball_msg->speed_z, ball_msg->heading);
			b.set_state(BallCrossState::alloc());
		}
		break;
		case TELE_BALL_STOP:
		{
			b.set_speed(0);
			b.set_state(BallStopState::alloc());
		}
		break;
		case TELE_PLAYER_PENALTY:
		{
			b.set_speed(0);
			b.set_state(PenaltyState::alloc());
		}
		break;
		case TELE_PLAYER_FREE:
		{
			b.set_speed(0);
			b.set_state(FreeState::alloc());
		}
		break;
		case TELE_PLAYER_CORNER:
		{
			b.set_speed(0);
			b.set_state(CornerState::alloc());
		}
		break;
		case TELE_BALL_GOAL_FLY:
		{
			b.set_speed(ball_msg->speed);
			b.set_state(BallGoalFlyState::alloc());
		}
		break;
		default:
		{

		}
		break;
    }
}
コード例 #11
0
/////////////////////////
// GlobalBallState
void GlobalBallState::execute(SoccerBall &b)
{
    SoccerPlayer *owner = b.get_owner();
    if (owner != NULL)
    {
        if (b.get_motion_type() == SoccerBall::STOP)
        {
            b.set_motion_type(SoccerBall::MOVE);
        }
        else if (b.get_motion_type() == SoccerBall::MOVE)
        {
            b.set_motion_type(SoccerBall::START_DRIBBLE);
        }
        else if (b.get_motion_type() == SoccerBall::OUTSIZE)
        {
        	b.set_motion_type(SoccerBall::OUTSIZE);
        }
        else if (b.get_motion_type() == SoccerBall::PENALTY)
        {
			b.set_pos(B_PENALTY_LOCATION_X, B_PENALTY_LOCATION_Y);
            b.set_speed(0);
            b.set_motion_type(SoccerBall::PENALTY);
			b.set_state(PenaltyState::alloc());
        	return;
        }
        else if (b.get_motion_type() == SoccerBall::FREE)
        {
			b.set_pos(b.get_boll_start_pos().x, b.get_boll_start_pos().y);
            b.set_speed(0);
            b.set_motion_type(SoccerBall::FREE);
			b.set_state(FreeState::alloc());
        	return;
        }
        else if (b.get_motion_type() == SoccerBall::CORNER)
        {
        	b.set_pos(b.get_boll_start_pos().x, b.get_boll_start_pos().y);
            b.set_speed(0);
            b.set_motion_type(SoccerBall::CORNER);
			b.set_state(CornerState::alloc());
        	return;
        }/*else if(b.get_motion_type() == SoccerBall::GOAL_FLY){
        	b.set_motion_type(SoccerBall::GOAL_FLY);
        	b.set_state();
        }*/
        else
        {
            b.set_motion_type(SoccerBall::DRIBBLE);
    		if ((abs((int)(b.get_pos().x - owner->get_pos().x))<2)&&(abs((int)(b.get_pos().x - owner->get_pos().x))<2))
    		{
    			b.set_speed_add(1);
    		}

    		if ((abs((int)(b.get_pos().x - owner->get_pos().x))>10)||(abs((int)(b.get_pos().x - owner->get_pos().x))>10))
    		{
    			b.set_speed_add(-1);
    		}

    		b.set_speed(owner->get_speed());
            b.set_heading(owner->get_heading());
            if (b.get_speed_add() == 1)
            {
            	b.set_pos(b.get_pos() + b.get_heading() * owner->get_speed());
            }
            else
            {
            	b.set_pos(b.get_pos() - b.get_heading() * owner->get_speed());
            }
            return;
        }
        b.set_heading(owner->get_heading());
        b.set_speed(owner->get_speed());
        b.set_pos(owner->get_pos());
    }
}
コード例 #12
0
ファイル: SoccerObjects.cpp プロジェクト: Arc0re/lithtech
void SoccerGoal::OnTouchNotify( HOBJECT hObj )
{
	CollisionInfo colInfo;
	DVector vBallVel;
	DBOOL bGoal;
	SoccerBall *pSoccerBall;
	DVector vPos, vDir, vDims;
	HOBJECT hPlayer;
	LMessage *pMsg;
	
	if( g_pServerDE->IsKindOf( g_pServerDE->GetObjectClass(hObj), m_hSoccerBall ))
	{
		pSoccerBall = ( SoccerBall * )g_pServerDE->HandleToObject( hObj );
		if( !pSoccerBall )
			return;

		// Already recorded this goal.  Ball should delete itself soon.
		if( pSoccerBall->IsMadeGoal( ))
			return;

		// Ball has to enter from correct side for directional goals
		if( m_bDirectional )
		{
			// Assume no goal
			bGoal = DFALSE;

			g_pServerDE->GetVelocity( hObj, &vBallVel );

			// Check if going in the right direction
			if( VEC_DOT( vBallVel, m_vGoalDirection ) > 0.0f )
			{
				bGoal = DTRUE;
			}
		}
		else
			bGoal = DTRUE;

		if( bGoal )
		{
			if(( hPlayer = pSoccerBall->GetLastPlayerTouched( )) == DNULL )
				return;
			// Send message to player and ball
			if( g_pServerDE->Common( )->CreateMessage( pMsg ) != LT_OK )
				return;
			pMsg->WriteByte( m_nTeamID );
			g_pServerDE->SendToObject( *pMsg, MID_GOAL, m_hObject, hPlayer, 0 );
			g_pServerDE->SendToObject( *pMsg, MID_GOAL, m_hObject, hObj, 0 );

			pMsg->Release();

			// Create special effects
			g_pServerDE->GetObjectPos( hObj, &vPos );
			g_pServerDE->GetVelocity( hObj, &vDir );
			VEC_MULSCALAR( vDir, vDir, -1.0f );
			VEC_SET( vDims, 25.0f, 25.0f, 25.0f );
			SetupClientGibFX( &vPos, &vDir, &vDims, ( SURFTYPE_FLESH/10 ) | SIZE_SMALL | TRAIL_BLOOD, 1.0f, 5 );

			// Play the sound
			if( m_hstrScoreSound )
			{
				g_pServerDE->GetObjectPos( m_hObject, &vPos );
				PlaySoundFromPos( &vPos, g_pServerDE->GetStringData( m_hstrScoreSound ), m_fRadius, SOUNDPRIORITY_MISC_MEDIUM );
			}

			SendTrigger( );
		}
	}
}