diff --git a/projet-code/cgp/library/cgp/geometry/shape/mesh/structure/mesh.cpp b/projet-code/cgp/library/cgp/geometry/shape/mesh/structure/mesh.cpp
index b610d8eceda8fc5ee59ddece484b903e80e71dc8..9cd6ed1e8619012d4fc4f3cb0bac49c6922f3bbf 100644
--- a/projet-code/cgp/library/cgp/geometry/shape/mesh/structure/mesh.cpp
+++ b/projet-code/cgp/library/cgp/geometry/shape/mesh/structure/mesh.cpp
@@ -162,15 +162,15 @@ namespace cgp
 			vec3 const& p1 = m.position[f1];
 			vec3 const& p2 = m.position[f2];
 
-			// Check edge length
+			// Check edge length (changed for compilation)
 			if (norm(p1 - p0) < 1e-6f) {
-				std::cout<<warning+"Edge ("+str(f0)+","+str(f1)+") has zero length. position["+str(f0)+"]="+str(p0)+", position["+str(f1)+"]="+str(p1)+"; L_edge = "<<str(norm(p1-p0))<<std::endl;
+				//std::cout<<warning+"Edge ("+str(f0)+","+str(f1)+") has zero length. position["+str(f0)+"]="+str(p0)+", position["+str(f1)+"]="+str(p1)+"; L_edge = "<<str(norm(p1-p0))<<std::endl;
 			}
 			if (norm(p2 - p1) < 1e-6f) {
-				std::cout<<warning+"Edge ("+str(f2)+","+str(f1)+") has zero length. position["+str(f2)+"]="+str(p2)+", position["+str(f1)+"]="+str(p1)+"; L_edge = "<<str(norm(p2-p1))<<std::endl;
+				//std::cout<<warning+"Edge ("+str(f2)+","+str(f1)+") has zero length. position["+str(f2)+"]="+str(p2)+", position["+str(f1)+"]="+str(p1)+"; L_edge = "<<str(norm(p2-p1))<<std::endl;
 			}
 			if (norm(p2 - p0) < 1e-6f) {
-				std::cout<<warning+"Edge ("+str(f2)+","+str(f0)+") has zero length. position["+str(f2)+"]="+str(p2)+", position["+str(f0)+"]="+str(p0)+"; L_edge = "<<str(norm(p2-p0))<<std::endl;
+				//std::cout<<warning+"Edge ("+str(f2)+","+str(f0)+") has zero length. position["+str(f2)+"]="+str(p2)+", position["+str(f0)+"]="+str(p0)+"; L_edge = "<<str(norm(p2-p0))<<std::endl;
 			}
 		}
 
diff --git a/projet-code/cgp/library/cgp/graphics/opengl/texture/texture.cpp b/projet-code/cgp/library/cgp/graphics/opengl/texture/texture.cpp
index 6212a73cba7958ab03e40dd287774f2d5ce7e5d7..dc37ac862563a02dd55f9164a831cd4273d01725 100644
--- a/projet-code/cgp/library/cgp/graphics/opengl/texture/texture.cpp
+++ b/projet-code/cgp/library/cgp/graphics/opengl/texture/texture.cpp
@@ -145,8 +145,8 @@ namespace cgp
         GLenum const gl_format = format_to_data_type(format);    // expect GL_RGB or GL_RGBA
         GLenum const gl_component = format_to_component(format); // expect GL_UNISNGED_BYTE
 
-        std::cout << (gl_format == GL_RGBA) << std::endl;
-        std::cout << (gl_component == GL_UNSIGNED_BYTE) << std::endl;
+        //std::cout << (gl_format == GL_RGBA) << std::endl;
+        //std::cout << (gl_component == GL_UNSIGNED_BYTE) << std::endl;
 
         glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, format, h, h, 0, gl_format, gl_component, ptr(x_neg.data));
         glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, format, h, h, 0, gl_format, gl_component, ptr(x_pos.data));
