16. Handling Mouse Input¶
16.1 Getting Mouse Cursor Position¶
- To get the current coordinates of the mouse cursor, use
Cursor::Pos()
Cursor::Pos()
returns aPoint
type value
Display emoji at mouse cursor position
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Font font{ FontMethod::MSDF, 48 };
const Texture texture{ U"🐥"_emoji };
while (System::Update())
{
const Point cursorPos = Cursor::Pos();
font(U"{}"_fmt(cursorPos)).draw(40, Vec2{ 40, 40 }, ColorF{ 0.1 });
texture.drawAt(cursorPos);
}
}
16.2 Checking if Mouse Button is Pressed¶
- When the left mouse button is pressed,
MouseL.down()
returnstrue
- When the right mouse button is pressed,
MouseR.down()
returnstrue
Output message when mouse button is pressed
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
// If left-clicked
if (MouseL.down())
{
Print << U"Left Click";
}
// If right-clicked
if (MouseR.down())
{
Print << U"Right Click";
}
}
}
16.3 Checking if Mouse Button is Being Pressed¶
- Unlike
.down()
,.pressed()
returnstrue
continuously while the button is being pressed
Output message while mouse button is being pressed
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
while (System::Update())
{
// If left button is being pressed
if (MouseL.pressed())
{
Print << U"Left Pressed";
}
// If right button is being pressed
if (MouseR.pressed())
{
Print << U"Right Pressed";
}
}
}
16.4 Combining Mouse Inputs¶
- Sample code for moving an emoji using mouse input:
- The emoji moves to where you left-click
- Right-clicking returns it to the center of the screen
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Texture texture{ U"🐥"_emoji };
Vec2 pos{ 400, 300 };
while (System::Update())
{
// If left-clicked
if (MouseL.down())
{
// Change emoji display position to mouse cursor position
pos = Cursor::Pos();
}
// If right-clicked
if (MouseR.down())
{
// Reset emoji display position to center of screen
pos = Vec2{ 400, 300 };
}
texture.drawAt(pos);
}
}
16.5 Checking if a Shape is Clicked¶
- To check if shapes like
Rect
orCircle
are clicked, use the member function.leftClicked()
of each shape class .leftClicked()
returnstrue
when that shape is left-clicked
Output message when shape is clicked
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Circle circle{ 200, 150, 100 };
const Rect rect{ 400, 300, 200, 100 };
while (System::Update())
{
// If circle is left-clicked
if (circle.leftClicked())
{
Print << U"Circle";
}
// If rectangle is left-clicked
if (rect.leftClicked())
{
Print << U"Rect";
}
circle.draw(Palette::Seagreen);
rect.draw(ColorF{ 0.4 });
}
}
16.6 Click Detection is Independent of Drawing¶
- Whether the shape is actually drawn on screen does not affect the result of
.leftClicked()
- The
rect
in the following code represents a rectangle covering the left half of the screen - Although it's not drawn using
.draw()
, you can still check if that rectangular area was left-clicked using.leftClicked()
Output message when left half of screen is clicked
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
// Rectangle covering the left half of the screen
const Rect rect{ 0, 0, 400, 600 };
while (System::Update())
{
// If left half of screen is left-clicked
if (rect.leftClicked())
{
Print << U"Click!";
}
}
}
16.7 Checking if Mouse Cursor is Over a Shape¶
- Using the member function
.mouseOver()
of each shape class, you can check if the mouse cursor is over that shape .mouseOver()
returnstrue
when the mouse cursor is over that shape- Like click detection, this doesn't depend on whether the shape is actually drawn
- The following code uses the conditional operator
A ? B : C
to change the shape's color depending on whether the mouse cursor is over the shape
Change shape color when mouse cursor is over the shape
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Circle circle{ 200, 150, 100 };
const Rect rect{ 400, 300, 200, 100 };
while (System::Update())
{
circle.draw(circle.mouseOver() ? Palette::Seagreen : Palette::White);
rect.draw(rect.mouseOver() ? ColorF{ 0.8 } : ColorF{ 0.6 });
}
}
16.8 Making Mouse Cursor Hand-shaped¶
- To inform users that an object can be operated with the mouse, you might change the mouse cursor to a hand shape
- Calling
Cursor::RequestStyle(CursorStyle::Hand);
makes the mouse cursor hand-shaped for that frame
Make cursor hand-shaped when mouse cursor is over shape
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Circle circle{ 200, 150, 100 };
while (System::Update())
{
if (circle.mouseOver())
{
Cursor::RequestStyle(CursorStyle::Hand);
}
circle.draw();
}
}
16.9 Checking if an Emoji is Clicked¶
- Emojis (textures) don't have
.leftClicked()
or.mouseOver()
- Instead, you can approximate with a shape of similar size for detection
- For emojis, you can roughly approximate with a circle of radius
60
- For emojis, you can roughly approximate with a circle of radius
- The following code is a sample for clicking an apple on the screen
Output message when emoji is clicked
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Texture emoji{ U"🍎"_emoji };
const Circle circle{ 200, 150, 60 };
while (System::Update())
{
// If mouse cursor is over the circle
if (circle.mouseOver())
{
// Make mouse cursor a hand icon
Cursor::RequestStyle(CursorStyle::Hand);
}
// If circle is left-clicked
if (circle.leftClicked())
{
Print << U"Apple";
}
emoji.drawAt(circle.center);
// Don't draw the circle
//circle.draw();
}
}
Review Checklist¶
- Learned that
Cursor::Pos()
gets the mouse cursor position as aPoint
type - Learned that
MouseL.down()
returnstrue
when the left mouse button is pressed - Learned that
MouseL.pressed()
returnstrue
continuously while the left mouse button is being pressed - Learned that shape classes'
.leftClicked()
returnstrue
when that shape is left-clicked - Learned that shape classes'
.mouseOver()
returnstrue
when the mouse cursor is over that shape - Learned that shape mouse-related detection can be performed regardless of whether the shape is drawn
- Learned that
Cursor::RequestStyle(CursorStyle::Hand);
makes the mouse cursor hand-shaped for that frame only - Learned to approximate with shapes for detection since emojis (textures) don't have
.leftClicked()
or.mouseOver()