Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Zaznaczanie prostokątnego obszaru przy pomocy lewego przycisku myszy

Ostatnio zmodyfikowano 2024-09-17 20:35
Autor Wiadomość
tBane
Temat założony przez niniejszego użytkownika
Zaznaczanie prostokątnego obszaru przy pomocy lewego przycisku myszy
» 2024-09-17 15:58:00
Witam. Próbuję napisać program, w którym można zaznaczać obszar używając lewego przycisku myszy. Napisałem taki kod jak poniżej, co robię źle ?

C/C++
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <iostream>
using namespace std;

sf::Vector2i mousePosition;
sf::Vector2i startMousePosition;
sf::RectangleShape rect;
sf::RenderWindow * window = nullptr;

int main() {
   
   
window = new sf::RenderWindow( sf::VideoMode( 1280, 720 ), "RECT" );
   
   
while( window->isOpen() ) {
       
       
mousePosition = sf::Mouse::getPosition( * window ); // Pobierz aktualną pozycję myszy względem bieżącego okna
       
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::MouseButtonPressed ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
                   
startMousePosition = sf::Mouse::getPosition( * window );
               
}
            }
           
        }
       
       
int start_x, start_y, end_x, end_y;
       
       
if( mousePosition.x > startMousePosition.x ) {
           
start_x = startMousePosition.x;
           
end_x = mousePosition.x;
       
}
       
else {
           
start_x = mousePosition.x;
           
end_x = startMousePosition.x;
       
}
       
       
if( mousePosition.y > startMousePosition.y ) {
           
start_y = startMousePosition.y;
           
end_y = mousePosition.y;
       
}
       
else {
           
start_y = mousePosition.y;
           
end_y = startMousePosition.y;
       
}
       
       
cout << "selected area: \n";
       
cout << "start: " << start_x << ", " << start_y << "\n";
       
cout << "end: " << end_x << ", " << end_y << "\n";
       
cout << "\n\n";
       
       
rect = sf::RectangleShape( sf::Vector2f( end_x - start_x, end_y - start_y ) );
       
rect.setPosition( start_x, start_y );
       
       
window->clear();
       
window->draw( rect );
       
window->display();
   
}
   
   
return 0;
}
P-181597
pekfos
» 2024-09-17 16:04:24
Nie ma pokrytego przypadku gdy nie trzymasz przycisku myszy.
P-181598
tBane
Temat założony przez niniejszego użytkownika
» 2024-09-17 16:19:00
Napisałem to co powiedziałeś i działa. Ale czy mój kod jest dobry ?

C/C++
void testSelectingFunction() {
   
   
sf::Vector2i mousePosition;
   
sf::Vector2i startMousePosition;
   
sf::RectangleShape rect;
   
sf::RenderWindow * window = nullptr;
   
   
enum class selection_states { none, select };
   
selection_states selection_state = selection_states::none;
   
   
window = new sf::RenderWindow( sf::VideoMode( 1280, 720 ), "RECT" );
   
   
while( window->isOpen() ) {
       
       
mousePosition = sf::Mouse::getPosition( * window ); // Pobierz aktualną pozycję myszy względem bieżącego okna
       
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::MouseButtonPressed ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
                   
startMousePosition = sf::Mouse::getPosition( * window );
               
} selection_state = selection_states::select;
           
}
           
           
if( event.type == sf::Event::MouseButtonReleased ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
selection_state = selection_states::none;
               
}
            }
        }
       
       
if( selection_state == selection_states::select ) {
           
           
int start_x, start_y, end_x, end_y;
           
           
if( mousePosition.x > startMousePosition.x ) {
               
start_x = startMousePosition.x;
               
end_x = mousePosition.x;
           
}
           
else {
               
start_x = mousePosition.x;
               
end_x = startMousePosition.x;
           
}
           
           
if( mousePosition.y > startMousePosition.y ) {
               
start_y = startMousePosition.y;
               
end_y = mousePosition.y;
           
}
           
else {
               
start_y = mousePosition.y;
               
end_y = startMousePosition.y;
           
}
           
           
cout << "selected area: \n";
           
cout << "start: " << start_x << ", " << start_y << "\n";
           
cout << "end: " << end_x << ", " << end_y << "\n";
           
cout << "\n\n";
           
           
rect = sf::RectangleShape( sf::Vector2f( end_x - start_x, end_y - start_y ) );
           
rect.setPosition( start_x, start_y );
       
}
       
       
window->clear();
       
if( selection_state == selection_states::select )
           
 window->draw( rect );
       
       
window->display();
   
}
   
}
P-181599
pekfos
» 2024-09-17 17:14:49
Jest błędny
C/C++
if( event.mouseButton.button == sf::Mouse::Left ) {
   
   
startMousePosition = sf::Mouse::getPosition( * window );
} selection_state = selection_states::select;
Na pewno nie testowałeś dla prawego przycisku myszy.

