string PhysicsController::run(string myState, float time_since_last_tick)
{
	string game_state_request = " ";
	for(vector<Entity*>::size_type i = 0; i != controlled_entities.size(); i++) 
	{
		if(controlled_entities[i]->getGameState()==myState)
		{
			if(controlled_entities[i]->getActive())
			{
				//PULL THE MOVING OBJECTS INFORMATION
				PhysicsComponent* physics = (PhysicsComponent*)controlled_entities[i]->getComponent("Physics");
				PositionComponent* position = (PositionComponent*)controlled_entities[i]->getComponent("Position");

				//PULLING ALL THE MASS AND FORCE INFORMATION

				float total_mass = 0 + physics->getMass();
				float total_translation [2] = {0,0};

				float moment_of_inertia = 0 + physics->getMass();
				float total_torque = 0;

				if( controlled_entities[i]->checkIfHasComponent("Collection"))
				{
					CollectionComponent* collection = (CollectionComponent*) controlled_entities[i]->getComponent("Collection");
					vector<Entity*> attached_entities = collection->getAttachedEntities();

					//Cycling through attached entities
					for(vector<Entity*>::size_type p = 0; p != attached_entities.size(); p++) 
					{
						Entity* attached_entity = attached_entities[p];

						TetheredComponent* tethered = (TetheredComponent*) attached_entity->getComponent("Tethered");
						PhysicsComponent* attached_physics = (PhysicsComponent*) attached_entity->getComponent("Physics");
						PositionComponent* attached_position = (PositionComponent*) attached_entity->getComponent("Position");
						RocketComponent* rocket = (RocketComponent*) attached_entity->getComponent("Rocket");

						float radian_from_center_mass = tethered->getDirectionRadian();
						float radian_to_center_mass = radian_from_center_mass + 3.1415926;
						float t = attached_position->getAngle() - radian_to_center_mass ;
				
						tethered->setT(t);

						//Translational
						vector<float> attached_vector_forces = attached_physics->getNetTranslationalForce();
						total_translation[0] += attached_vector_forces[0];
						total_translation[1] += attached_vector_forces[1];
					
						total_mass+= attached_physics->getMass();

						//Angular
						float attached_net_angular_force = attached_physics->getNetAngularForce();
						total_torque += attached_net_angular_force;

						float distance = tethered->getDistance();
						moment_of_inertia += attached_physics->getMass()*(distance*distance);
					}
			
				}

				//Apparently on forces that have a distance can spin it
				//So after we've pulled all the angular forces we can find the angular acceleration

				//and then you use torque = I*a

				physics->setAngularAcceleration(total_torque/moment_of_inertia);
		

				//PLANAR MOVEMENT

				//We already have the tethered objects' forces so now we need the forces affectin the main object itself
				vector<float> vector_forces = physics->getNetTranslationalForce();
				total_translation[0] += vector_forces[0];
				total_translation[1] += vector_forces[1];
		

				//Calculating the net acceleration net forces and net mass
				physics->setAccelerationX(total_translation[0]/total_mass);
				physics->setAccelerationY(total_translation[1]/total_mass);

				//Determine its new velocity
				physics->setVelocityX(physics->getVelocity()[0]+physics->getAcceleration()[0]*time_since_last_tick);
				physics->setVelocityY(physics->getVelocity()[1]+physics->getAcceleration()[1]*time_since_last_tick);

				//Determine its new position if its not tethered to something
				if( !controlled_entities[i]->checkIfHasComponent("Tethered"))
				{
					position->setX(position->getPosition()[0]+physics->getVelocity()[0]*time_since_last_tick);
					position->setY(position->getPosition()[1]+physics->getVelocity()[1]*time_since_last_tick);
				}
			
				//ANGULAR MOVEMENT
				//	Both tethered and collected entities get this because a tethered can be rotating on its own
				//	on top of being rotated by the collectors movement.
				//  On it's own, a tethered object cannot have an angular acceleration, it must be machine assisted.
		
				physics->setAngularVelocity(physics->getAngularVelocity()+physics->getAngularAcceleration()*time_since_last_tick);
				position->setAngle(position->getAngle()+physics->getAngularVelocity()*time_since_last_tick);

				//To make sure the tethered objects get moved we make sure the collector handles them we he is passed into this controller
				if( controlled_entities[i]->checkIfHasComponent("Collection"))
				{
					CollectionComponent* collection = (CollectionComponent*) controlled_entities[i]->getComponent("Collection");
					vector<Entity*> attached_entities = collection->getAttachedEntities();

					//Go throuhg all the attached entities and update their tethered position wiht the new positon of the collector
					for(vector<Entity*>::size_type p = 0; p != attached_entities.size(); p++) 
					{
						Entity* attached_entity = attached_entities[p];

						TetheredComponent* tethered = (TetheredComponent*) attached_entity->getComponent("Tethered");
						PhysicsComponent* attached_physics = (PhysicsComponent*) attached_entity->getComponent("Physics");
						PositionComponent* attached_position = (PositionComponent*) attached_entity->getComponent("Position");

						////Determine its new position

						//As the object spins so will all the tethered objects
						tethered->setDirectionRadian( tethered->getDirectionRadian() + physics->getAngularVelocity()*time_since_last_tick);

						float radian_from_center_mass = tethered->getDirectionRadian();
						float radian_to_center_mass = radian_from_center_mass + 3.1415926;
						attached_position->setAngle(radian_to_center_mass + tethered->getT());
				
						//Need to update the angle of the rocket as the main ship spins

						//Set the tethered object to the new position in the new direction
						attached_position->setX( position->getPosition()[0] + cos(tethered->getDirectionRadian())*tethered->getDistance());
						attached_position->setY( position->getPosition()[1] + sin(tethered->getDirectionRadian())*tethered->getDistance());
					}
				}
				position->calculateBucketPosition(BUCKET_WIDTH);
			}
		}
	}
	return game_state_request;
}
Ejemplo n.º 2
0
string RocketController::run(string myState)
{
	string game_state_request;
	for(vector<Entity*>::size_type i = 0; i != controlled_entities.size(); i++) 
	{
		Entity* ent = controlled_entities[i];
		if(ent->getGameState() == myState)
			{
			if(ent->getActive())
			{
				//SUBTRACT FUEL
				SpaceshipComponent* spaceship = (SpaceshipComponent*) ent->getComponent("Spaceship");
				float current_fuel = spaceship->getCurrentFuel();

				CollectionComponent* collection = (CollectionComponent*) ent->getComponent("Collection");
				vector<Entity*> attached_entities = collection->getAttachedEntities();

				//Cycling through attached entities
				for(vector<Entity*>::size_type p = 0; p != attached_entities.size(); p++) 
				{
					Entity* attached_entity = attached_entities[p];
					attached_entity->setActive(true);

					if(attached_entity->checkIfHasComponent("Rocket"))
					{
						RocketComponent* rocket = (RocketComponent*) attached_entity->getComponent("Rocket");
						TetheredComponent* tethered = (TetheredComponent*) attached_entity->getComponent("Tethered");
						PositionComponent* position = (PositionComponent*) attached_entity->getComponent("Position");
						PhysicsComponent* physics = (PhysicsComponent*) attached_entity->getComponent("Physics");

						physics->clearForces();

						if(rocket->getOnOrOff())
						{
							if(spaceship->getCurrentFuel() - rocket->getFuelConsumption() >= 0)
							{
								//The rocket is on
								float force_exerted = rocket->getForceExerted();
								float angle = position->getAngle();

								float x =  rocket->getForceExerted()*cos(angle);
								float y =  rocket->getForceExerted()*sin(angle);
						
								physics->addTranslationalForce(x,y);

								//Angular Forces

								float distance = tethered->getDistance();
								float angular_force = distance *  rocket->getForceExerted() * -sin(tethered->getT());

								physics->addAngularForce(angular_force);

								//Burning fuel
								spaceship->subtractCurrentFuel(rocket->getFuelConsumption());
							}
						}
					}
				}
			}
			else
			{
				CollectionComponent* collection = (CollectionComponent*) ent->getComponent("Collection");
				vector<Entity*> attached_entities = collection->getAttachedEntities();

				//Cycling through attached entities
				for(vector<Entity*>::size_type p = 0; p != attached_entities.size(); p++) 
				{
					attached_entities[p]->setActive(false);
				}
			}
		}
	}
	return game_state_request;
}