diff --git a/projet-code/scenes_inf443/base/assets/electroball.png b/projet-code/scenes_inf443/base/assets/electroball.png
new file mode 100644
index 0000000000000000000000000000000000000000..ca60b56c5098553519a38f9c9a77355d6d7d3dbc
Binary files /dev/null and b/projet-code/scenes_inf443/base/assets/electroball.png differ
diff --git a/projet-code/scenes_inf443/base/assets/fireframes.png b/projet-code/scenes_inf443/base/assets/fireframes.png
new file mode 100644
index 0000000000000000000000000000000000000000..e65e2a1d1b9b840c92a513e394f8cef2e91b063a
Binary files /dev/null and b/projet-code/scenes_inf443/base/assets/fireframes.png differ
diff --git a/projet-code/scenes_inf443/base/assets/spriteice.png b/projet-code/scenes_inf443/base/assets/spriteice.png
new file mode 100644
index 0000000000000000000000000000000000000000..97f1c4885ac9bcfaf6c69a5890f814886c92e3a7
Binary files /dev/null and b/projet-code/scenes_inf443/base/assets/spriteice.png differ
diff --git a/projet-code/scenes_inf443/base/assets/water.png b/projet-code/scenes_inf443/base/assets/water.png
new file mode 100644
index 0000000000000000000000000000000000000000..d8f43106480fb878bdd96c3ec9e306a1c58a2917
Binary files /dev/null and b/projet-code/scenes_inf443/base/assets/water.png differ
diff --git a/projet-code/scenes_inf443/base/src/projectiles.cpp b/projet-code/scenes_inf443/base/src/projectiles.cpp
index 84c2b82bd6df4a5f08c8af96a5fc849a5611a138..55f863ee017e6ddc2e49629b80f48c306a7e99fd 100644
--- a/projet-code/scenes_inf443/base/src/projectiles.cpp
+++ b/projet-code/scenes_inf443/base/src/projectiles.cpp
@@ -5,8 +5,32 @@ void projectiles::initialize()
 {
 	N = 0;
 	projectiles_prop.resize(N);
-
 	mesh.initialize_data_on_gpu(mesh_primitive_sphere(0.1f));
+
+	fire_animation = image_load_file("assets/fireframes.png");
+	fire_grid = image_split_grid(fire_animation, 4, 3);
+	cgp::mesh sphere_mesh = mesh_primitive_sphere(0.5);
+	fireball.initialize_data_on_gpu(sphere_mesh);
+	fireball.texture.initialize_texture_2d_on_gpu(fire_grid[2]);
+	fireball.texture.update_wrap(GL_REPEAT, GL_REPEAT);
+
+	water_animation = image_load_file("assets/water.png");
+	water_grid = image_split_grid(water_animation, 3, 2);
+	waterball.initialize_data_on_gpu(sphere_mesh);
+	waterball.texture.initialize_texture_2d_on_gpu(water_grid[2]);
+	waterball.texture.update_wrap(GL_REPEAT, GL_REPEAT);
+
+	ice_animation = image_load_file("assets/spriteice.png");
+	ice_grid = image_split_grid(ice_animation, 4, 4);
+	iceball.initialize_data_on_gpu(sphere_mesh);
+	iceball.texture.initialize_texture_2d_on_gpu(ice_grid[2]);
+	iceball.texture.update_wrap(GL_REPEAT, GL_REPEAT);
+
+	electro_animation = image_load_file("assets/electroball.png");
+	electro_grid = image_split_grid(ice_animation, 4, 2);
+	electroball.initialize_data_on_gpu(sphere_mesh);
+	electroball.texture.initialize_texture_2d_on_gpu(electro_grid[2]);
+	electroball.texture.update_wrap(GL_REPEAT, GL_REPEAT);
 }
 
 void projectiles::reset() {
diff --git a/projet-code/scenes_inf443/base/src/projectiles.hpp b/projet-code/scenes_inf443/base/src/projectiles.hpp
index 10bb78e04112e5c3616c830f2ddfa9401f2fff3b..2bcf2696f4519c7d9e0284f6063d67655eb34669 100644
--- a/projet-code/scenes_inf443/base/src/projectiles.hpp
+++ b/projet-code/scenes_inf443/base/src/projectiles.hpp
@@ -12,6 +12,23 @@ struct projectiles {
 	std::vector<projectile> projectiles_prop;
 
 	std::vector<projectile::projectile_type> el_types = { projectile::projectile_type::fire, projectile::projectile_type::ice, projectile::projectile_type::rock, projectile::projectile_type::electric, projectile::projectile_type::water };
+	
+	//Textures
+	image_structure fire_animation;
+	std::vector<image_structure> fire_grid;
+	mesh_drawable fireball;
+
+	image_structure water_animation;
+	std::vector<image_structure> water_grid;
+	mesh_drawable waterball;
+
+	image_structure ice_animation;
+	std::vector<image_structure> ice_grid;
+	mesh_drawable iceball;
+
+	image_structure electro_animation;
+	std::vector<image_structure> electro_grid;
+	mesh_drawable electroball;
 
 	mesh_drawable mesh;
 	
diff --git a/projet-code/scenes_inf443/base/src/scene.cpp b/projet-code/scenes_inf443/base/src/scene.cpp
index 514eb17eca6caaf071906d251d1c243e71f6ccd3..3a21a828c6eea858778ed070d02414113ea6ace4 100644
--- a/projet-code/scenes_inf443/base/src/scene.cpp
+++ b/projet-code/scenes_inf443/base/src/scene.cpp
@@ -16,22 +16,23 @@ using namespace cgp;
 std::vector<vec3> tree_position;
 std::vector<vec3> grass_position;
 
+
 void scene_structure::initialize()
 {
 	//CAMERA
 	camera_control.initialize(inputs, window); // Give access to the inputs and window global state to the camera controler
 
-	//for orbit camera
+	//Orbit camera
 	//camera_control.set_rotation_axis_z(); 
 	//camera_control.look_at({ 20.0f,15.0f,15.0f }, {0,0,0});
-
-	//for first person camera
-	camera_control.camera_model.position_camera = { 0,0,evaluate_terrain_height(0,0) + 10 };
+	
+	//First person camera
+	camera_control.camera_model.position_camera = { 0,0,evaluate_terrain_height(0,0)+10};
+	//camera_control.camera_model.position_camera = { 0,-5,0};
 	camera_control.camera_model.set_rotation_axis({ 0,0,1 });
-	//custum function we added to ..first_person_euler
 	global_frame.initialize_data_on_gpu(mesh_primitive_frame());
 
-
+	
 	//SKYBOX
 	//skybox_debug.png for debugging
 	image_structure image_skybox_template = image_load_file("assets/skybox2.jpg");
@@ -46,8 +47,6 @@ void scene_structure::initialize()
 	skybox.texture2.initialize_cubemap_on_gpu(image_grid2[7].rotate_90_degrees_counterclockwise(), image_grid2[1].rotate_90_degrees_clockwise(), image_grid2[4].rotate_90_degrees_clockwise().rotate_90_degrees_clockwise(), image_grid2[10], image_grid2[3], image_grid2[5].rotate_90_degrees_clockwise().rotate_90_degrees_clockwise());
 
 
-
-
 	//TERRAIN
 	int N_terrain_samples = 500;
 	mesh const terrain_mesh = create_terrain_mesh(N_terrain_samples);
@@ -64,7 +63,6 @@ void scene_structure::initialize()
 		GL_REPEAT,
 		GL_MIRRORED_REPEAT);
 
-
 	//OBJECTS
 	int r = 1;
 	int h = 5;
@@ -85,6 +83,7 @@ void scene_structure::initialize()
 	mesh tree_mesh = create_tree();
 	tree.initialize_data_on_gpu(tree_mesh);
 
+
 	float x = 1.0;
 	float y = 2.0;
 	tree.model.translation = { x, y, evaluate_terrain_height(x,y) };
@@ -105,7 +104,7 @@ void scene_structure::initialize()
 		GL_CLAMP_TO_BORDER);
 
 	chain1.initialize();
-	bouncing.initialize(10); //10 balls
+	bouncing.initialize(20); //10 balls
 
 	bats.initialize_bats();
 	dragons.initialize_dragons();
@@ -156,16 +155,16 @@ void scene_structure::display_frame()
 	if (gui.display_wireframe)
 		draw_wireframe(terrain, environment);
 
+
+	//Draw trees if close enough
 	for (int i = 0; i < num_trees(); i++) {
-		//tree.model.translation = tree_position[i];
-		//draw(tree, environment);
-		sapin1.sapin["Trunk"].transform_local.translation = tree_position[i];
-		sapin1.sapin.update_local_to_global_coordinates();
-		draw(sapin1.sapin, environment);
+		if (norm(tree_position[i]-camera_control.camera_model.position_camera) < 75 ) {
+			sapin1.sapin["Trunk"].transform_local.translation = tree_position[i];
+			sapin1.sapin.update_local_to_global_coordinates();
+			draw(sapin1.sapin, environment);
+		}
 	}
-	//vec3 p = display_mvt();
-	//display_bird(p);
-	//display_chain(p);
+
 	display_ball();
 	display_bats();
 	display_dragons();
@@ -283,7 +282,7 @@ void scene_structure::display_semiTransparent()
 	
 	for (int i = 0; i < num_grass(); i++) {
 		grass.model.translation = grass_position[i];
-		rotation_transform R = rotation_transform::from_frame_transform({ 1,0,0 }, { 0,0,1 }, right, { 0,0,1 });
+		rotation_transform R = rotation_transform::from_frame_transform({ 1,0,0 }, { 0,0,1}, right, {0,0,1});
 		grass.model.rotation = R;
 		draw(grass, environment);
 	}
@@ -347,17 +346,96 @@ void scene_structure::display_ball() {
 }
 
 void scene_structure::display_projectiles() {
+	
+	vec3 const right = camera_control.camera_model.right();
+	rotation_transform R = rotation_transform::from_frame_transform({ cos(ball_turn_speed * timer.t + 150),sin(ball_turn_speed * timer.t + 150),0 }, { 0,0,1 }, right, { 0,0,1 });
+	rotation_transform R2 = rotation_transform::from_frame_transform({ cos(ball_turn_speed * timer.t + 150),-sin(ball_turn_speed * timer.t + 150),0 }, { 0,0,1 }, right, { 0,0,1 });
 
 	projectiles.simulate(timer.scale * 0.03f);
 	for (int i = 0; i < projectiles.N; i++) {
 		for (int j = 0; j < bats.N; j++) {
 			if (bats.bats_prop[j].bat_hitbox.is_in_hitbox(projectiles.projectiles_prop[i].pos, bats.bats_prop[j].pos)) bats.bats_prop[j].isdead = true;
 		}
-
 		projectiles.mesh.model.translation = projectiles.projectiles_prop[i].pos;
 		projectiles.mesh.material.color = projectiles.projectiles_prop[i].color;
 		draw(projectiles.mesh, environment);
+		
+		
+		glEnable(GL_BLEND);
+		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+		glDepthMask(false);
+
+		if (projectiles.projectiles_prop[i].elemental_type == projectile::projectile_type::fire) {
+
+			if (fmod(timer.t, ball_reset_speed) > 0.1) change_animation = true;
+			if (fmod(timer.t, ball_reset_speed) < 0.1 && change_animation) {
+				change_animation = false;
+				projectiles.fireball.texture.update(projectiles.fire_grid[std::rand()%12]);
+			}
+			
+			projectiles.fireball.model.translation = projectiles.projectiles_prop[i].pos;
+			draw(projectiles.fireball, environment);
+			projectiles.fireball.model.rotation = R;
+			draw(projectiles.fireball, environment);
+			projectiles.fireball.model.rotation = R2;
+			draw(projectiles.fireball, environment);
+
+		}
+		else if (projectiles.projectiles_prop[i].elemental_type == projectile::projectile_type::water) {
+
+			if (fmod(timer.t, ball_reset_speed) > 0.1) change_animation = true;
+			if (fmod(timer.t, ball_reset_speed) < 0.1 && change_animation) {
+				change_animation = false;
+				projectiles.waterball.texture.update(projectiles.water_grid[std::rand() % 6]);
+			}
+
+			projectiles.waterball.model.translation = projectiles.projectiles_prop[i].pos;
+			draw(projectiles.waterball, environment);
+			projectiles.waterball.model.rotation = R;
+			draw(projectiles.waterball, environment);
+			projectiles.waterball.model.rotation = R2;
+			draw(projectiles.waterball, environment);
+
+		}
+		else if (projectiles.projectiles_prop[i].elemental_type == projectile::projectile_type::ice) {
+
+			if (fmod(timer.t, ball_reset_speed) > 0.1) change_animation = true;
+			if (fmod(timer.t, ball_reset_speed) < 0.1 && change_animation) {
+				change_animation = false;
+				projectiles.iceball.texture.update(projectiles.ice_grid[std::rand() % 6]);
+			}
+
+			projectiles.iceball.model.translation = projectiles.projectiles_prop[i].pos;
+			draw(projectiles.iceball, environment);
+			projectiles.iceball.model.rotation = R;
+			draw(projectiles.iceball, environment);
+			projectiles.iceball.model.rotation = R2;
+			draw(projectiles.iceball, environment);
+
+		}
+		else if (projectiles.projectiles_prop[i].elemental_type == projectile::projectile_type::electric) {
+
+			if (fmod(timer.t, ball_reset_speed) > 0.1) change_animation = true;
+			if (fmod(timer.t, ball_reset_speed) < 0.1 && change_animation) {
+				change_animation = false;
+				projectiles.electroball.texture.update(projectiles.electro_grid[std::rand() % 8]);
+			}
+
+			projectiles.electroball.model.translation = projectiles.projectiles_prop[i].pos;
+			draw(projectiles.electroball, environment);
+			projectiles.electroball.model.rotation = R;
+			draw(projectiles.electroball, environment);
+			projectiles.electroball.model.rotation = R2;
+			draw(projectiles.electroball, environment);
+
+		}
+
+		glDepthMask(true);
+		glDisable(GL_BLEND);
+		
+
 	}
+
 }
 
 void scene_structure::mouse_move_event()
@@ -368,7 +446,6 @@ void scene_structure::mouse_move_event()
 void scene_structure::mouse_click_event()
 {
 	if (camera_control.inputs->mouse.click.left){
-		//std::cout << "ball created";
 		projectiles.add_ball(camera_control.camera_model.position_camera + 2*camera_control.camera_model.front(), 20*camera_control.camera_model.front());
 	}
 	camera_control.action_mouse_click(environment.camera_view);
diff --git a/projet-code/scenes_inf443/base/src/scene.hpp b/projet-code/scenes_inf443/base/src/scene.hpp
index 65a085040df1ef35d088cf5919776b9b12de74ca..daaa70d66ad2e630e57c6e86e371a6fe17bafef8 100644
--- a/projet-code/scenes_inf443/base/src/scene.hpp
+++ b/projet-code/scenes_inf443/base/src/scene.hpp
@@ -55,11 +55,15 @@ struct scene_structure : cgp::scene_inputs_generic {
 	// Timer used for the animation
 	timer_basic timer;
 
+	bool change_animation=true;
+
 	cgp::mesh_drawable terrain;
 	cgp::mesh_drawable cyl;
 	cgp::mesh_drawable cone;
 	cgp::mesh_drawable tree;
 	cgp::mesh_drawable grass;
+	float ball_turn_speed = 30;
+	float ball_reset_speed = 0.2;
 	cgp::mesh_drawable hitbox_sphere;
 
 	// Timer used for the animation
diff --git a/projet-code/scenes_inf443/base/src/settings.cpp b/projet-code/scenes_inf443/base/src/settings.cpp
index dc525711b9e263314675e6f20c93a56f108accf2..9b7c87764e48342ec0645933fd17071271437b61 100644
--- a/projet-code/scenes_inf443/base/src/settings.cpp
+++ b/projet-code/scenes_inf443/base/src/settings.cpp
@@ -1,7 +1,7 @@
 #include "settings.hpp"
 
 float _terrain_length = 250;
-int _num_trees = _terrain_length / 2;
+int _num_trees = _terrain_length * 2;
 int _num_grass = _terrain_length / 2;