Oct 6, 2022

A Classic Ping-Pong Game in Flutter

Let us see how to create the old ping-pong game using the new Flutter

Author

Jeevan Chandra JoshiJeevan Chandra JoshiSenior Software Engineer - I
A Classic Ping-Pong Game in Flutter

During the Google I/O event 2022, Flutter team announced the Casual Games Toolkit, to pull together new and existing resources that enable us to speed up the development of casual games. Building a game is always fascinating. So, today we will see how we can build different components in flutter and combine them together to build a game using the Flame Engine.

The concept of this game is that there is a ball and paddles. The ball will move freely on the canvas and the paddle will move only in 2 directions i.e., left or right. Once the ball hits the paddle it will rebound.

Flutter

Flutter is an open-source framework by Google for building beautiful, natively compiled, multi-platform applications from a single codebase.
Since Flutter can render UI at up to 60 FPS, we will use this capability to build a simple game using the flame engine.

Flame Game Engine

Flame is an open-source game engine built on top of Flutter - that provides various game development tools such as input, images, sprites, animations, and collision detection to create 2-D games.

Prerequisites

  • Flutter, version 2.10.0 or above;
  • Visual Studio Code, or any other IDE, for example, Android Studio;
  • Git, in order to save your project on GitHub/GitLab.

Getting Started

This game comprises 2 playing modes i.e., Single-player, and Multi-player.
There are four main tasks of the game:

  • Background: A field for playing the game.
  • Ball: A circular component which will move on the canvas.
  • Paddle: A rectangular component to hit the ball.
  • Score: A text component to keep track of the points.

Package Dependency

To get started with Flame, you need to install the package. In your pubspec.yaml file, add the dependency as shown below:

dependencies:
  flame: ^1.3.0

Flame Game Loop

The first component that we will set up is the flame game loop. All other components will be created and managed from here.

class MyGame extends FlameGame {
  @override
  Future<void> onLoad() async {
    super.onLoad();
  }
}
  • onLoad: This method loads the background, ball, paddle, and score for our game and registers them for the action.
  • When a game is added to a Flutter widget tree the following lifecycle methods will be called in order: onGameResizeonLoad, and onMount. After that, it invokes update and render back and forth every time until the widget is removed from the tree.

To render the game we have to use GameWidget, which takes the instance of the FlameGame.

void main() {
  final game = MyGame();
  runApp(
    GameWidget(game: game),
  );
}
  • GameWidget: It is a Flutter Widget that is used to insert a Game inside the Flutter widget tree.

Creating Background

To add a background to the screen we will draw a rectangle using the render() method.

Paint back = Paint()..color = const Color(0xff001122);
Paint front = Paint()..color = Colors.white..strokeWidth = 4.0;

@override
  void onGameResize(Vector2 size) {
    rect = Vector2.zero() & gameRef.size;
    super.onGameResize(size);
  }

@override
  void render(Canvas canvas) {
    canvas.drawRect(rect, back);
    canvas.drawRect(rect, front);
  }
  • gameRef: It is a getter provided by the mixin HasGameRef, it provides the instance of the current game.
  • onGameResize(): It is used to set the position of the component based on the screen size. This method is called before the component is rendered.
  • render(): This method is used to draw the components, to accomplish this it provides a Canvas object that offers a wide range of methods to generate content on the screen.
Ping Pong Background

Creating Ball

To create a ball we will use Circle Component. It requires the radius and the colour of the component.

CircleComponent()
  ..radius = 25
  ..setColor(Colors.green);

@override
  void update(dt) {
    super.update(dt);
    position += velocity * dt;
  }
  • update(): This method is used to change the state of the game and its component. The update method provides a parameter that contains the delta of milliseconds since the last build.
Ping Pong Ball

Now we will use the MoveByEffect method to move the ball, It requires the offset and the controller.

MoveByEffect move(double x, double y) {
  return MoveByEffect(
    Vector2(x, y),
    EffectController(
      duration: 5,
      curve: Curves.linear,
    ),
  );
}

Collision detection is needed to detect and act upon two components intersecting each other. Collision detection systems use HitBoxes to create bounding boxes of the components.
To make the ball collide we will use CircleHitbox and add the ScreenHitbox Component which represents the edges of the screen.

Collision Detection

@override
void onCollisionStart(Set<Vector2> intersectionPoints, PositionComponent other) {
  super.onCollisionStart(intersectionPoints, other);
  if (other is ScreenHitbox) {
    final collision = intersectionPoints.first;
    if (collision.x == 0) speed.x = -speed.x;
    if (collision.y == 0) speed.y = -speed.y;
    if (collision.x == gameRef.size.x) speed.x = -speed.x;
    if (collision.y == gameRef.size.y) speed.y = -speed.y;
  }
}

As soon as the Ball hits the edge of the screen the intersection points will be provided by the callback, and based on these intersection points we will revert back the ball.
HasCollisionDetection is a mixin used to keep track of the components that can collide.

