Add the Lions!
Calculated
5 + 3 = 8
Kiddo Rechner
Kiddo Rechner is a highly engaging math learning ecosystem built for preschool children. Rather than relying on simple text entries, users drag, toss, and group bouncy 3D-shaded numerical cubes. It delivers premium, fluid game mechanics without requiring large heavy game frameworks like Unity.
The Problem
Educational math games for young children are often static and lack tactile engagement, while heavy 2D physics engines frequently degrade app launch and render metrics on budget mobile devices.
Product Thinking
Children learn through kinesthetic movement. Interactive numbers must behave like real physical blocks—bouncing, colliding, and shifting naturally, which makes learning intuitive and deeply memorable.
Engineering Challenges
Building a lightweight, custom 2D math physics simulation directly in Dart and locking continuous layout updates inside isolated UI sub-trees to keep cheap processors cool.
Key Learnings
Mastered performance boundaries, custom canvas paint pipelines, and the inner mechanics of the Flutter Element and RenderObject lifecycles.
Architectural & Code Decisions
Deep technical breakdowns of individual structural choices and implementation patterns.
RepaintBoundary Isolation
Wrapped the canvas layout containing continuous collision vectors inside a RepaintBoundary. This prevents changes in the moving blocks from forcing the entire screen tree to re-layout and repaint, reducing CPU draw by over 60%.
// RepaintBoundary containment block
@override
Widget build(BuildContext context) {
return RepaintBoundary(
child: CustomPaint(
painter: MathPhysicsPainter(
blocks: controller.activePhysicsBlocks,
),
),
);
}Custom Math Physics Collision Solver
Coded a lightweight elastic collision engine supporting spherical bounding boundaries, removing any external dependencies on heavy physics engines.
// Standard 1D Elastic Collision vector calculation
void resolveCollision(Block a, Block b) {
final double dx = b.x - a.x;
final double dy = b.y - a.y;
final double distance = math.sqrt(dx * dx + dy * dy);
if (distance < (a.radius + b.radius)) {
// Normal collision math
final double nx = dx / distance;
final double ny = dy / distance;
final double kx = a.vx - b.vx;
final double ky = a.vy - b.vy;
final double p = 2 * (nx * kx + ny * ky) / (a.mass + b.mass);
a.vx -= p * b.mass * nx;
a.vy -= p * b.mass * ny;
b.vx += p * a.mass * nx;
b.vy += p * a.mass * ny;
}
}