Optimisation du dessin des blocs et dessin correct du fond répété
This commit is contained in:
		
							parent
							
								
									6e430acf0a
								
							
						
					
					
						commit
						3d620bfd11
					
				|  | @ -277,6 +277,7 @@ void Level::processEvent(const sf::Event& event) { | |||
| 
 | ||||
| void Level::draw() { | ||||
|     sf::RenderWindow& window = getWindow(); | ||||
|     sf::Vector2u window_size = window.getSize(); | ||||
| 
 | ||||
|     // animation de la rotation de la caméra
 | ||||
|     float goal = std::fmod((float) gravity_direction * 90, 360); | ||||
|  | @ -295,25 +296,42 @@ void Level::draw() { | |||
|     // efface la scène précédente
 | ||||
|     window.clear(sf::Color(66, 165, 245)); | ||||
| 
 | ||||
|     // dessin du fond s'il y en a un
 | ||||
|     // on englobe la caméra dans un rectangle circonscrit, dans
 | ||||
|     // le cas où elle serait en rotation
 | ||||
|     sf::Vector2f camera_corners[] = { | ||||
|         pixelToCoords(sf::Vector2i(0, 0)), | ||||
|         pixelToCoords(sf::Vector2i(window_size.x, 0)), | ||||
|         pixelToCoords(sf::Vector2i(window_size.x, window_size.y)), | ||||
|         pixelToCoords(sf::Vector2i(0, window_size.y)) | ||||
|     }; | ||||
| 
 | ||||
|     sf::Vector2f camera_topleft = camera_corners[0]; | ||||
|     sf::Vector2f camera_botright = camera_corners[0]; | ||||
| 
 | ||||
|     for (unsigned int i = 0; i < 4; i++) { | ||||
|         camera_topleft.x = std::min(camera_topleft.x, camera_corners[i].x); | ||||
|         camera_topleft.y = std::min(camera_topleft.y, camera_corners[i].y); | ||||
|         camera_botright.x = std::max(camera_botright.x, camera_corners[i].x); | ||||
|         camera_botright.y = std::max(camera_botright.y, camera_corners[i].y); | ||||
|     } | ||||
| 
 | ||||
|     // on dessine le fond s'il y en a un
 | ||||
|     if (background != "") { | ||||
|         sf::Texture& bg_texture = getResourceManager().getTexture(background); | ||||
|         sf::Vector2f bg_size = (sf::Vector2f) bg_texture.getSize(); | ||||
| 
 | ||||
|         background_sprite.setTexture(bg_texture); | ||||
| 
 | ||||
|         sf::Vector2f win_size = camera.getSize(); | ||||
|         sf::Vector2i bg_size = (sf::Vector2i) bg_texture.getSize(); | ||||
|         sf::Vector2f corner = camera.getCenter() - win_size / 2.f; | ||||
|         // on regarde la position du coin où il faut commencer à
 | ||||
|         // dessiner le fond, et la zone sur laquelle il faut le dessiner
 | ||||
|         int x_left = std::floor(camera_topleft.x / bg_size.x); | ||||
|         int y_top = std::floor(camera_topleft.y / bg_size.y); | ||||
|         int x_right = std::ceil(camera_botright.x / bg_size.x); | ||||
|         int y_bottom = std::ceil(camera_botright.y / bg_size.y); | ||||
| 
 | ||||
|         // on calcule le nombre de fois qu'il faut dessiner
 | ||||
|         // le fond, et où commencer à la dessiner, pour que
 | ||||
|         // l'écran soit couvert totalement et que le fond se déplace
 | ||||
|         int x_min = std::floor(corner.x / bg_size.x); | ||||
|         int y_min = std::floor(corner.y / bg_size.y); | ||||
|         int x_max = std::ceil((corner.x + win_size.x) / bg_size.x); | ||||
|         int y_max = std::ceil((corner.y + win_size.y) / bg_size.y); | ||||
| 
 | ||||
|         for (int x = x_min; x < x_max; x++) { | ||||
|             for (int y = y_min; y < y_max; y++) { | ||||
|         // et on dessine aux positions calculées
 | ||||
|         for (int x = x_left; x < x_right; x++) { | ||||
|             for (int y = y_top; y < y_bottom; y++) { | ||||
|                 background_sprite.setPosition(sf::Vector2f( | ||||
|                     x * (bg_size.x), y * (bg_size.y) | ||||
|                 )); | ||||
|  | @ -323,17 +341,29 @@ void Level::draw() { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // chargement de la file d'affichage des objets
 | ||||
|     std::priority_queue<Object::Ptr, std::vector<Object::Ptr>, ObjectCompare> display_queue; | ||||
|     // tri des objets par ordre d'affichage
 | ||||
|     std::sort( | ||||
|         objects.begin(), objects.end(), | ||||
|         [](const Object::Ptr &a, const Object::Ptr &b) { | ||||
|             sf::Vector2f a_pos = a->getPosition(); | ||||
|             sf::Vector2f b_pos = b->getPosition(); | ||||
| 
 | ||||
|     for (unsigned int i = 0; i < objects.size(); i++) { | ||||
|         display_queue.push(objects[i]); | ||||
|     } | ||||
|             return a_pos.x - a_pos.y + a->getLayer() | ||||
|                  < b_pos.x - b_pos.y + b->getLayer(); | ||||
|         } | ||||
|     ); | ||||
| 
 | ||||
|     // dessin des objets de la file d'affichage couche par couche
 | ||||
|     while (!display_queue.empty()) { | ||||
|         display_queue.top()->draw(*this); | ||||
|         display_queue.pop(); | ||||
|     for (auto it = objects.begin(); it != objects.end(); it++) { | ||||
|         sf::Vector2i screen_pos = coordsToPixel((*it)->getPosition()); | ||||
|         sf::FloatRect aabb = (*it)->getAABB(); | ||||
| 
 | ||||
|         // si l'objet est visible à l'écran, on le dessine
 | ||||
|         if (screen_pos.x >= -aabb.width && screen_pos.y >= -aabb.height && | ||||
|             screen_pos.x <= window_size.x + aabb.width && | ||||
|             screen_pos.y <= window_size.y + aabb.height) { | ||||
|             (*it)->draw(*this); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue