Learning hand gesture using Perfect Circle
Perfect Circle may look like a simple drawing game at first but it actually teaches one of the most important skills in modern game development which is hand gesture detection.
Every time a player touches the screen and starts drawing the game tracks movement continuously.
The game studies how the finger moves where it starts where it ends and how smooth the path looks.
This entire process is called gesture handling.
Gesture systems are everywhere in modern games and mobile applications.
Swiping slicing dragging pinching rotating and drawing are all examples of gestures.
Perfect Circle is a very good beginner project because it focuses on one clear gesture which is drawing a circle shape using your hand.
When players draw on the screen the game captures many position points.
These points together create a path.
The game then checks whether that path looks like a proper circle.
Learning this system helps you create advanced mobile games later.
You can build drawing games ninja slicing games puzzle games spell casting systems and many other interactive experiences.
Understanding how touch gestures work
A gesture begins when the player touches the screen.
While the finger moves the device keeps sending updated coordinates.
These coordinates tell the game the exact location of the finger every moment.
When the player lifts the finger the gesture ends.
The game then studies the collected points and decides what the player tried to do.
In Perfect Circle the game expects a circular motion.
If the movement looks uneven incomplete or too small the score becomes lower.
Why gesture systems are important in games
Gesture systems create direct interaction between the player and the game.
Pressing buttons feels simple but gestures feel natural because players physically move their hands.
This creates stronger immersion.
Perfect Circle feels addictive because the player is directly responsible for the shape being created.
Every small hand movement changes the result.
That personal connection makes gesture based games very engaging.
Capturing touch points in Flutter
The first step is detecting touch movement.
Flutter provides gesture systems that help track dragging and drawing.
Create a list to store all finger positions.
List<Offset> points = [];
Every time the finger moves add the new position into the list.
GestureDetector(
onPanUpdate: (details) {
setState(() {
points.add(details.localPosition);
});
},
)
Now the game continuously stores the path created by the player.
Understanding what Offset means
Offset is a Flutter object that stores x and y coordinates.
X controls horizontal movement.
Y controls vertical movement.
Every finger movement generates a new Offset position.
Together these positions form the drawing path.
Drawing the gesture path on screen
After collecting points the next step is showing the line visually.
This makes the game feel responsive because players instantly see their movement.
class CirclePainter extends CustomPainter {
final List<Offset> points;
CirclePainter(this.points);
@override
void paint(Canvas canvas, Size size) {
final paintObject = Paint()
..color = Colors.white
..strokeWidth = 6
..style = PaintingStyle.stroke;
for (int i = 0; i < points.length - 1; i++) {
canvas.drawLine(
points[i],
points[i + 1],
paintObject,
);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
This painter connects all saved points using lines.
The result looks like freehand drawing.
Adding the painter into the screen
CustomPaint(
painter: CirclePainter(points),
child: Container(),
)
Now the player can visually see the gesture path while drawing.
Detecting gesture start
A proper gesture system should know when drawing begins.
Clear old points before starting a new attempt.
onPanStart: (details) {
setState(() {
points.clear();
points.add(details.localPosition);
});
},
This ensures every drawing starts fresh.
Detecting gesture end
When the finger lifts from the screen the gesture finishes.
This is the best moment to calculate accuracy.
onPanEnd: (details) {
checkCircleAccuracy();
},
The game now knows when to analyze the drawing.
Checking if the circle is closed
One important rule in Perfect Circle is connecting the ending back to the starting point.
Open circles should fail.
Compare the first point and the last point.
bool isClosedCircle() {
if (points.length < 10) {
return false;
}
final start = points.first;
final end = points.last;
final distance = (start - end).distance;
return distance < 40;
}
If the distance is small enough the shape counts as closed.
Rejecting tiny circles
Tiny circles are easier to fake and do not test real hand movement.
The game should reject them.
bool isLargeEnough() {
double minX = points.first.dx;
double maxX = points.first.dx;
double minY = points.first.dy;
double maxY = points.first.dy;
for (final point in points) {
if (point.dx < minX) {
minX = point.dx;
}
if (point.dx > maxX) {
maxX = point.dx;
}
if (point.dy < minY) {
minY = point.dy;
}
if (point.dy > maxY) {
maxY = point.dy;
}
}
double width = maxX - minX;
double height = maxY - minY;
return width > 150 && height > 150;
}
This checks whether the drawing area is large enough.
Calculating circle quality
The next step is checking how circular the shape looks.
A real circle keeps nearly equal distance from the center at all points.
First calculate the center position.
Offset calculateCenter() {
double totalX = 0;
double totalY = 0;
for (final point in points) {
totalX += point.dx;
totalY += point.dy;
}
return Offset(
totalX / points.length,
totalY / points.length,
);
}
Now calculate the average radius.
double calculateAverageRadius(Offset center) {
double total = 0;
for (final point in points) {
total += (point - center).distance;
}
return total / points.length;
}
After that compare every point distance against the average radius.
double calculateAccuracy() {
final center = calculateCenter();
final averageRadius = calculateAverageRadius(center);
double error = 0;
for (final point in points) {
double distance =
(point - center).distance;
error +=
(distance - averageRadius).abs();
}
double averageError =
error / points.length;
double score =
100 - averageError;
return score.clamp(0, 100);
}
The lower the error the better the score becomes.
This system gives players instant feedback.
Why hand stability matters
Human hands naturally shake slightly during movement.
Small inconsistencies create bumps and uneven curves.
Perfect Circle becomes difficult because maintaining consistent motion is harder than most people expect.
The game secretly teaches fine motor control and movement rhythm.
Improving gesture smoothness
Raw touch points sometimes look shaky.
Smoothing can improve visual quality.
One simple method is ignoring points that are too close together.
onPanUpdate: (details) {
final point = details.localPosition;
if (points.isEmpty) {
points.add(point);
return;
}
final lastPoint = points.last;
if ((point - lastPoint).distance > 5) {
setState(() {
points.add(point);
});
}
},
This reduces unnecessary jitter.
Adding score text
Showing results instantly keeps players engaged.
double score = 0;
Update the score after gesture completion.
void checkCircleAccuracy() {
if (!isClosedCircle()) {
score = 0;
return;
}
if (!isLargeEnough()) {
score = 0;
return;
}
score = calculateAccuracy();
}
Display the score using Text widgets.
Text(
"${score.toStringAsFixed(0)}%",
style: const TextStyle(
fontSize: 40,
color: Colors.white,
),
)
This creates the satisfying percentage system used in Perfect Circle.
Making gesture games feel responsive
Fast response is extremely important in touch based games.
Delayed drawing feels frustrating and disconnected.
Smooth rendering and quick updates make the game feel premium.
Players enjoy games more when their movement instantly appears on screen.
Common beginner mistakes
Many beginners collect too many points which slows performance.
Others forget to clear previous drawings before starting a new attempt.
Some developers also calculate scores before the gesture ends which creates unstable results.
Small design choices matter greatly in gesture systems.
Using gesture systems in future games
Once you understand hand gesture detection you can build many advanced mechanics.
You can create spell drawing systems in fantasy games.
You can build signature systems and drawing applications.
You can create swipe combat systems and puzzle games.
Gesture handling is one of the most valuable skills in mobile game development.
Final thoughts
Perfect Circle is much more than a simple drawing challenge.
It teaches how human movement interacts with software in real time.
Every touch every curve and every movement becomes part of the gameplay experience.
Learning gesture systems helps you create games that feel interactive natural and satisfying.
Start with simple touch detection first.
Then slowly improve smoothing accuracy checking and score systems.
Over time you will understand how powerful gesture based interaction can become in Flutter game development.