Swiping and GetX state management using Currency Counter
Building games with Flutter becomes much more exciting when players can interact directly with the screen using gestures. In Currency Counter, the entire gameplay depends on swiping upward quickly to count money before the timer ends. Even though the mechanic feels simple, there are many systems working together behind the scenes. The game must detect finger movement, update the score instantly, refresh the interface smoothly, and keep performance fast even when the player swipes many times every second.
This is where GetX state management becomes very useful. GetX helps developers manage changing data without creating large amounts of unnecessary code. Instead of rebuilding the entire screen repeatedly, GetX updates only the widgets that need changes. This creates smoother gameplay and better responsiveness, especially in fast reaction games like Currency Counter.
In this tutorial, you will learn how swiping works in Flutter and how GetX can manage score values, swipe counters, timers, and game states in a clean and organized way. You will also learn how to connect swipe gestures directly to reactive variables so the user interface updates instantly whenever the player performs an action.
Understanding swipe based gameplay
Swipe games are popular because they feel natural on mobile devices. Instead of tapping tiny buttons, the player uses direct finger movement across the screen. This creates a smoother and more satisfying experience. In Currency Counter, the player swipes upward to count each currency stack.
Every swipe represents action and progress. The faster the player swipes, the higher the score becomes. This creates tension and excitement because players try to improve their speed while maintaining accuracy.
Flutter includes gesture detection systems that allow developers to track swipes very easily. The most common way is using GestureDetector. This widget listens for touch movement and performs actions whenever the player interacts with the screen.
Before using GetX, let us first understand a basic swipe detector.
GestureDetector(
onVerticalDragUpdate: (details) {
if (details.delta.dy < 0) {
print("Swiped Up");
}
},
child: Container(
width: double.infinity,
height: 300,
color: Colors.green,
),
)
In this example, Flutter checks the direction of the finger movement. Negative vertical movement means the user moved upward. Once Flutter detects the upward movement, the game can increase the currency count.
This is the foundation of Currency Counter gameplay. Every successful swipe increases the player score and updates the screen instantly.
Why GetX is useful for swipe games
Many beginners create games using setState everywhere. While this works for small projects, it becomes difficult to manage when the game grows larger. Constantly rebuilding the entire interface may also reduce performance in fast games.
GetX solves this problem using reactive variables. Instead of refreshing everything, GetX updates only the specific widget connected to a changing value.
In Currency Counter, several values change continuously during gameplay.
The score increases after every swipe.
The timer decreases every second.
Combo counters may increase.
The game over screen appears after time finishes.
Managing all these updates with traditional methods can become messy. GetX keeps the code cleaner and easier to maintain.
First install GetX in pubspec.yaml.
dependencies:
flutter:
sdk: flutter
get:
After installing the package, import it inside your Dart file.
import 'package:get/get.dart';
Creating the Currency Controller
GetX organizes logic using controllers. A controller stores the game data and business logic separately from the user interface.
This makes the code easier to understand and helps prevent large messy widget files.
Create a controller for Currency Counter.
import 'package:get/get.dart';
class CurrencyController extends GetxController {
RxInt score = 0.obs;
void increaseMoney() {
score.value++;
}
}
Here, score is reactive because of obs. Whenever the score changes, GetX automatically updates the widgets connected to it.
The increaseMoney function increases the score by one every time the player swipes upward.
Displaying reactive score on screen
Now connect the controller to the user interface.
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class CurrencyScreen extends StatelessWidget {
final CurrencyController controller =
Get.put(CurrencyController());
CurrencyScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: Center(
child: Obx(
() => Text(
"Money ${controller.score.value}",
style: const TextStyle(
color: Colors.white,
fontSize: 32,
fontWeight: FontWeight.bold,
),
),
),
),
);
}
}
Obx listens to reactive variables. Whenever the score changes, only the Text widget rebuilds automatically.
This creates a smooth experience because Flutter does not waste performance rebuilding unrelated widgets.
Connecting swipe gestures with GetX
Now combine gesture detection with reactive score updates.
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class CurrencyScreen extends StatelessWidget {
final CurrencyController controller =
Get.put(CurrencyController());
CurrencyScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
body: GestureDetector(
onVerticalDragUpdate: (details) {
if (details.delta.dy < 0) {
controller.increaseMoney();
}
},
child: Center(
child: Obx(
() => Text(
"Money ${controller.score.value}",
style: const TextStyle(
color: Colors.white,
fontSize: 34,
fontWeight: FontWeight.bold,
),
),
),
),
),
);
}
}
Now every upward swipe increases the money counter instantly.
This creates the main gameplay mechanic of Currency Counter.
Adding a countdown timer
Swipe games become more exciting with time pressure. Currency Counter uses a sixty second timer that pushes the player to move faster.
GetX can manage the timer easily.
import 'dart:async';
class CurrencyController extends GetxController {
RxInt score = 0.obs;
RxInt timeLeft = 60.obs;
Timer? timer;
void increaseMoney() {
score.value++;
}
void startTimer() {
timer = Timer.periodic(
const Duration(seconds: 1),
(timer) {
if (timeLeft.value > 0) {
timeLeft.value--;
} else {
timer.cancel();
}
},
);
}
}
The timer decreases every second automatically. Since timeLeft is reactive, the user interface updates immediately without manual rebuilding.
Showing timer on screen
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Obx(
() => Text(
"Time ${controller.timeLeft.value}",
style: const TextStyle(
color: Colors.orange,
fontSize: 28,
),
),
),
const SizedBox(height: 30),
Obx(
() => Text(
"Money ${controller.score.value}",
style: const TextStyle(
color: Colors.white,
fontSize: 34,
),
),
),
],
)
Now the player can see both the remaining time and current money count while swiping.
This creates urgency and keeps the gameplay exciting.
Starting the timer automatically
GetX controllers include lifecycle methods. One of the most useful methods is onInit. This method runs automatically when the controller starts.
@override
void onInit() {
super.onInit();
startTimer();
}
Now the timer begins automatically when the screen opens.
Creating a game over system
Every game needs a proper ending state. When the timer reaches zero, Currency Counter should stop counting swipes and show the final score.
RxBool gameOver = false.obs;
void startTimer() {
timer = Timer.periodic(
const Duration(seconds: 1),
(timer) {
if (timeLeft.value > 0) {
timeLeft.value--;
} else {
gameOver.value = true;
timer.cancel();
}
},
);
}
Once gameOver becomes true, the game can disable swipe input and display a result screen.
if (!controller.gameOver.value) {
controller.increaseMoney();
}
This prevents cheating after time finishes.
Showing game over message
Obx(
() {
if (controller.gameOver.value) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
"Game Over",
style: TextStyle(
color: Colors.red,
fontSize: 40,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 20),
Text(
"Final Money ${controller.score.value}",
style: const TextStyle(
color: Colors.white,
fontSize: 28,
),
),
],
);
}
return const SizedBox();
},
)
This creates a complete gameplay cycle from start to finish.
Why reactive systems improve performance
Many developers underestimate how important performance is in swipe based games. Players may swipe rapidly dozens of times every few seconds. If the entire interface rebuilds repeatedly, the game may begin to lag.
GetX improves efficiency because only connected widgets update. The timer widget updates separately from the score widget. The game over screen updates only when needed.
This keeps animations smoother and gameplay more responsive.
Fast reaction games depend heavily on responsiveness. Even tiny delays can make controls feel bad. Reactive state management helps avoid these problems.
Improving the swipe feeling
Great swipe games feel satisfying. Simple score updates are not enough. Players enjoy visual feedback after every action.
You can improve the experience by adding small animations whenever the player swipes.
Currency can move upward.
Score text can briefly scale larger.
Particles can appear around the screen.
Sounds can play after successful swipes.
Small improvements like these make the gameplay feel more alive and polished.
Organizing project structure
As your game grows, keeping files organized becomes very important.
A clean structure for Currency Counter might look like this.
lib
controllers
currency_controller.dart
screens
currency_screen.dart
widgets
score_text.dart
timer_text.dart
main.dart
Organized folders make future updates much easier. You can add sounds, animations, leaderboards, and effects without creating confusion.
Benefits of GetX for beginners
Many beginners struggle with state management because Flutter has multiple approaches. GetX is popular because it reduces boilerplate code and allows faster development.
The syntax is easy to read.
Reactive variables are simple to understand.
Controllers separate logic cleanly.
Navigation and dependency injection are also included.
This makes GetX a strong choice for arcade style mobile games.
Final thoughts
Swiping games may appear simple from the outside, but they rely on fast updates and responsive systems behind the scenes. Currency Counter becomes much smoother when Flutter gesture detection combines with GetX reactive state management.
By using GestureDetector, the game can detect upward movement instantly. By using GetX, score values and timers update automatically without unnecessary rebuilding. Together, these systems create gameplay that feels responsive, clean, and enjoyable.
As you continue learning Flutter game development, you can expand this project further by adding combo systems, difficulty levels, sound effects, online leaderboards, animations, and visual polish. The foundation you learned here gives you a strong starting point for creating fast and engaging swipe based games using Flutter and GetX.