Creating Paddle

To create a paddle we will use RectangleComponent. It requires the position and the size of the component.

RectangleComponent()
  ..position = Vector2(gameRef.size[0] / 2, gameRef.size[1] / 1.1);
  ..size = Vector2(gameRef.size[0] / 4, gameRef.size[1] / 64);
Ping Pong Paddle

We will detect collision with the paddle by using RectangleHitbox.

@override
void onCollisionStart(Set<Vector2> intersectionPoints, PositionComponent other) {
  super.onCollisionStart(intersectionPoints, other);
  if (other is Paddle) {
    speed.x = -speed.x;
    speed.y = -speed.y;
  }
}

As soon as the ball hits the paddle the intersection points will be provided by the callback, and we will change the direction of the ball by changing its coordinate points.
After that, we can add the movement in the Paddle with the help of keyboard keys and add the keyboard events to the game, so with the ArrowLeft key the paddle will move to the left and with the ArrowRight key, the paddle will move to the right.

@override
KeyEventResult onKeyEvent(
    RawKeyEvent event, Set<LogicalKeyboardKey> keysPressed) {
  final isKeyDown = event is RawKeyDownEvent;
  if (event.logicalKey == LogicalKeyboardKey.arrowLeft) {
    velocity.x = isKeyDown ? -1 : 0;
  } else if (event.logicalKey == LogicalKeyboardKey.arrowRight) {
    velocity.x = isKeyDown ? 1 : 0;
  }
  return super.onKeyEvent(event, keysPressed);
}

Building Points System

At last, Let's build the point system with the help of Text Component which requires a text and text-renderer.

TextComponent()
  ..text = score
  ..paint = TextPaint(
  style: const TextStyle(
    fontSize: 60,
    color: Colors.green,
    fontWeight: FontWeight.w900,
  ),
)
Ping Pong Game Points System

Currently, the Game supports mobile and web platforms. In the case of the web, there are two game modes i.e., single-player and multi-player. The movement of the bat can be handled by the keyboard keys. In the case of mobile, there is only a single-player mode and the movement of the bat can be handled by the swipe left, swipe right gesture.

Playing Instructions

  • Press 1: For a single-player game. Use ArrowLeft and ArrowRight keys for playing.
  • Press 2: For a multiplayer game. Player 1 can use W, and S keys and Player 2 can use ArrowUp and ArrowDown keys.
  • Press Space: For replaying the game.
  • Press Enter: For the main menu or the switching the game mode.

Play the Live Game 🕹
Here is the Source Code 🔗

That's it… We have completed our game using flutter-flame-engine. HAPPY GAMING :)

Subscribe to Our Newsletter

RELATED ARTICLES

More from the engineering frontline.

Dive deep into our research and insights on design, development, and the impact of various trends to businesses.
Why Legacy Systems Block Real-Time AI Decision-Making
Business

Aug 4, 2026

Why Legacy Systems Block Real-Time AI Decision-Making
Learn how legacy systems limit real-time AI decision-making and what businesses can do to build an AI-ready infrastructure.
What Makes an AI Product Enterprise-Ready? A Business Leader’s Perspective
Business

Aug 4, 2026

What Makes an AI Product Enterprise-Ready? A Business Leader’s Perspective
Most AI pilots never make it to production. Here are the five questions business leaders should ask before approving, buying, or scaling an AI product.
Building AI-Powered Banking CRM Platforms Without Replacing Core Banking Systems
Business

Jul 31, 2026

Building AI-Powered Banking CRM Platforms Without Replacing Core Banking Systems
Banks can modernize CRM with AI without replacing their core banking systems. This guide covers the architecture, use cases, governance, and roadmap to do it.
AI in Fintech: Everyone's Talking, Few are Shipping
Business

Jul 30, 2026

AI in Fintech: Everyone's Talking, Few are Shipping
This blog covers the key engineering, governance, and compliance principles required to build production-ready AI systems for financial services.
ERP and MES Integration for U.S. Pharma Manufacturers: A Roadmap to Achieve Zero-Error Production and End-to-End Traceability
Business

Jul 27, 2026

ERP and MES Integration for U.S. Pharma Manufacturers: A Roadmap to Achieve Zero-Error Production and End-to-End Traceability
A strategic roadmap for U.S. pharma leaders integrating ERP and MES to reduce production errors, accelerate batch release, strengthen compliance readiness, and enable end-to-end traceability across manufacturing sites.
How to Build Medical Device Software with AI: Compliance, Architecture, and Development Process
Business

Jul 24, 2026

How to Build Medical Device Software with AI: Compliance, Architecture, and Development Process
A guide for engineering leaders on building compliant, production-ready AI medical device software, from architecture to FDA clearance.

The Right Conversation Can Save You Six Months.

Whether you’re navigating AI adoption, modernizing legacy systems, or scaling a product - we start by listening. No pitch deck. No template. A real conversation.