コード例 #1
0
void OurEnemyActor::walkingAgent(ACTORid enemyID, EnemyTeam **team, int teamCount)
{
    float origin[3] = {0,0,0};

    //敵人位置
    float enemyPos[3];
    FnActor enemy;
    enemy.Object(enemyID);
    enemy.GetPosition(enemyPos);
    //自己位置
    float selfPos[3];
    FnActor self;
    self.Object(aID);
    self.GetPosition(selfPos);
    float selfFDir[3], selfUDir[3];
    actor.GetDirection(selfFDir,selfUDir);

    float distance = twoPointDis(selfPos, enemyPos);

    float flockingPos[3];
    flockingPosition(flockingPos, selfPos, enemyPos, team, teamCount);
    float flockingDis = twoPointDis(flockingPos, origin);

    float newPos[3];
    newPos[0] = flockingPos[0]+selfPos[0];
    newPos[1] = flockingPos[1]+selfPos[1];
    newPos[2] = flockingPos[2]+selfPos[2];

    //先轉向再移動,再轉回來
    actorFaceTo(aID, newPos[0], newPos[1], newPos[2]);
    actor.MoveForward(flockingDis,true);
    //actor.SetWorldDirection(selfFDir,selfUDir);
    actorFaceTo(aID, enemyPos[0], enemyPos[1], enemyPos[2]);
    //actor.SetPosition(newPos);

    if(distance < AWARE_DISTANCE)
    {

        if(distance <= COMBAT_DISTANCE)
        {
            sendAction(ourCombatIdleAction);
        }
        else
        {
            sendAction(ourRunAction);
            actor.MoveForward(SPEED, TRUE, FALSE, 0.0f, TRUE);
        }
    }
    else
    {
        sendAction(ourIdleAction);
    }
}
コード例 #2
0
//計算在這個群體中適當的位置
void OurEnemyActor::flockingPosition(float *newPos, float *selfPos, float *targetPos, EnemyTeam **team, int teamCount)
{
    float attraction[3] = {0,0,0};

    //共有多少隊友離你夠近,會影響到調整距離
    int member_num = 0;
    for(int i = 0; i < teamCount; i++)
    {
        //驚動狀態的隊伍才考慮
        //if(team[i]->aware)
        {
            //separation & cohesion
            for(int mi = 0; mi < team[i]->member_num; mi++)
            {
                //只檢查沒掛的人,且不要把自己算進去
                if(team[i]->members[mi]->HP > 0 && team[i]->members[mi]->aID != this->aID)
                {
                    float friPos[3];
                    FnActor fri;
                    fri.Object(team[i]->members[mi]->aID);
                    fri.GetPosition(friPos);

                    float dis = sqrt(pow(friPos[0]-selfPos[0],2)
                                     +pow(friPos[1]-selfPos[1],2)
                                     +pow(friPos[2]-selfPos[2],2));

                    if(dis < OVERLAP_DISTANCE
                            ||(team[i] == this->team && dis < CROWDED_DISTANCE))
                    {
                        //separation
                        if(dis == 0)
                        {
                            attraction[0] += 1;
                            attraction[1] += 1;
                        }
                        else
                        {
                            attraction[0] += -(friPos[0]-selfPos[0])*pow(1-dis/CROWDED_DISTANCE,2);
                            attraction[1] += -(friPos[1]-selfPos[1])*pow(1-dis/CROWDED_DISTANCE,2);
                            attraction[2] += -(friPos[2]-selfPos[2])*pow(1-dis/CROWDED_DISTANCE,2);
                        }
                    }
                    else if(team[i] == this->team)
                    {
                        //cohesion
                        attraction[0] += (friPos[0]-selfPos[0])*pow((dis-CROWDED_DISTANCE)/(AWARE_DISTANCE-CROWDED_DISTANCE),2);
                        attraction[1] += (friPos[1]-selfPos[1])*pow((dis-CROWDED_DISTANCE)/(AWARE_DISTANCE-CROWDED_DISTANCE),2);
                        attraction[2] += (friPos[2]-selfPos[2])*pow((dis-CROWDED_DISTANCE)/(AWARE_DISTANCE-CROWDED_DISTANCE),2);
                    }
                    member_num++;
                }
            }
        }
    }

    //若與呂布重疊就分離
    float dis = sqrt(pow(targetPos[0]-selfPos[0],2)
                     +pow(targetPos[1]-selfPos[1],2)
                     +pow(targetPos[2]-selfPos[2],2));

    if(dis < OVERLAP_DISTANCE)
    {
        //separation
        if(dis == 0)
        {
            attraction[0] += 1;
            attraction[1] += 1;
        }
        else
        {
            attraction[0] += -(targetPos[0]-selfPos[0])*pow(1-dis/CROWDED_DISTANCE,2);
            attraction[1] += -(targetPos[1]-selfPos[1])*pow(1-dis/CROWDED_DISTANCE,2);
            attraction[2] += -(targetPos[2]-selfPos[2])*pow(1-dis/CROWDED_DISTANCE,2);
        }
        member_num++;
    }

    if(member_num > 0)
    {
        attraction[0] /= member_num;
        attraction[1] /= member_num;
        attraction[2] /= member_num;
    }

    /*
    //cohesion
    float sum[3] = {0,0,0};
    for(int i = 0; i < member_num; i++)
    {
    	if(team->members[i]->aID != aID)
    	{
    		float friPos[3];
    		FnActor fri;
    		fri.Object(team->members[i]->aID);
    		fri.GetPosition(friPos);

    		sum[0] += friPos[0];
    		sum[1] += friPos[1];
    		sum[2] += friPos[2];
    	}
    }
    float avg[3] = {sum[0]/member_num,
    				sum[1]/member_num,
    				sum[2]/member_num};
    float avgDis = sqrt((avg[0]-selfPos[0])*(avg[0]-selfPos[0])+
    					(avg[1]-selfPos[1])*(avg[1]-selfPos[1])+
    					(avg[2]-selfPos[2])*(avg[2]-selfPos[2]));

    float cohesion[3] = {(avg[0]-selfPos[0])*pow((avgDis-crowdedDistance)/(awareDistance-crowdedDistance),2),
    					 (avg[1]-selfPos[1])*pow((avgDis-crowdedDistance)/(awareDistance-crowdedDistance),2),
    					 (avg[2]-selfPos[2])*pow((avgDis-crowdedDistance)/(awareDistance-crowdedDistance),2)};
    					 */

    //align
    float align[3] = {0,0,0};
    /*
    float sumV[3] = {0,0,0};
    for(int i = 0; i < member_num; i++)
    {
    	if(team->members[i]->aID != aID && team->members[i]->HP > 0)
    	{
    		float friPos[3];
    		FnActor fri;
    		fri.Object(team->members[i]->aID);
    		fri.GetPosition(friPos);

    		float vx = (targetPos[0]-friPos[0]);
    		float vy = (targetPos[1]-friPos[1]);
    		float vz = (targetPos[2]-friPos[2]);
    		float dis = sqrt(sumV[0]*sumV[0]+sumV[1]*sumV[1]+sumV[2]*sumV[2]);
    		if(dis != 0)
    		{
    			sumV[0] += vx/dis;
    			sumV[1] += vy/dis;
    			sumV[2] += vz/dis;
    		}
    	}
    }
    if(member_num > 0)
    {
    	align[0] = sumV[0]/member_num;
    	align[1] = sumV[1]/member_num;
    	align[1] = sumV[2]/member_num;
    }
    */
    newPos[0] = attraction[0]+align[0];
    newPos[1] = attraction[1]+align[1];
    newPos[2] = attraction[2]+align[2];
}