Ostatnio zmodyfikowano wczoraj o godz. 19:20
tBane Temat założony przez niniejszego użytkownika |
[C++ SFML 2.6.2] Obsługa wielu zdarzeń kursora » 2024-12-20 17:01:28 Witam. Potrzebuję obsłużyć wiele zdarzeń kursora jednocześnie i nie wiem jak się za to zabrać a męczę się już trochę z tym. Zdarzenia do obsługi: brak, kliknięcie, podwójne kliknięcie i zaznaczenie. Byłbym wdzięczny za każdą pomoc. sf::Time currentTime; sf::Time prevTime;
sf::Vector2i mousePosition; sf::Vector2f worldMousePosition; sf::Time mouse_start_time; sf::Vector2i startMousePosition; sf::Vector2f startWorldMousePosition; sf::RectangleShape selectArea; enum class MouseState { None, Press, Selecting, Click, DoubleClick }; MouseState mouse_state = MouseState::None;
int main() { while( window->isOpen() ) { prevTime = currentTime; currentTime = timeClock.getElapsedTime(); mousePosition = sf::Mouse::getPosition( * window ); worldMousePosition = window->mapPixelToCoords( mousePosition ); sf::Event event; while( window->pollEvent( event ) ) { if( event.type == sf::Event::Closed ) { window->close(); } else if( event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left ) { if(( currentTime - mouse_start_time ).asSeconds() < 0.2f ) { if( mouse_state == MouseState::Click ) { mouse_state = MouseState::DoubleClick; std::cout << "double click\n"; } else if( mouse_state == MouseState::Selecting ) { mouse_start_time = currentTime; mouse_state = MouseState::Click; std::cout << "click\n"; } else mouse_state = MouseState::None; } else { mouse_state = MouseState::None; cout << " end selecting\n"; } } else if( event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left ) { if( mouse_state == MouseState::None ) { mouse_state = MouseState::Press; mouse_start_time = currentTime; startMousePosition = mousePosition; startWorldMousePosition = worldMousePosition; } } } if( mouse_state == MouseState::Press ) { if(( currentTime - mouse_start_time ).asSeconds() > 0.1f ) { mouse_state = MouseState::Selecting; std::cout << "start selecting\n"; } } if( mouse_state == MouseState::Selecting ) { cout << "selecting\n"; } } return 0; }
|
|
pekfos |
» 2024-12-20 17:13:06 Napisz co to za kod i co chciałbyś żeby robił, albo co robi źle. Bo tak to nie wiadomo co odpisać. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-12-20 17:33:54 Jest to kod obsługujący zdarzenia kursora. No więc kod działa tak:
-jeżeli przycisk jest puszczony to jest to jakieś kliknięcie, należy więc sprawdzić czy podwójne czy pojedyncze i je obsłużyć (wyświetl "click" lub "double click" -jeżeli przycisk jest trzymany to jest to zaznaczenie a jeżeli jeszcze MouseState jest None to jest to początek zaznaczenia
i po zdarzeniach -jeżeli stan myszy jest press to zmieniamy stan kursora na zaznaczenie -jeżeli stan myszy to zaznaczenie to wykonujemy operację zaznaczania
Nie wiem gdzie popełniłem błąd logiczny, nie wyjaśnię. Chciałbym by kod obsługiwał takie zdarzenia dla lewego przycisku myszy jak kliknięcie, podwójne kliknięcie oraz zaznaczenie. Byłbym wdzieczny za pomoc :-) |
|
pekfos |
» 2024-12-20 18:34:36 Dziwnie to jakoś wymyśliłeś, zwłaszcza z tymi wymaganiami czasowymi. Nie wymyślasz tu koła na nowo, tylko chcesz zreprodukować zachowanie Windowsa, które możesz zresztą łatwo wybadać na ikonkach na pulpicie. W szczególności
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-12-20 18:39:18 Podesłałbyś kod obsługujący te zachowania? |
|
pekfos |
» 2024-12-20 19:08:16 Ale wygodnie z Twojej strony. #include <SFML/Graphics.hpp> #include <cstdio> #include <cmath>
int main() { sf::RenderWindow okno( sf::VideoMode( 320, 240 ), "Kurs SFML 2.0 - http://cpp0x.pl" ); sf::Clock stoper; enum class State { Idle, Click, DoubleClickDone, Select } state = State::Idle; sf::Time lastPressTime; sf::Vector2f lastPressPos; bool isPressed = false; const float DoubleClickMaxTime = 0.5f; const float ClickMaxProximity = 10.f; while( okno.isOpen() ) { sf::Event event; sf::Time now = stoper.getElapsedTime(); while( okno.pollEvent( event ) ) { if( event.type == sf::Event::Closed ) okno.close(); if( event.type == sf::Event::MouseButtonPressed && event.mouseButton.button == sf::Mouse::Left ) { isPressed = true; if( state == State::Click &&( now - lastPressTime ).asSeconds() <= DoubleClickMaxTime ) { puts( "Double click" ); state = State::DoubleClickDone; } lastPressTime = now; lastPressPos = sf::Vector2f( event.mouseButton.x, event.mouseButton.y ); } if( event.type == sf::Event::MouseButtonReleased && event.mouseButton.button == sf::Mouse::Left ) { isPressed = false; switch( state ) { case State::Idle: state = State::Click; break; case State::Select: puts( "Select done" ); state = State::Idle; break; default: state = State::Idle; } } if( state != State::Select && state != State::DoubleClickDone && event.type == sf::Event::MouseMoved && isPressed ) { sf::Vector2f v( event.mouseMove.x, event.mouseMove.y ); v -= lastPressPos; if( fabs( v.x ) + fabs( v.y ) > ClickMaxProximity ) { puts( "Select start" ); state = State::Select; } } } if( state == State::Click &&( now - lastPressTime ).asSeconds() > DoubleClickMaxTime ) { puts( "Click" ); state = State::Idle; } okno.clear(); if( state == State::Select ) { sf::Vector2i pos = sf::Mouse::getPosition( okno ); sf::Vector2f mm( std::min < float >( pos.x, lastPressPos.x ), std::min < float >( pos.y, lastPressPos.y ) ); sf::Vector2f mx( std::max < float >( pos.x, lastPressPos.x ), std::max < float >( pos.y, lastPressPos.y ) ); sf::RectangleShape rs; rs.setSize( mx - mm ); rs.setPosition( mm ); rs.setOutlineThickness( 1 ); sf::Color col = sf::Color::Blue; rs.setOutlineColor( col ); col.a = 128; rs.setFillColor( col ); okno.draw( rs ); } okno.display(); } return 0; } |
|
tBane Temat założony przez niniejszego użytkownika |
» 2024-12-20 19:20:02 Ok. Dziękuję. Teraz to trzeba przeanalizować i zrozumieć. Dziękuję za pomoc! :-) |
|
« 1 » |