Relatywne Pozycjonowanie Elementów
Ostatnio zmodyfikowano 2026-01-24 16:40
tBane Temat założony przez niniejszego użytkownika |
» 2026-01-24 16:03:21 Wierzę w siebie, ale skille mam słabe :P W prototypie tym są cztery prostokąty po lewej stronie i jedna sekcja po prawej stronie. Prostokąty można za pomocą drag&drop przenieść na sekcję i tam są pozycjonowane. Gdy występuje możliwość przeniesienia prostokąta na sekcje to zmienia on kolor z zielonego na czerwony. Podrzucam kod jakby ktoś kiedyś coś podobnego chciał robić :-) #include <SFML/Graphics.hpp>
class Rect { public: const static int rectWidth = 128; const static int rectHeight = 64; sf::IntRect _rect; sf::Color _color; bool _isMoved; sf::Vector2i _offset; Rect() { _rect.size.x = rectWidth; _rect.size.y = rectHeight; _color = sf::Color::Green; _isMoved = false; _offset = sf::Vector2i( 0, 0 ); } void setColor( sf::Color color ) { _color = color; } void setColor( bool isIntersected ) { _color =( isIntersected ) ? sf::Color::Red : sf::Color::Green; } void setPosition( sf::Vector2i position ) { _rect.position = position; } void draw( sf::RenderWindow & window ) { sf::RectangleShape rect; rect.setSize( sf::Vector2f( _rect.size ) ); rect.setFillColor( _color ); rect.setPosition( sf::Vector2f( _rect.position ) ); window.draw( rect ); } };
class SectionRight { public: const static int margin = 16; const static int intersectPercent = 90; sf::IntRect _rect; std::vector < std::shared_ptr < Rect >> _relativeRects; SectionRight() { _rect.size.x = Rect::rectWidth + 2 * margin; _rect.size.y = 600; _rect.position.x = 800 - _rect.size.x; _rect.position.y = 0; } bool contains( std::shared_ptr < Rect > rect ) { return std::find( _relativeRects.begin(), _relativeRects.end(), rect ) != _relativeRects.end(); } bool intersect( std::shared_ptr < Rect > rect ) { sf::IntRect intRect; intRect.position = rect->_rect.position; intRect.position.x = rect->_rect.position.x + rect->_rect.size.x *( 100 - intersectPercent ) / 100; intRect.position.y = rect->_rect.position.y + rect->_rect.size.y *( 100 - intersectPercent ) / 100; intRect.size.x = rect->_rect.size.x * intersectPercent / 100; intRect.size.y = rect->_rect.size.y * intersectPercent / 100; sf::IntRect sectionIntRect; sectionIntRect.position = _rect.position; if( _relativeRects.empty() ) { sectionIntRect.size = sf::Vector2i( _rect.size.x, margin * 2 + Rect::rectHeight ); } else { sectionIntRect.size = sf::Vector2i( _rect.size.x, _relativeRects.back()->_rect.position.y + 2 *( Rect::rectHeight + margin ) ); } if( intRect.position.x + intRect.size.x * 2 / 8 > sectionIntRect.position.x ) { if( intRect.position.y + intRect.size.y < sectionIntRect.position.y ) { return true; } else { bool condition = sectionIntRect.findIntersection( intRect ).has_value(); return condition; } } return false; } void positionRects() { for( int i = 0; i < _relativeRects.size(); ++i ) { sf::Vector2i newPosition( _rect.position.x + margin, _rect.position.y + margin + i *( Rect::rectHeight + margin ) ); _relativeRects[ i ]->setPosition( newPosition ); } } void insertRect( std::shared_ptr < Rect > rect ) { auto it = std::find( _relativeRects.begin(), _relativeRects.end(), rect ); if( it != _relativeRects.end() ) { _relativeRects.erase( it ); } int i = 0; int mouseY = rect->_rect.position.y; while( i < _relativeRects.size() && mouseY > _relativeRects[ i ]->_rect.position.y ) { i++; } _relativeRects.insert( _relativeRects.begin() + i, rect ); positionRects(); } void addRect( std::shared_ptr < Rect > rect ) { if( contains( rect ) ) { insertRect( rect ); return; } int i = 0; while( i < _relativeRects.size() && rect->_rect.position.y > _relativeRects[ i ]->_rect.position.y ) { i += 1; } _relativeRects.insert( _relativeRects.begin() + i, rect ); positionRects(); } void removeRect( std::shared_ptr < Rect > rect ) { auto it = std::find( _relativeRects.begin(), _relativeRects.end(), rect ); if( it != _relativeRects.end() ) { _relativeRects.erase( it ); } positionRects(); } void draw( sf::RenderWindow & window ) { sf::RectangleShape rect; rect.setSize( sf::Vector2f( _rect.size ) ); rect.setFillColor( sf::Color::Color( 47, 47, 47 ) ); rect.setPosition( sf::Vector2f( _rect.position ) ); window.draw( rect ); } };
std::vector < std::shared_ptr < Rect >> relativeRects;
std::shared_ptr < Rect > pressedRect( sf::Vector2i cursorPosition ) { for( auto & rect: relativeRects ) { if( rect->_rect.contains( cursorPosition ) ) { return rect; } } return nullptr; }
int main() { sf::RenderWindow window( sf::VideoMode( sf::Vector2u( 800, 600 ), 32 ), "Relative Rects" ); relativeRects.push_back( std::make_shared < Rect >() ); relativeRects.push_back( std::make_shared < Rect >() ); relativeRects.push_back( std::make_shared < Rect >() ); relativeRects.push_back( std::make_shared < Rect >() ); for( int i = 0; i < relativeRects.size(); i += 1 ) { sf::Vector2i position( 32,( Rect::rectHeight + 16 ) * i ); relativeRects[ i ]->setPosition( position ); } std::shared_ptr < SectionRight > sectionRight = std::make_shared < SectionRight >(); sf::Vector2i cursorPosition( 0, 0 ); while( window.isOpen() ) { while( const std::optional event = window.pollEvent() ) { cursorPosition = sf::Mouse::getPosition( window ); if( event->is < sf::Event::Closed >() ) window.close(); if( const auto mouseRelease = event->getIf < sf::Event::MouseButtonReleased >() ) { for( auto & rect: relativeRects ) { if( rect->_isMoved ) { ( sectionRight->intersect( rect ) ) ? sectionRight->addRect( rect ) : sectionRight->removeRect( rect ); rect->_isMoved = false; rect->_offset = sf::Vector2i( 0, 0 ); } } } if( const auto mousePress = event->getIf < sf::Event::MouseButtonPressed >() ) { sf::Vector2i cursorPosition = mousePress->position; auto rect = pressedRect( cursorPosition ); if( rect ) { rect->_isMoved = true; rect->_offset = cursorPosition - sf::Vector2i( rect->_rect.position ); } } } for( auto & rect: relativeRects ) { if( rect->_isMoved ) rect->setPosition( cursorPosition - rect->_offset ); rect->setColor( sectionRight->intersect( rect ) ); } window.clear(); sectionRight->draw( window ); for( auto & rect: relativeRects ) { rect->draw( window ); } window.display(); } return 0; }
|
|
| 1 « 2 » |