コード例 #1
0
ufo::SteeringDecision ufoplugin::AlignmentBehaviour::yield ( const float elapsedTime)
{
	assert( myPilot != 0 );
	
	Flock *flock = myPilot->getFlock();
	assert( flock != 0 );

	SteeringDecision retval;
	int neighbours = 0;

	//accumulate direction
	for ( Flock::const_iterator it=flock->begin(); it != flock->end(); ++it)
	{
		// TODO: test angle:
		Vec3f distance = (*it)->getPosition() - myPilot->getPosition();
		// only consider "near" neighbors:
		if ( neighbourDistance < 0.0f || lengthSquared(distance) <= neighbourDistance*neighbourDistance )
		{
			retval.direction += (*it)->getVelocity();
			neighbours++;
		}
	}
	if ( neighbours > 0 )
	{
		// we are only interested in the direction:
		retval.directionUsed = true;
		// compute average direction:
		retval.direction /= neighbours;
	}
	return retval;
}
コード例 #2
0
ファイル: Play.cpp プロジェクト: Bojam1/AI_Asteroids
void Play::Update(float time,  sf::RenderWindow& window){

	player->Update(time);

	for (int i = 0; i < 3; i++)
	{
		enemies[i].Update(time, player->GetPosition());
	}
	asteroid->Update(time);
	factoryShip->Update(time, player->GetPosition());
	AsteroidManager::GetInstance()->Update(time, player);
	PowerUpManager::GetInstance()->Update(time, player);
	BulletManager::GetInstance()->Update(time, player->GetPosition());

	if (action == "flock")
		flock.flocking();
	else
		flock.swarming(player->GetPosition());

	sf::Event Event;
	while (window.pollEvent(Event)){
		if ((Event.type == sf::Event::KeyPressed) && (Event.key.code == sf::Keyboard::Escape))
			window.close();
		if ((Event.type == sf::Event::KeyPressed && Event.key.code == sf::Keyboard::Space))
		{
			player->Shoot();
		}
		if ((Event.type == sf::Event::KeyPressed && Event.key.code == sf::Keyboard::S))
		if (action == "flock")
			action = "swarm";
		else
			action = "flock";
	}
}
コード例 #3
0
/* process keyboard special keys inputs */
void processSpecialKeys(int key, int x, int y) {

	/* turn flock leader */
	if (key == GLUT_KEY_LEFT) {
		bflock.direct_boid_leader(LEFT);
	}
	if (key == GLUT_KEY_RIGHT) {
		bflock.direct_boid_leader(RIGHT);
	}
	if (key == GLUT_KEY_UP) {
		bflock.direct_boid_leader(UP);
	}
	if (key == GLUT_KEY_DOWN) {
		bflock.direct_boid_leader(DOWN);
	}

	/* change fog density */
	if (key == GLUT_KEY_F1) {
		fog_density -= 0.00001;
		enable_fog();
		printf("# Fog Density: %3f\n", fog_density);
	}
	if (key == GLUT_KEY_F2) {
		fog_density += 0.00001;
		enable_fog();
		printf("# Fog Density: %3f\n", fog_density);
	}

}
コード例 #4
0
/* process keyboard input. receives key and mouse position */
void processNormalInput(unsigned char key, int x, int y) {

	// esc key code
	if (key == ESC_KEY_CODE) {
		exit(0);
	}

	/* change camera mode */
	if (key == 'c') {
		camera.change_mode();
	}

	/* add new boid to flock */
	if (key == 'a') {
		bflock.add_new_boid();
	}

	/* remove boid from flock */
	if (key == 'r') {
		bflock.remove_boid();
	}

	/* camera zoom-in, zoom-out */
	if (key == 'q') {
		camera.zoom(ZOOM_OUT);
	}

	if (key == 'e') {
		camera.zoom(ZOOM_IN);
	}

	/* activate debug mode */
	if (key == 'd') {
		debug = (debug + 1) % 2;
		nextFrame = true;
	}

	/* start simulation */
	if (key == 's') {
		started = true;
	}

	/* advance frame */
	if (key == 'n') {
		nextFrame = true;
	}

	/* enable-disable fog */
	if (key == 'f') {
		if (fog_enabled) {
			disable_fog();
			fog_enabled = false;
		} else {
			enable_fog();
			fog_enabled = true;
		}
	}

}
コード例 #5
0
ファイル: Play.cpp プロジェクト: Bojam1/AI_Asteroids
void Play::Draw(sf::RenderWindow& window){

	//game Window
	window.setView(Camera::GetInstance()->getView());

	window.draw(m_BGSprite);

	
	for (int i = 0; i < 3; i++)
	{
		enemies[i].Draw(window);
	}
	//asteroid->Draw(window);
	AsteroidManager::GetInstance()->Draw(window);
	PowerUpManager::GetInstance()->Draw(window);
	BulletManager::GetInstance()->Draw(window);
	factoryShip->Draw(window);
	//Draws all of the Boids out, and applies functions that are needed to update.
	for (int i = 0; i < shapes.size(); i++)
	{
		//Cout's removed due to slowdown and only needed for testing purposes
		//cout << "Boid "<< i <<" Coordinates: (" << shapes[i].getPosition().x << ", " << shapes[i].getPosition().y << ")" << endl;
		//cout << "Boid Code " << i << " Location: (" << flock.getBoid(i).location.x << ", " << flock.getBoid(i).location.y << ")" << endl;

		//Matches up the location of the shape to the boid
		shapes[i].setPosition(flock.getBoid(i).location.x, flock.getBoid(i).location.y);

		// Calculates the angle where the velocity is pointing so that the triangle turns towards it.
		float theta;
		theta = flock.getBoid(i).angle(flock.getBoid(i).velocity);
		shapes[i].setRotation(theta);

		if (BulletManager::GetInstance()->IsColliding(shapes[i].getPosition(), shapes[i].getRadius()))
		{
			shapes[i].setOutlineColor(sf::Color::Red);
		}
		window.draw(shapes[i]);

		player->Draw(window);
	}

		//MiniMap
		window.setView(MiniMap::GetInstance()->getStaticView());
		window.draw(m_BGMapSprite);
		for (int i = 0; i < shapes.size(); i++)
		{
			window.draw(shapes[i]);
		}
		factoryShip->Draw(window);
		BulletManager::GetInstance()->Draw(window);
		AsteroidManager::GetInstance()->Draw(window);
		player->DrawOnMap(window);

		//reset view
		window.setView(Camera::GetInstance()->getView());
}
コード例 #6
0
ファイル: main.cpp プロジェクト: stuntfarmboy/Projets
int main(){
	srand(time(NULL));
	sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "SpaceInvaders", sf::Style::Close);
	Player player(sf::Vector2f(5 * square.x, 18 * square.y));
	window.setKeyRepeatEnabled(false);

	Flock flock;

	sf::Clock chronoFlock, chronoBullet, chronoFlockBullet;
	while (window.isOpen()){
		sf::Event event;
		while (window.pollEvent(event)){
			if (event.type == sf::Event::Closed || (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape))
				window.close();
			if (event.type == sf::Event::KeyPressed){
				switch (event.key.code){
				case(sf::Keyboard::A) :
					if (player.pos().x > 1 * square.x)
						player.move(sf::Vector2f(-square.x,0));
					break;
				case(sf::Keyboard::D) :
					if (player.pos().x < 10 * square.x)
						player.move(sf::Vector2f(square.x,0));
					break;
				case(sf::Keyboard::Space) :
					player.fire();
					chronoBullet.restart();
					break;
				}
			}
		}
		window.clear(sf::Color::Black);
		if (chronoFlock.getElapsedTime().asMilliseconds() > 500){
			flock.move();
			chronoFlock.restart();
		}
		if (chronoFlockBullet.getElapsedTime().asMilliseconds() > 2000){
			flock.fire();
			chronoFlockBullet.restart();
		}
		if (chronoBullet.getElapsedTime().asMilliseconds() > 40){
			player.update();
			flock.update();
			chronoBullet.restart();
		}
		player.draw(window);
		flock.draw(window);
		window.display();
	}

	return 0;
}
コード例 #7
0
ファイル: Play.cpp プロジェクト: Bojam1/AI_Asteroids
Play::Play(int SCREEN_WIDTH, int SCREEN_HEIGHT)
{
	//sf::VideoMode desktop = sf::VideoMode::getDesktopMode();
	//const int window_height = desktop.height;
	//const int window_width = desktop.width;
	//cout << SCREEN_WIDTH << endl;
	float boidsSize = 8;
	
	factoryShip = new FactoryShip(sf::Vector2f(600, 500), 100);
	factoryShip->Load();
	player = new Player();
	
	//Enemy enemies[3];
	asteroid = new Asteroids(player->GetPosition());
	
	enemies[1] =  Enemy(sf::Vector2f(100, 100), 100);
	enemies[2] =  Enemy(sf::Vector2f(10, 10), 50);

	for (int i = 0; i < 3; i++)
	{
		enemies[i].Load();
	}

	m_BGTexture.loadFromFile("bg.jpg");
	m_BGSprite.setTexture(m_BGTexture);
	m_BGSprite.setPosition(0, 0);

	m_BGMapSprite.setTexture(m_BGTexture);
	m_BGMapSprite.setColor(sf::Color(255, 255, 255, 100));

	//Flock flock;
	//vector<sf::CircleShape> shapes;

	for (int i = 0; i < 25; i++) //Number of boids is hardcoded for testing pusposes.
	{
		//Boid b(rand() % window_width, rand() % window_height); //Starts the boid with a random position in the window.
		Boid b((SCREEN_WIDTH * 3) / 2, (SCREEN_HEIGHT * 3) / 2 - 150); //Starts all boids in the center of the screen
		sf::CircleShape shape(boidsSize, 3); //Shape with a radius of 10 and 3 points (Making it a triangle)

		//Changing the Visual Properties of the shape
		//shape.setPosition(b.location.x, b.location.y); //Sets position of shape to random location that boid was set to.
		shape.setPosition(SCREEN_WIDTH, SCREEN_HEIGHT); //Testing purposes, starts all shapes in the center of screen.
		shape.setOutlineColor(sf::Color(0, 255, 0));
		shape.setFillColor(sf::Color::Green);
		shape.setOutlineColor(sf::Color::White);
		shape.setOutlineThickness(1);
		shape.setRadius(boidsSize);

		//Adding the boid to the flock and adding the shapes to the vector<sf::CircleShape>
		flock.addBoid(b);
		shapes.push_back(shape);

	}

	Camera::GetInstance()->Init(SCREEN_WIDTH, SCREEN_HEIGHT);
	MiniMap::GetInstance()->Init(SCREEN_WIDTH, SCREEN_HEIGHT);
	AsteroidManager::GetInstance()->Init(player->GetPosition());
	PowerUpManager::GetInstance()->Init();
}
コード例 #8
0
	void simulator(){
		printf("Duck simulator: with gooseadapter\n");
		/*Quackable* mallardDuck = new QuackCounter(new MallardDuck());
		Quackable* redheadDuck= new QuackCounter(new RedheadDuck());
		Quackable* duckCall = new QuackCounter(new DuckCall());
		Quackable* rubberDuck = new QuackCounter(new RubberDuck());
		Quackable* googseDuck = new GooseAdapter(*(new Goose()));*/
		AbstractDuckFactory* duckFactory = new CountingDuckFactory();
		Quackable* mallardDuck = duckFactory->createMallardDuck();
		Quackable* redheadDuck= duckFactory->createRedheadDuck();
		Quackable* duckCall = duckFactory->createDuckCall();
		Quackable* rubberDuck = duckFactory->createRubberDuck();
		Quackable* googseDuck = new GooseAdapter(*(new Goose()));
		simulate(mallardDuck);
		simulate(redheadDuck);
		simulate(duckCall);
		simulate(rubberDuck);
		simulate(googseDuck);

		/*simulate(*mallardDuck);
		simulate(*redheadDuck);
		simulate(*duckCall);
		simulate(*rubberDuck);*/
		Flock* flockOfDucks = new Flock();
		flockOfDucks->add(redheadDuck);
		flockOfDucks->add(duckCall);
		flockOfDucks->add(rubberDuck);
		flockOfDucks->add(googseDuck);
		printf("\nsimulater flockOfDucks\n");
		simulate(flockOfDucks);

		Flock* flockOfMallards = new Flock();
		Quackable* mallardOne = duckFactory->createMallardDuck();
		Quackable* mallardTwo = duckFactory->createMallardDuck();
		Quackable* mallardThree = duckFactory->createMallardDuck();
		Quackable* mallardFour = duckFactory->createMallardDuck();
		flockOfMallards->add(mallardOne);
		flockOfMallards->add(mallardTwo);
		flockOfMallards->add(mallardThree);
		flockOfMallards->add(mallardFour);
		printf("\nsimulater flockOfMallards\n");
		simulate(flockOfMallards);

		printf("\nobserver\n");
		Quackologist* quacklogist = new Quackologist();
		flockOfDucks->registerObserver(quacklogist);
		simulate(flockOfDucks);
		printf("\nThe ducks quacked %d times\n", QuackCounter::getQuacks());
	}
