Пример #1
0
b2Vec2 MapController::steeringBehaviourSeparation(Agent &agent)
{
	b2Vec2 totalForce = b2Vec2_zero;

	int neighboursCount = 0;

	for (int i = 0; i < agents.size(); i++) {
		Agent &a = agents[i];
		if (&a != &agent) {
			float32 distance = B2Vec2DHelper::distanceTo(agent.getPosition(), a.getPosition());
			if (distance < agent.minSeparation && distance > 0) {
				b2Vec2 pushForce = agent.getPosition() - a.getPosition();
				float32 length = pushForce.Normalize(); //Normalize returns the original length
				float32 r = (Agent::radius + Agent::radius);

				totalForce += pushForce * (1 - ((length - r) / (Agent::minSeparation - r)));//agent.minSeparation)));
				neighboursCount++;
			}
		}
	}

	if (neighboursCount == 0) {
		return totalForce; //Zero
	}

	return totalForce * (Agent::maxForce / neighboursCount);
}
Пример #2
0
b2Vec2 MapController::steeringBehaviourFlowField(Agent &agent)
{
	b2Vec2 floor = B2Vec2DHelper::floorV(agent.getPosition());

	int x = floor.x;
	int y = floor.y;

	b2Vec2 f00 = isValid(x, y) ? flow[x][y] : b2Vec2_zero;
	b2Vec2 f01 = isValid(x, y + 1) ? flow[x][y + 1] : b2Vec2_zero;
	b2Vec2 f10 = isValid(x + 1, y) ? flow[x + 1][y] : b2Vec2_zero;
	b2Vec2 f11 = isValid(x + 1, y + 1) ? flow[x + 1][y + 1] : b2Vec2_zero;

	//Do the x interpolations
	float32 xWeight = agent.getPosition().x - floor.x;

	b2Vec2 top = f00 * (1 - xWeight) +  f10 * xWeight;
	b2Vec2 bottom = f01 * (1 - xWeight) + f11 * xWeight;

	//Do the y interpolation
	float32 yWeight = agent.getPosition().y - floor.y;

	//This is now the direction we want to be travelling in (needs to be normalized)
	b2Vec2 desiredDirection = top * (1 - yWeight) + bottom * yWeight;
	desiredDirection.Normalize();

	//If we are centered on a grid square with no vector this will happen
	/*if (isnan(desiredDirection.LengthSquared())) {
		return b2Vec2_zero;
	}*/

	return steerTowards(agent, desiredDirection);
}
Пример #3
0
b2Vec2 MapController::steeringBehaviourSeek(Agent &agent, b2Vec2 dest)
{
	if (dest.x == agent.getPosition().x && dest.y == agent.getPosition().y) {
		return b2Vec2_zero;
	}

	b2Vec2 desired = dest - agent.getPosition();

	desired *= (Agent::maxSpeed / desired.Length());

	b2Vec2 velocityChange = desired - agent.getVelocity();

	return velocityChange * (Agent::maxForce / Agent::maxSpeed);
}
Пример #4
0
b2Vec2 MapController::steeringBehaviourAlignment(Agent &agent)
{
	b2Vec2 averageHeading = b2Vec2_zero;
	int neighboursCount = 0;

	//for each of our neighbours (including ourself)
	for (int i = 0; i < agents.size(); i++) {
		Agent &a = agents[i];
		float32 distance = B2Vec2DHelper::distanceTo(agent.getPosition(), a.getPosition());
		//That are within the max distance and are moving
		if (distance < Agent::maxCohesion && a.getVelocity().Length() > 0 && a.group == agent.group) {
			//Sum up our headings
			b2Vec2 head = a.getVelocity();
			head.Normalize();
			averageHeading += head;
			neighboursCount++;
		}
	}

	if (neighboursCount == 0) {
		return averageHeading; //Zero
	}

	//Divide to get the average heading
	averageHeading *= (1 / neighboursCount);

	//Steer towards that heading
	return steerTowards(agent, averageHeading);
}
Пример #5
0
b2Vec2 MapController::steeringBehaviourCohesion(Agent &agent)
{
	b2Vec2 centerOfMass = b2Vec2_zero;//agent.position().Copy();
	int neighboursCount = 0;

	for (int i = 0; i < agents.size(); i++) {
		Agent &a = agents[i];
		if (&a != &agent && a.group == agent.group) {
			float32 distance = B2Vec2DHelper::distanceTo(agent.getPosition(), a.getPosition());
			if (distance < Agent::maxCohesion) {
				//sum up the position of our neighbours
				centerOfMass += a.body->GetPosition();
				neighboursCount++;
			}
		}
	}

	if (neighboursCount == 0) {
		return b2Vec2_zero;
	}

	//Get the average position of ourself and our neighbours
	centerOfMass *= (1 / neighboursCount);

	//seek that position
	return steeringBehaviourSeek(agent, centerOfMass);
}
Пример #6
0
/**
 * Agent removes agent in location in group from world and takes resources
 * It also removes links to agents killed by combat (lenders, borrowers, etc.)
 * @param loc :Pointer to Location of the winning agent
 * @param grp : Pointer to Group containing location of losing agent (or possibly an empty location)
 * @see Combat Rule
 * @return true if agent exists at loc else false
 * @exception none
 */
bool AgentCombat::executeAction(Location *loc, group *grp)
{
    if (loc->hasAgent()) {
        Agent *winner = grp->getPrimeMover()->getAgent(); //must equal loc->getAgent()!
        if (grp->getMembers().size()!=0)/*!< we are moving somewhere */
        {
            if (grp->getMembers()[0]->hasAgent()==false) {/*!< moving to empty location */
                loc->getAgent()->incSugar(grp->getMembers()[0]->getSugar());/*!< eat sugar at destination */
                grp->getMembers()[0]->setSugar(0);/*!< sugar at location is consumed */
            }
            else{
                //std::cout <<"COMBAT!"<<std::endl;
                //1. Update victorious agent resources
                Agent *loser = grp->getMembers()[0]->getAgent();//only one member in group - the loser
                winner->incSugar(grp->getMembers()[0]->getReward());//*WHAT IF WE ADD SPICE?*
                grp->getMembers()[0]->setSugar(0);/*!< sugar at location is consumed */
                //2. Kill vanquished agent
                std::pair<int,int> currPosition=loser->getPosition();
                if (loser!=sim->killAgent(currPosition))
                {
                    std::cerr << "Delete of agent failed"<<std::endl;
                }
            }
            //Move agent to new position
            std::pair<int,int> currPosition=winner->getPosition();
            sim->setAgent(currPosition, nullptr);//remove old location ptr to agent
            winner->setPosition(grp->getMembers()[0]->getPosition());//set new position to new location
            sim->setAgent(grp->getMembers()[0]->getPosition(),winner);//add ptr to agent at new location
        }
        else{/*!< we are staying put-not moving */
            loc->getAgent()->incSugar(loc->getSugar());/*!< eat sugar at destination */
            loc->setSugar(0);/*!< sugar at location is consumed */
        }
        for(auto ag:winner->getChildren())/*!< Remove any links to killed children */
        {
            if (ag->isKilled()) {
                winner->removeChild(ag);
            }
        }
        winner->removeKilledLoans();/*!< remove loans with killed agents */
        winner->removeKilledFather();/*!< remove father link if he is killed */
        winner->removeKilledMother();/*!< remove mother link if she is killed */
        return true;
    }else{
        return false;/*!< no agent present so did nothing */
    }
}