Mastering SFML Game Development by Raimondas Pupius

Mastering SFML Game Development by Raimondas Pupius

Author:Raimondas Pupius [Pupius, Raimondas]
Language: eng
Format: azw3, pdf
Publisher: Packt Publishing
Published: 2017-03-06T05:00:00+00:00


Let us take a look at how the selection rectangle can be updated for entities and emitters:

void GUI_SelectionOptions::UpdateSelectDrawable() { if (m_selectMode == SelectMode::Entities) { if (m_entityId == -1) { return; } if (!m_entity) { return; } if (m_entityManager->HasComponent(m_entityId, Component::Collidable)) { auto col = m_entityManager-> GetComponent<C_Collidable>(m_entityId, Component::Collidable); auto primitive = col->GetCollidable(); m_selectDrawable.setPosition(primitive.left, primitive.top); m_selectDrawable.setSize( sf::Vector2f(primitive.width, primitive.height)); } else if (m_entityManager->HasComponent(m_entityId, Component::SpriteSheet)) { auto drawable = m_entityManager-> GetComponent<C_SpriteSheet>(m_entityId, Component::SpriteSheet); auto pos = drawable->GetSpriteSheet()->GetSpritePosition(); auto size = drawable->GetSpriteSheet()->GetSpriteSize(); m_selectDrawable.setPosition(pos); m_selectDrawable.setSize(sf::Vector2f(size)); } else { m_selectDrawable.setPosition( m_entity->GetPosition() - sf::Vector2f(16.f, 16.f)); m_selectDrawable.setSize(sf::Vector2f(32.f, 32.f)); } } else if (m_selectMode == SelectMode::Emitters) { if (!m_emitter) { return; } auto pos = sf::Vector2f( m_emitter->GetPosition().x, m_emitter->GetPosition().y); m_selectDrawable.setPosition(pos - sf::Vector2f(16.f, 16.f)); m_selectDrawable.setSize(sf::Vector2f(32.f, 32.f)); } }

As always, our logic branches out, depending on the selection mode we are in. Provided we are working with entities, a few checks are necessary in order to make sure one is selected. If it is, the next problem at hand is giving the rectangle a proper size, origin, and position. The easiest way to do that is by obtaining the colloidal component of an entity and manipulating it based on the collision primitive. If the entity doesn't have that type of component, we attempt to use the next best thing - its sprite sheet. Finally, if there's only a position component to work with, the rectangle is centered at the entity's position and given a fixed size of 32x32.

Dealing with emitters is quite similar, minus the entire component headache. Provided one is selected, its 2D position is obtained and used to centre the rectangle, while giving it a static size of 32x32.

Let us move on to updating the tile selection next:

void GUI_SelectionOptions::UpdateTileSelection() { auto& tileStart = m_mapControls->GetMouseTileStart(); auto& mouseTile = m_mapControls->GetMouseTile(); auto start = sf::Vector2f( (tileStart.x + (tileStart.x > mouseTile.x ? 1 : 0)) * Sheet::Tile_Size, (tileStart.y + (tileStart.y > mouseTile.y ? 1 : 0)) * Sheet::Tile_Size ); auto end = sf::Vector2f( (mouseTile.x + (tileStart.x <= mouseTile.x ? 1 : 0)) * Sheet::Tile_Size, (mouseTile.y + (tileStart.y <= mouseTile.y ? 1 : 0)) * Sheet::Tile_Size ); m_selectDrawable.setPosition( (start.x <= end.x ? start.x : end.x), (start.y <= end.y ? start.y : end.y) ); m_selectDrawable.setFillColor(m_selectStartColor); m_selectDrawable.setSize({ std::abs(end.x - start.x), std::abs(end.y - start.y) }); m_selectRangeX = sf::Vector2i( std::min(tileStart.x, mouseTile.x), std::max(tileStart.x, mouseTile.x) ); m_selectRangeY = sf::Vector2i( std::min(tileStart.y, mouseTile.y), std::max(tileStart.y, mouseTile.y) ); }

This is the actual method that handles tile selection logic. First, the coordinates of the starting tile that got clicked are obtained along with the current mouse position in tile coordinates. This information is used to calculate absolute global coordinates for the rectangle that will be used to represent the selection. The actual rectangle is then updated with this information, as well as set to have the m_selectStartColor color. Finally, all that is left to do is save this information as the current selection range, making sure it is in ascending order.

Next, updating entity selection deserves a peek:

void GUI_SelectionOptions::UpdateEntitySelection() { if (!m_mapControls->IsInAction()) { return; } if (!m_entity) { return; } m_entity->MoveBy(m_mapControls->GetMouseDifference()); auto elevation = m_entity->GetElevation(); m_selectionOptions->GetElement("Pos_X")-> SetText(std::to_string(static_cast<int>( m_entity->GetPosition().x))); m_selectionOptions->GetElement("Pos_Y")-> SetText(std::to_string(static_cast<int>( m_entity->GetPosition().



Download



Copyright Disclaimer:
This site does not store any files on its server. We only index and link to content provided by other sites. Please contact the content providers to delete copyright contents if any and email us, we'll remove relevant links or contents immediately.