Voici une solution, excusez pour le code vraiment "à l'arrache" et pas commentée du tout
Header:class MouseClick
{
public:
enum Status: unsigned short
{
NONE = 0,
DOWN,
DOUBLE_DOWN,
PENDING,
CLICK,
DOUBLE
};
MouseClick();
virtual ~MouseClick();
void handle();
inline bool left() const { return (std::get<0>(m_clicks) == Status::CLICK); }
inline bool right() const { return (std::get<1>(m_clicks) == Status::CLICK); }
inline bool doubleleft() const { return (std::get<0>(m_clicks) == Status::DOUBLE); }
inline bool doubleright() const { return (std::get<1>(m_clicks) == Status::DOUBLE); }
void clear();
private:
sf::Clock m_time;
unsigned long m_last;
std::tuple<Status, Status> m_clicks;
static const unsigned short click_delay = 100; /// ms
};
Source:MouseClick::MouseClick() :
m_time(sf::Clock()),
m_last(m_time.getClock().getElapsedTime().asMilliseconds()),
m_clicks(std::make_tuple(NONE, NONE))
{
//ctor
}
MouseClick::~MouseClick()
{
//dtor
}
void MouseClick::handle()
{
bool left = sf::Mouse::isButtonPressed(sf::Mouse::Button::Left),
right = sf::Mouse::isButtonPressed(sf::Mouse::Button::Right);
Status& last_left = std::get<0>(m_clicks);
Status& last_right = std::get<1>(m_clicks);
unsigned long clock = m_time.getClock().getElapsedTime().asMilliseconds();
auto delta = clock-m_last;
if(left && last_left == Status::NONE)
{
last_left = Status::DOWN;
m_last = clock;
}
else if(left && last_left == Status::PENDING)
{
if(delta < click_delay)
{
last_left = Status::DOUBLE_DOWN;
m_last = clock;
}
}
else if(!left && last_left == Status::DOWN)
{
last_left = Status::PENDING;
m_last = clock;
}
else if(!left && last_left == Status::PENDING)
{
if(delta > click_delay)
{
last_left = Status::CLICK;
m_last = clock;
}
}
else if(!left && last_left == Status::DOUBLE_DOWN)
{
if(delta < click_delay)
{
last_left = Status::DOUBLE;
m_last = clock;
}
}
else if(!left &&
(last_left == Status::CLICK || last_left == Status::DOUBLE)
&& delta > click_delay)
{
last_left = Status::NONE;
m_last = clock;
}
if(right && last_right == Status::NONE)
{
last_right = Status::DOWN;
m_last = clock;
}
else if(right && last_right == Status::PENDING)
{
if(delta < click_delay)
{
last_right = Status::DOUBLE_DOWN;
m_last = clock;
}
}
else if(!right && last_right == Status::DOWN)
{
last_right = Status::PENDING;
m_last = clock;
}
else if(!right && last_right == Status::PENDING)
{
if(delta > click_delay)
{
last_right = Status::CLICK;
m_last = clock;
}
}
else if(!right && last_right == Status::DOUBLE_DOWN)
{
if(delta < click_delay)
{
last_right = Status::DOUBLE;
m_last = clock;
}
}
else if(!right &&
(last_right == Status::CLICK || last_right == Status::DOUBLE)
&& delta > click_delay)
{
last_right = Status::NONE;
m_last = clock;
}
}
void MouseClick::clear()
{
m_clicks = std::make_tuple(Status::NONE, Status::NONE);
}
Pour verifier le click sur un sprite:
MouseClick click;
sf::Sprite mon_sprite;
// Trucs sur le sprite
if(mouseclick.left()) { ... }
if(mouseclick.right()) { ... }
if(mouseclick.doubleleft()) { ... }
if(mouseclick.doubleright()) { ... }
Ne pas oublier d'appeler
MouseClick::clear(); si un des
MouseClick::bool à retourné
true !