14. Moving Shapes and Emojis¶
Learn how to create motion by changing variable values over time to make shapes and emojis move.
14.1 Motion Basics¶
- You can express motion by changing the position, size, angle, etc. of shapes and emojis over time
- Specifically, prepare variables that manage the motion state and change the variable values over time
Problems with Fixed Value Addition Motion¶
- Adding fixed values every frame as in the following code causes the motion speed to vary depending on the main loop execution frequency (Tutorial 4.3)
Program that moves 1 pixel per frame
# include <Siv3D.hpp>
void Main()
{
// Circle's X coordinate
double x = 0.0;
while (System::Update())
{
x += 1.0;
Circle{ x, 300, 50 }.draw();
}
}
- In a program that moves 1 pixel per frame:
- In a 60 FPS environment, it moves 60 pixels per second
- In a 120 FPS environment, it moves 120 pixels per second
- This causes unintended animation results on different computers and changes in game difficulty
Creating Time-based Motion¶
- Motion that isn't affected by frame rate uses elapsed time from the previous frame
Scene::DeltaTime()returns the elapsed time from the previous frame (in seconds) as adoubletype- At 60 FPS, it's 1/60 second (about 0.016 seconds) per frame
- At 120 FPS, it's 1/120 second (about 0.008 seconds) per frame
- By multiplying this value by "pixels to move per second," you can get the appropriate addition value for the frame rate
- For example, to move 100 pixels per second, do the following:
Program that moves 100 pixels per second
# include <Siv3D.hpp>
void Main()
{
// Circle's X coordinate
double x = 0.0;
while (System::Update())
{
x += (Scene::DeltaTime() * 100.0);
Circle{ x, 300, 50 }.draw();
}
}
- This program stably moves at 100 pixels per second whether the main loop runs at 60 FPS or 120 FPS
14.2 Moving Emojis¶
- Use a
Vec2type variable to move emojis - The emoji moves to the right at 100 pixels per second

Program where emoji moves right at 100 pixels per second
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Texture emoji{ U"🐥"_emoji };
// Position to draw the emoji
Vec2 pos{ 100, 300 };
while (System::Update())
{
// Move position to the right at 100 pixels per second
pos.x += (Scene::DeltaTime() * 100.0);
// Draw emoji at current position
emoji.drawAt(pos);
}
}
14.3 Back and Forth Movement¶
- Extend the program from 14.2 so the emoji moves in the opposite direction when it reaches the screen edge
- Introduce a variable
double velocityrepresenting movement speed: positivevelocityfor rightward movement, negative for leftward - When moving right and reaching the right edge of the screen (800 pixels minus 60 pixels considering emoji size), change
velocityto negative - Similarly, when moving left and reaching the left edge (60 pixels), change
velocityback to positive

Program where emoji moves back and forth
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Texture emoji{ U"🐥"_emoji };
// Position to draw the emoji
Vec2 pos{ 100, 300 };
// Emoji movement speed
double velocity = 100.0;
while (System::Update())
{
// Update position
pos.x += (Scene::DeltaTime() * velocity);
if (((0.0 < velocity) && (740 < pos.x)) // Reaches right edge or
|| ((velocity < 0.0) && (pos.x < 60))) // reaches left edge
{
// Reverse velocity
velocity *= -1;
}
emoji.drawAt(pos);
}
}
14.4 Diagonal Movement + Bouncing¶
- Further extend the program from 14.3 to implement diagonal movement and bouncing
- Introduce a variable
Vec2 velocityrepresenting movement speed in each direction- Store horizontal speed in the x component and vertical speed in the y component
Vec2can be operated on with operators like+=and*to manipulate x and y components together- You can write
pos += (Scene::DeltaTime() * velocity);

Program where emoji bounces
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Texture emoji{ U"🐥"_emoji };
// Position to draw the emoji
Vec2 pos{ 100, 300 };
// Emoji movement speed
Vec2 velocity{ 100.0, 100.0 };
while (System::Update())
{
// Update position
pos += (Scene::DeltaTime() * velocity);
if (((0.0 < velocity.x) && (740 < pos.x)) // Reaches right edge or
|| ((velocity.x < 0.0) && (pos.x < 60))) // reaches left edge
{
// Reverse x-direction velocity
velocity.x *= -1;
}
if (((0.0 < velocity.y) && (540 < pos.y)) // Reaches bottom edge or
|| ((velocity.y < 0.0) && (pos.y < 60))) // reaches top edge
{
// Reverse y-direction velocity
velocity.y *= -1;
}
emoji.drawAt(pos);
}
}
14.5 Rotation¶
- Introduce a variable
double anglerepresenting rotation angle and rotate at 180 degrees per second

Program where emoji rotates at 180 degrees per second
# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
const Texture emoji{ U"🍣"_emoji };
// Emoji rotation angle
double angle = 0_deg;
while (System::Update())
{
// Update angle
angle += (Scene::DeltaTime() * 180_deg);
// Draw emoji at current position and angle
emoji.rotated(angle).drawAt(400, 300);
}
}
14.6 Member Variables of Shape Classes¶
Circle Class¶
- The
Circleclass has the following member variables:
struct Circle
{
union
{
// Center coordinates
Vec2 center;
struct { double x, y; };
};
// Radius
double r;
};
- The center X coordinate of circle
circleis the same whether accessed ascircle.center.xorcircle.x
Rect Class¶
- The
Rectclass has the following member variables:
struct Rect
{
union
{
// Top-left coordinates
Point pos;
struct { int32 x, y; };
};
union
{
// Width and height
Point size;
struct { int32 w, h; };
};
};
- The top-left X coordinate of rectangle
rectis the same whether accessed asrect.pos.xorrect.x - The top-left Y coordinate of rectangle
rectis the same whether accessed asrect.pos.yorrect.y - The width of rectangle
rectis the same whether accessed asrect.size.xorrect.w - The height of rectangle
rectis the same whether accessed asrect.size.yorrect.h
RectF Class¶
- The
RectFclass has the following member variables:
struct RectF
{
union
{
// Top-left coordinates
Vec2 pos;
struct { double x, y; };
};
union
{
// Width and height
Vec2 size;
struct { double w, h; };
};
};
- The
RectFclass has similar member variables to theRectclass, but handles coordinates and sizes withdoubletype instead ofint32
14.7 Moving Shapes¶
- Use the member variables explained in 14.6 to move shapes

# include <Siv3D.hpp>
void Main()
{
Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });
Circle circle{ 400, 300, 10 };
RectF rect{ 100, 200, 100, 200 };
while (System::Update())
{
const double deltaTime = Scene::DeltaTime();
circle.r += (deltaTime * 40.0);
rect.x += (deltaTime * 100.0);
circle.draw();
rect.draw(ColorF{ 0.8, 0.9, 1.0 });
}
}
Review Checklist¶
- Learned about the problems with fixed value addition motion
- Learned how to create time-based motion
- Learned how to move emojis
- Learned how to implement back and forth movement and bouncing
- Learned how to create rotating motion
- Learned how to move shapes using member variables of shape classes