selection_states jest przekombinowane, to jest zadanie dla bool. Zrobiłeś enumem dwie stałe i tylko jednej używasz do decyzji w działaniu programu, druga robi tylko za przeciwieństwo pierwszej.
Zmienne mają niepotrzebnie duży zasięg i niepotrzebnie używasz dynamicznej alokacji pamięci, której na dodatek nie zwalniasz. Lepiej byłoby tak
C/C++
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <algorithm>  
// std::min, max

int main() {
   
sf::RenderWindow window( sf::VideoMode( 1280, 720 ), "RECT" );
   
   
sf::Vector2i startMousePosition;
   
bool selection_state = false;
   
   
while( window.isOpen() ) {
       
       
sf::Vector2i mousePosition = sf::Mouse::getPosition( window );
       
       
sf::Event event;
       
while( window.pollEvent( event ) ) {
           
if( event.type == sf::Event::Closed )
               
 window.close();
           
           
if( event.type == sf::Event::MouseButtonPressed ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
                   
startMousePosition = sf::Mouse::getPosition( window );
                   
selection_state = true;
               
}
            }
           
           
if( event.type == sf::Event::MouseButtonReleased ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
selection_state = false;
               
}
            }
        }
       
       
window.clear();
       
       
if( selection_state ) {
           
int start_x = std::min( startMousePosition.x, mousePosition.x );
           
int start_y = std::min( startMousePosition.y, mousePosition.y );
           
int end_x = std::max( startMousePosition.x, mousePosition.x );
           
int end_y = std::max( startMousePosition.y, mousePosition.y );
           
           
// Nie ma sensu przechowywać RectangleShape dłużej niż to potrzebne
           
sf::RectangleShape rect( sf::Vector2f( end_x - start_x, end_y - start_y ) );
           
rect.setPosition( start_x, start_y );
           
window.draw( rect );
       
}
       
       
window.display();
   
}
   
   
return 0;
}
P-181600
tBane
Temat założony przez niniejszego użytkownika
» 2024-09-17 18:02:22
Ok. Poprawiłem kod.

C/C++
void testSelectingFunction() {
   
// Local mouse position
   
sf::Vector2i mousePosition;
   
sf::Vector2i startMousePosition;
   
   
// Global mouse position
   
sf::Vector2f worldMousePosition;
   
sf::Vector2f startWorldMousePosition;
   
   
sf::RectangleShape rect;
   
sf::RenderWindow * window;
   
   
bool selection_state = false;
   
   
window = new sf::RenderWindow( sf::VideoMode( 1280, 720 ), "RECT" );
   
   
while( window->isOpen() ) {
       
       
mousePosition = sf::Mouse::getPosition( * window ); // Pobierz aktualną pozycję myszy względem bieżącego okna
       
worldMousePosition = window->mapPixelToCoords( mousePosition );
       
       
sf::Event event;
       
while( window->pollEvent( event ) ) {
           
           
if( event.type == sf::Event::MouseButtonPressed ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
                   
startMousePosition = sf::Mouse::getPosition( * window );
                   
startWorldMousePosition = window->mapPixelToCoords( startMousePosition );
               
} selection_state = true;;
           
}
           
           
if( event.type == sf::Event::MouseButtonReleased ) {
               
if( event.mouseButton.button == sf::Mouse::Left ) {
                   
selection_state = false;
                   
// action
               
}
            }
        }
       
       
if( selection_state == true ) {
           
           
int start_x = std::min( ceil( startWorldMousePosition.x / tileSide ), ceil( worldMousePosition.x / tileSide ) );
           
int start_y = std::min( ceil( startWorldMousePosition.y / tileSide ), ceil( worldMousePosition.y / tileSide ) );
           
int end_x = std::max( ceil( startWorldMousePosition.x / tileSide ), ceil( worldMousePosition.x / tileSide ) );
           
int end_y = std::max( ceil( startWorldMousePosition.y / tileSide ), ceil( worldMousePosition.y / tileSide ) );
           
           
cout << "selected area: \n";
           
cout << "start: " << start_x << ", " << start_y << "\n";
           
cout << "end: " << end_x << ", " << end_y << "\n";
           
cout << "\n\n";
           
           
rect = sf::RectangleShape( sf::Vector2f(( end_x - start_x ) * tileSide,( end_y - start_y ) * tileSide ) );
           
rect.setPosition( start_x * tileSide, start_y * tileSide );
       
}
       
       
window->clear();
       
if( selection_state == true )
           
 window->draw( rect );
       
       
window->display();
   
}
   
   
delete window;
   
}
P-181602
« 1 »
  Strona 1 z 1