コード例 #9
0
/* program main loop */
void main_loop(int data) {

	glutTimerFunc(REFRESH_RATE, main_loop, 1);

	if (started) {
		/* check if debug mode is active */
		if (!debug || nextFrame) {
			camera.update_camera(bflock.flock_center, bflock.leader.speed);
			bflock.update_boids(w.get_objects());
		}
		if (debug && nextFrame) {
			bflock.debug_flock();
			w.debug_world();
			camera.debug_camera();
			nextFrame = false;
		}
	}

	/* redraw scene */
	glutPostRedisplay();
}
コード例 #10
0
/* display callback function */
void render_scene() {

	/* Limpar todos os pixels */
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	if (started) {
		camera.look_at();
		w.draw_world();
		bflock.draw_boids();
	}
	else {
		draw_text("- cubieboids -", screenWidth / 2, screenHeight / 2);
		draw_text("press 's' to start!", screenWidth / 2, screenHeight / 2 - 20);
	}

	/* Não esperar! */
	glFlush();

}
コード例 #11
0
ファイル: Main.cpp プロジェクト: Nluce/Flocking
int main(int argc, char ** argv)
{
	//Initialise GLFW
	if (!glfwInit())
	{
		return -1;
	}

	GLFWwindow* window;
	window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Flocking Demo", NULL, NULL);
	if (!window)
	{
		glfwTerminate();
		return -2;
	}


	glfwMakeContextCurrent(window);
	if (glewInit() != GLEW_OK)
	{
		// OpenGL didn't start-up! shutdown GLFW and return an error code
		glfwTerminate();
		return -3;
	}

	Text font = Text("NLuceGameEngine/fonts/font.png");

	//create shader program
	//	GLuint uiProgramFlat = CreateProgram("VertexPositionColorUV.glsl.glsl", "FlatFragmentShader.glsl");
	GLuint uiProgramColorTexture = CreateProgram("Shaders/VertexPositionColorUV.glsl", "Shaders/TexturedFragmentShader.glsl");
	//	GLuint uiProgramTexture = CreateProgram("VertexPositionUV.glsl", "FragmentPositionUV.glsl");

	//find the position of the matrix variable in the shader so we can send info there later
	GLuint shaderIDMVP = glGetUniformLocation(uiProgramColorTexture, "MVP");

	// screen is with origin at lower left (y is up)
	mat4 screen = glm::ortho(0.0f, (float)SCREEN_WIDTH, 0.0f, (float)SCREEN_HEIGHT);

	float centerX = SCREEN_WIDTH / 2;
	float centerY = SCREEN_HEIGHT / 2;

	// screenCentered is with origin at center (y is up)
	mat4 screenCentered = glm::ortho(-centerX, centerX, -centerY, centerY);

	// screenCenteredx2 is centered and scaled up by 2
	mat4 screenCenteredx2 = scale(screenCentered, vec3(2, 2, 1));

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	mat4 world = screen;

	Sprite::defaultMatrix = &world;
	Sprite::defaultMatrixLocation = shaderIDMVP;
	//	world = translate(world, vec3(centerX, centerY, 0)); // center on screen
	//	world = scale(world, vec3(gameScale, gameScale, 1.0)); // scale to screen
	//	world = translate(world, vec3(0, -cameraHeight, 0)); // vertical scrolling

	Flock flock;

	/*    GAME LOOP      */

	while (!glfwWindowShouldClose(window))
	{
		theGame.startFrame();
		{
			glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
			glClear(GL_COLOR_BUFFER_BIT);
			glUseProgram(uiProgramColorTexture);

			flock.move(theGame.elapsedTime);
			flock.draw();

			glfwSwapBuffers(window);
		}

		//poll for and process events
		glfwPollEvents();
	}

	glfwTerminate();
	return 0;
}
コード例 #12
0
ファイル: boids.cpp プロジェクト: semajrolyat/gwucs6555
void generate_flock( const Vector3& flock_center, const unsigned int& number_of_boids, const double& flock_extens ) {
    Boid* boid;
    Flock* flock = new Flock();
    flocks.push_back( flock );

    // assign to master list of boids
    double radius = 1.0;
    double height = 3.0;
    for( unsigned int i = 0; i < number_of_boids; i++ ) {
        boid = new Boid();
        boid->body.insert( MeshLoader::cone( radius, height, 16 ) );
        double x = flock_center.x() + ( (double) rand() / (double) RAND_MAX ) * flock_extens - flock_extens / 2.0;
        double y = 0.0;
        double z = flock_center.z() + ( (double) rand() / (double) RAND_MAX ) * flock_extens - flock_extens / 2.0;
        boid->body.pose.position = Vector3( x, y, z );

        boid->body.mass = 1.0;
        boid->goal = BOID_GOAL_LOCAL;
        boid->role = BOID_ROLE_FOLLOWER;
        boid->motivator_detector.position = Vector3( 0.0, 0.0, height );
        boid->base_orientation = Vector3( 0.0, PI/2.0, 0.0 );
        //boid->body.pose.orientation = Vector3( 0.0, PI/2.0, 0.0 );

        // back of the envelope reassessment if no collision anticipated
        boid->frames_till_reassess_trajectory = 5;
        // rate of yaw in terms of keyframes
        boid->yaw_rate_per_frame = RAD_PER_DEG;
        // forward velocity in terms of keyframes
        boid->max_forward_velocity_per_frame = 0.001;


        // add it to the master list of boids
        boids.push_back( boid );

        flock->add( boid );
        if( i == 0 ) {
            flock->leader = boid;
            boid->goal = BOID_GOAL_GLOBAL;
            boid->role = BOID_ROLE_LEADER;

            Vector3 base_orientation_vector = boid->motivator_detector.position;
            base_orientation_vector.normalize();
            Vector3 base_orientation_angle = boid->base_orientation;

            Vector3 orientation = boid->body.pose.orientation;

            Vector3 motivator_direction = motivator.position - boid->body.pose.position;
            motivator_direction.normalize();

            // calculate the angle between the direction to the motivator and the orientation of the boid
            double theta = angle_in_x_z( base_orientation_vector, motivator_direction );

            boid->body.pose.orientation = Vector3( 0.0, theta, 0.0 );

            //
            boid->body.trajectory.insert_keyframe( 1, boid->body.pose );
            Pose pose = Pose( motivator.position, boid->body.pose.orientation );
            boid->body.trajectory.insert_keyframe( 200, pose );

            boid->body.trajectory.construct_trajectory();

            boid->body.trajectory.prev_keyframe_id = 0;
            boid->body.trajectory.next_keyframe_id = 1;
            boid->body.trajectory.spline_basis = CubicSpline::basisUniformNonrationalBSpline();
            boid->body.trajectory.spline_arclength_map = CubicSpline::map_spline( CUBIC_SPLINE_B, boid->body.trajectory.controlpoints );
            boid->body.trajectory.cyclic = true;
        } else {
            Vector3 base_orientation_vector = boid->motivator_detector.position;
            base_orientation_vector.normalize();
            Vector3 boid_forward_movement_vector = base_orientation_vector * boid->max_forward_velocity_per_frame;
            // determine if left turn, right turn or straight.
            // draw a vector from the boid to the motivator to determine direction
            //Vector3 base_orientation_angle = boid->base_orientation;

            //Vector3 orientation = boid->body.pose.orientation;

            Vector3 motivator_direction = motivator.position - boid->body.pose.position;
            motivator_direction.normalize();

            // calculate the angle between the direction to the motivator and the orientation of the boid
            double theta = angle_in_x_z( base_orientation_vector, motivator_direction );
            double rads_per_frame = boid->yaw_rate_per_frame;
            assert( boid->frames_till_reassess_trajectory > 0 );
            if( theta < boid->yaw_rate_per_frame )
                rads_per_frame = theta / (double) boid->frames_till_reassess_trajectory;
            double rads_over_keyframe = rads_per_frame * boid->frames_till_reassess_trajectory;
            if( theta < 0 )
                rads_over_keyframe = -rads_over_keyframe;
            Quaternion q = Quaternion( sin(rads_over_keyframe/2.0), 0.0, cos(rads_over_keyframe/2.0), 0.0 );
            Matrix3 R = q.matrix3();
            Pose p1 = boid->body.pose;
            Vector3 position = boid->body.pose.position + R * boid_forward_movement_vector;
            double orientation_y = boid->body.pose.orientation.y() + rads_over_keyframe;
            Pose p2 = Pose( position, Vector3( 0.0, orientation_y, 0.0 ) );
            boid->body.trajectory.insert_keyframe( frame_id, p1 );
            boid->body.trajectory.insert_keyframe( frame_id + boid->frames_till_reassess_trajectory, p2 );
            boid->body.trajectory.construct_trajectory();

            boid->body.trajectory.prev_keyframe_id = 0;
            boid->body.trajectory.next_keyframe_id = 1;
            boid->body.trajectory.spline_basis = CubicSpline::basisUniformNonrationalBSpline();
            boid->body.trajectory.spline_arclength_map = CubicSpline::map_spline( CUBIC_SPLINE_B, boid->body.trajectory.controlpoints );
            boid->body.trajectory.cyclic = false;
        }
    }
}
コード例 #13
0
ファイル: compound.cpp プロジェクト: whypro/design_pattern
    void simulate(AbstractDuckFactory* duckFactory)
    {
        Quackable* readheadDuck = duckFactory->createRedheadDuck();
        Quackable* duckCall = duckFactory->createDuckCall();
        Quackable* rubberDuck = duckFactory->createRubberDuck();
        Quackable* gooseAdapter = new GooseAdapter(new Goose);

        Flock* flockOfDucks = new Flock;
        flockOfDucks->add(readheadDuck);
        flockOfDucks->add(duckCall);
        flockOfDucks->add(rubberDuck);
        flockOfDucks->add(gooseAdapter);

        Quackable* mallardDuckOne = duckFactory->createMallardDuck();
        Quackable* mallardDuckTwo = duckFactory->createMallardDuck();
        Quackable* mallardDuckThree = duckFactory->createMallardDuck();
        Quackable* mallardDuckFour = duckFactory->createMallardDuck();

        Flock* flockOfMallards = new Flock;
        flockOfMallards->add(mallardDuckOne);
        flockOfMallards->add(mallardDuckTwo);
        flockOfMallards->add(mallardDuckThree);
        flockOfMallards->add(mallardDuckFour);

        flockOfDucks->add(flockOfMallards);

        Quackologist quackologist;
        flockOfDucks->registerObserver(&quackologist);

        std::cout << "Duck Simulator: Whole Flock Simulation" << std::endl;
        simulate(flockOfDucks);

        std::cout << "Duck Simulator: Mallard Flock Simulation" << std::endl;
        simulate(flockOfMallards);

        std::cout << QuackCounter::getQuacks() << std::endl;

        delete flockOfDucks;
    }
コード例 #14
0
ファイル: main.cpp プロジェクト: Alycen/Asteroid_Wars
int main()
{
	float boidsSize = 3;
	string action = "flock";

	//Gets the resolution, size, and bits per pixel for the screen of the PC that is running this program.
	sf::VideoMode desktop = sf::VideoMode::getDesktopMode();
	const int window_height = desktop.height;
	const int window_width = desktop.width;

	//Having the style of "None" gives a false-fullscreen effect for easier closing and access.
	//No FPS limit of V-sync setting needed for it may cause unnecessary slowdown.
	sf::RenderWindow window(sf::VideoMode(desktop.width, desktop.height, desktop.bitsPerPixel), "Boids", sf::Style::None); 
	
	//Create flock, vector of shapes, and initialize boids
	Flock flock;
	vector<sf::CircleShape> shapes;

	for (int i = 0; i < 100; i++) //Number of boids is hardcoded for testing pusposes.
	{
		//Boid b(rand() % window_width, rand() % window_height); //Starts the boid with a random position in the window.
		Boid b(window_width / 3, window_height / 3); //Starts all boids in the center of the screen
		sf::CircleShape shape(8,3); //Shape with a radius of 10 and 3 points (Making it a triangle)

		//Changing the Visual Properties of the shape
		//shape.setPosition(b.location.x, b.location.y); //Sets position of shape to random location that boid was set to.
		shape.setPosition(window_width, window_height); //Testing purposes, starts all shapes in the center of screen.
		shape.setOutlineColor(sf::Color(0,255,0));
		shape.setFillColor(sf::Color::Green);
		shape.setOutlineColor(sf::Color::White);
		shape.setOutlineThickness(1);
		shape.setRadius(boidsSize);

		//Adding the boid to the flock and adding the shapes to the vector<sf::CircleShape>
		flock.addBoid(b);
		shapes.push_back(shape);
	}

	while (window.isOpen())
	{	
		//Event used to close program when window is closed
		sf::Event event;
		while (window.pollEvent(event))
		{
			//"close requested" event: we close the window
			//Implemented alternate ways to close the window. (Pressing the escape, X, and BackSpace key also close the program.)
			if ((event.type == sf::Event::Closed) || 
				(event.type == sf::Event::KeyPressed &&
				 event.key.code == sf::Keyboard::Escape) ||
				(event.type == sf::Event::KeyPressed &&
				 event.key.code == sf::Keyboard::BackSpace) ||
				(event.type == sf::Event::KeyPressed &&
				 event.key.code == sf::Keyboard::X))
			{
				window.close();
			}
			if ((event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space))
				if (action == "flock")
					action = "swarm";
				else
					action = "flock";

		}

		//check for mouse click, draws and adds boid to flock if so.
		if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
		{
			//Gets mouse coordinates, sets that as the location of the boid and the shape
			sf::Vector2i mouseCoords = sf::Mouse::getPosition(window);
			Boid b(mouseCoords.x, mouseCoords.y, true);
			sf::CircleShape shape(10,3);

			//Changing visual properties of newly created boid
			shape.setPosition(mouseCoords.x, mouseCoords.y);
			shape.setOutlineColor(sf::Color(255, 0, 0));
			shape.setFillColor(sf::Color(255, 0, 0));
			shape.setOutlineColor(sf::Color::White);
			shape.setOutlineThickness(1);
			shape.setRadius(boidsSize);

			//Adds newly created boid and shape to their respective data structure
			flock.addBoid(b);
			shapes.push_back(shape);

			//New Shape is drawn
			window.draw(shapes[shapes.size()-1]);
		}
		//Clears previous frames of visualization to not have clutter. (And simulate animation)
		window.clear();

		//Draws all of the Boids out, and applies functions that are needed to update.
		for (int i = 0; i < shapes.size(); i++)
		{
			window.draw(shapes[i]);

			//Cout's removed due to slowdown and only needed for testing purposes
			//cout << "Boid "<< i <<" Coordinates: (" << shapes[i].getPosition().x << ", " << shapes[i].getPosition().y << ")" << endl;
			//cout << "Boid Code " << i << " Location: (" << flock.getBoid(i).location.x << ", " << flock.getBoid(i).location.y << ")" << endl;

			//Matches up the location of the shape to the boid
			shapes[i].setPosition(flock.getBoid(i).location.x, flock.getBoid(i).location.y);

			// Calculates the angle where the velocity is pointing so that the triangle turns towards it.
			float theta;
			theta = flock.getBoid(i).angle(flock.getBoid(i).velocity);
			shapes[i].setRotation(theta);

			// These if statements prevent boids from moving off the screen through warpping
			// If boid exits right boundary
			if (shapes[i].getPosition().x > window_width)
				shapes[i].setPosition(shapes[i].getPosition().x - window_width, shapes[i].getPosition().y);
			// If boid exits bottom boundary
			if (shapes[i].getPosition().y > window_height)
				shapes[i].setPosition(shapes[i].getPosition().x, shapes[i].getPosition().y - window_height);
			// If boid exits left boundary
			if (shapes[i].getPosition().x < 0)
				shapes[i].setPosition(shapes[i].getPosition().x + window_width, shapes[i].getPosition().y);
			// If boid exits top boundary
			if (shapes[i].getPosition().y < 0)
				shapes[i].setPosition(shapes[i].getPosition().x, shapes[i].getPosition().y + window_height);
		}

		//Applies the three rules to each boid in the flock and changes them accordingly.
		if (action == "flock")
			flock.flocking();
		else
			flock.swarming();

		//Updates the window with current values of any data that was modified.
		window.display();

	//This loop continues until window is closed. Continues the process of updating, drawing, rendering the boids, and the window.
	}
	return 0;

}