
Create a two-player Wi-Fi connected game for Android and iOS using Flutter and Dart, with accelerometer-controlled movement, game objects, sound, a user interface, and code access for learning.
Learn to create a game in Flutter and Dart with expert insights from NRA Nica, an electronics engineer who loves mobile development.
Begin by affirming you can become a programmer, and dive into a course using Flutter and Dart, with Flame engine and plugins for scenes and audio to design the game.
Build a two-player tennis game with paddles on sides that bounce the ball off walls and paddles, score on misses, and start with a single-player version.
Create a new Flutter project in Android Studio, name it, set a company domain, apply high-contrast color scheme, then clear main.dart, remove test widget code, and add assets/images.
Learn to add the flame game engine to a Flutter project by copying the flame dependency into pubspec.yaml with a caret version constraint, then run pub get until dependencies resolve.
Create the ball image by setting a 64×64 canvas, choosing tennis-ball yellow with capacity 255, filling from top-left to bottom-right, and saving as ball.png in 256 colors.
Create the pad image by resizing the canvas to 228 by 20 pixels, changing the color to cyan, filling the canvas with a rectangle, and saving as a 256-color image.
Add two images to the flutter flame game project by placing them in assets/images and updating the assets section to include ball.png and red.png.
Build the bowl class as a sprite component using the flame package. Create a constructor that calls the base sprite constructor with 64 by 64 and the ball image.
Centralize height and width constants in a separate file and reuse them in the ball class. Override resize to reset the ball's x and y to zero on screen resize.
Create the pad class by duplicating the ball class, rename to pad, and define constants: pad length 28 pixels, pad height 26 pixels, and another constant equals 50.
Discover how to position the ball and the bed on a resizable screen using a top-left origin, center alignment, and coordinate calculations in the pad class.
Use the overridden resized method to center the pad on resize by computing x as screen width divided by two minus the pad width and fix y at 50.
Explain the pad positioning constants: set pad height to 20, top-left to bottom-of-screen distance to 50, and opponent pad distance to bottom to 30.
Set up separate constants for the pad game, isolating length, height, and power to enable future tweaks, including a 30-pixel distance from the screen top to the pad.
Copy the pad plus code to create pad2, rename the class to pad2, and adjust the constructor to set pad2 length and height, while reusing the same image for consistency.
Create a test game class in Flutter/Dart by extending the Flame base game, importing the Flame package and bulldog art, and instantiating a ball.
Create the main function as the entry point, import needed files, instantiate a game object, and call runApp with the game widget to start the app.
Test the Flutter game on an Android virtual device, create a Pixel a three avd, and run the app to observe slow ball movement.
Connect a real device to Android Studio and run the app to observe smooth ball motion on a real device, faster than virtual device, with recording causing a minor jump.
Refactor the game class to hide the bull clause with an underscore. Add screen size, a pad, ball speed, and dx/dy, and initialize them in the constructor.
Add the sensors package to enable accelerometer input for moving the bed in the single-player game. Import the package, update pubspec, and create an init method for the game constructor.
Create constants for the game screen size (x and y) and for the top, bottom, and right borders to standardize layout.
Learn to determine the screen size (width and height) in Flutter using flame initial dimensions, import flame.dart, and print the size, noting the status bar reduces height.
Implement the _init() method for a single-player Flutter/Dart game by wiring an anonymous event handler, normalizing input, and capping bed movement with a max constant in the constants file.
Override the resize method for the single-player dodge dart game to update the screen size, store it in a member variable, and call super.resize(size) before the render method.
Override the render method in the single-player game version, implement a draw background method using the canvas, and finalize by calling the base class render with the canvas.
Implement the _drawBackground method to fill the screen by drawing a teal rectangle on the canvas using a paint object and a color constant from a constants file.
Implement the update method in a single-player game, handling accelerometer events to update the paddle position and trigger ball movement via movePad and moveBall in Flutter/Dart.
Implement the _movePad() method to update the paddle's position by setting its x and y coordinates from incoming events, enabling responsive paddle movement in the Flutter/Dart game.
Implement the underscore bounce method to update the ball's x and y with speed, bouncing off left/right borders by reversing x velocity and wrapping from top to bottom.
Implement the bounce() logic for a Flutter game using ball diameter, X and Y positions, and speed to detect edge collisions, reverse velocity, and reappear at top after bottom exit.
Explore ball bounces off left and right borders, top-bottom wrapping, and pad collisions, then test the single player version by connecting a device and running the app.
Watch a real-device screen recording of the game where objects wrap around screen edges and bounce, confirming behavior on all players. Next video adds sound.
Add game sound by creating an audio directory, importing bounce, win, and loss mp3 files, updating pubspec.yaml to include audio assets, and adding an audio package to enable playback.
Add sound to your Flutter game using assets and the all audio players package, and load bounce, when, and loss sounds via an audio cache.
Load the mp3 file path, set the volume, and call play for bounce, wind, and loss sounds as the ball bounces and exits the screen in a Flutter game.
Set up constants to connect the game, including a boolean isClient, IP addresses, and compute ball diameter and pad lengths from screen size (dividing by 12, 7, 20, and 30).
Introduce UDP networking in the game and implement a Dart UDP class using a connectionless protocol for speed, accepting packet loss, with a static stream subscription variable and port constants.
Explore creating a UDP data method in Flutter/Dart, using camelCase naming, a static socket, binding to a host and port, and streaming datagrams to strings.
Define a static sendData method that takes a string, an IP address, and a port; use the existing socket, guard against null, convert to data, and send.
Configure main.dart to enable fullscreen landscape mode, instantiate the Utah class and call flame, and fetch the device IP with the Wi-Fi package while updating dependencies and printing the IP.
Wire UDP into game.dart by adding member variables and a constructor. Implement a data-processing callback in the UDP class.
Implement bounce logic in game.dart by handling event streams and updating ball and pad collisions. Separate server and client paths and prepare methods to set position data and future updates.
Build a Dart udp data sender in Flutter by constructing a score and screen coordinates string, preventing duplicates, and sending via a static udp method to the other device.
Create the process data method to parse input by spaces, differentiate client and server, enforce length thresholds, and set screen coordinates and ball positions.
Describe how the setPosData method computes synchronized pad and ball positions across devices, using screen size, clamping to screen edges, and scaling movement with screen ratio for client-server symmetry.
Fixes in main.dart remove full-screen action bars by clearing UI overlays; wire UDP data handling with a callback, and pass received data to the procData function; prepare constants in construct.
Modify constants in consts.dart to differentiate server and client configurations. Adjust bed height, bed range, and IP values for server and client manually.
Fix and initialize game.dart variables in a flutter/dart game, setting up score, ball positions, and booleans, adjusting resize bounds, and preparing a future sound client method.
The lesson demonstrates implementing a play sound client method in game.dart, detailing how to trigger sounds, control balance and volume, and use conditional logic to manage scores and state.
Review the play sound client method, track the ball’s current and old positions within a 10‑unit range, and trigger bounce, loss, or wind sounds as the ball hits edges.
Optimize consts.dart for a Flutter/Dart multiplayer game by configuring client and server IP addresses, and handling x/y coordinates for automatic setup.
Connect the server and client for a two-player Flutter/Dart game, configure server and client IPs, and run the game on both devices to test multiplayer.
Server and client devices mirror actions as tilting moves the bed and ball left or right, with blocking and bouncing, setting up the score in the next video.
Define scoring in a Flutter/Dart game by creating a consts.dart with color constants, text styles, and font size settings, and score limits, and implement a text box to display scores.
Create a text box class to display the game score using a text box component in Flutter/Dart, wiring imports, constructor, and a custom draw method with color and stroke style.
The lecture explains adding score tracking to a Flutter/Dart game, updating player and opponent scores when wind sounds play, and configuring text with tiny fonts using flame.
implement the placeText method in game.dart to render a message with a Text widget, positioned at the top center using screen width, with y set to zero.
Learn to implement the getScoreText() helper in game.dart to format the score and opponent's score for display, including separators and cross-class usage.
Explore the checkScore method in Dart, comparing your score to max score and winning margin to declare a winner or none, while updating on-screen text.
Parse the data string by spaces into a list, convert index 0 and 1 to your and opponent scores, and determine the winner with server‑client inversion.
Copy the method name, recreate a UDP instance with a new parameter, and add a process score and a send score method to transmit the server score to the client.
In this lecture, we extend the udp.dart file to support scoring by wiring a process score callback into the UDP class constructor and outlining client-server score flow.
Create the initScoring method in udp.dart, listen on the UDP socket, and on data arrival convert the received data to a string, then call the procScore callback with the score.
Create the udp.dart sendScore method to obtain a socket asynchronously, validate the other device IP, and send the score using code units to the specified IP and port.
Design a start page for a networked game, displaying server/client status, win/lose messages and the score, with a start or resume button, server-only ball speed control, and a chat area.
Set up a Flutter app by adding a third-party color picker package, importing it in main.dart, and configuring the app class with a blue theme and start page.
Define a home page class as a stateful widget with a title property and key, initialize via constructor and super, and override createState to return the home page state.
This lecture explains creating the home page state class in flutter/dart, initializing text editing controllers, score, messages, and related fields in the constructor and setup in init.
Override vote method and set up the home page state build method to configure a scaffold with app bar and list view, create a game object, and wire UI components.
Define constants in consts.dart for the game UI, including max message lines, speed width, message count, surge, margin, and font size, then proceed with the Dart bolt method.
Learn to build a Flutter list view with rows and text widgets styled by context text theme, add constants, and prepare for radio buttons in the next video.
Explore the HomePageState build method as you add radio buttons in a row, handle value changes, and prepare a text field for IP addresses in the next video.
This lecture shows building the home page state in Flutter/Dart with radio buttons and a text field to enter the other device IP, including validation and a start game button.
Display device IP and add a start game button in a Flutter list view to begin a game via UDP messages for client or server, navigate to the game screen.
Build and customize a Flutter app interface by adding settings to change the background color through a dialog with a color picker, triggered by a raised button.
Server-only UI enables adjusting the bolt speed in a flutter game, with a numeric text field, double parsing, and an apply button.
Build the user interface for a chat-like communication section in a Flutter/Dart app, including a text field, a message list, and a UDP-based message sender.
Finalize the communication section by building a text field in a width-constrained container, applying message styling with max lines and overflow ellipses, and prepare for the show score method.
Create the showMessage method inside the HomePageState class to display incoming opponent messages from the first item in the messages list, then implement showMessages for rendering.
Implement the showMessages method in the home page state to loop through the messages list, concatenate each string with a newline, and return the combined string.
Implement the changeColor method in the HomePageState to update the user interface using setState when a new color is provided. Prepare groundwork for the dispose method in the next video.
Implement the HomePageState showScore method to update the on-screen score from the game class, trigger a UI update with setState, and override dispose for cleanup.
Override the dispose method to cancel the score and message stream subscriptions, clear subscription data objects from the UDP class, nullify references, and call super.dispose.
Continue refining the UDP class user interface, adding subscription and socket messages, two callback functions, and an extended constructor with a port message and show message callbacks.
In the udp class, initMessaging binds a UDP socket to a port, uses futures to await data, converts bytes to a string, and calls show message with the received data.
Add the UDP sendMessage method to the UI, build a message with the other device's IP and port, and send it via the socket when available.
Learn to integrate the game class with the user interface by wiring callback functions for score and messages, using a UDP object, and navigating back with context and navigator.pop.
Develop the getWinText method in the game class to generate win or loss messages from the score winner, returning formatted strings for each case in Dart/Flutter.
Implement the reset method in the game class to reset scores to zero when there is no winner. Reinitialize the ball speeds x and y to prepare a fresh round.
Identify and fix core issues in the flutter/dart game project by refactoring text box components, removing obsolete reminders, auto layout adjustments, and streamlining udp client/server code.
Fix main.dart by removing an unused import and awaiting a future string to form the IP address, then update the UI with a new row and bold 20-point text.
fix and refactor game.dart in flutter/dart by updating imports, switching cupertino to material, removing unused code, and implementing score display, winner checks, and client-server interactions.
Learn how to run a Flutter/Dart game on two devices, with the first device serving as the server and the second as the client, including connecting devices and validating functionality.
Explore testing a Flutter/Dart multiplayer game on server and client devices, using a networked setup to change color, adjust ball speed, synchronize scores, and exchange in game messages.
In this course you will learn how to create a 2 player WiFi connected mobile game using Flutter and Dart. While learning how to create the game, you will learn a lot about Flutter and Dart.
Movement in the game will be controlled by sensor input. Accelerometer input to be exact.
Only minimal programming knowledge is required, like knowing what variables and functions and classes are. We won’t waste much time on history, installation and other boring topics, and we’ll try to stick to the fun, interesting and cool stuff.
In this course we will go through everything that is needed to create this game. The course will be divided into the following sections:
Introduction and Background
Conception and Preparation
Create and Add the Images
Creating the Game objects
Test Version of the Game
Single Player Version of the Game
Adding Sound
Connecting the Game
Scoring in the Game
The User Interface
Reviewing All the Code
Ideas for Improving the Game
We will start with a little bit of background. Then we’ll go through the idea of the game. Next we’ll get a better idea of what we want to achieve. En suite we’ll start coding a single player version of the game. Then we’ll add functionality for the second player and connect everything to WiFi. Finally, when the game is working as expected, it will be time for the user interface. First we’ll plan on what it should look like, and then we’ll just do it.
During the course, we’ll spend most of our time coding. Everything will be explained and you will have access to all the code. You will also have access to a PDF file containing all the external links that we referred to in the course.
Your feedback is very important to me in order to improve this course in the future. You will automatically have access to any new or improved future content - forever.
If there is something that is not clear, please let me know, so that I can make a video explaining is. Because if something is not clear to you, chances are that it is not clear to someone else as well. And if you have any questions, feel free to contact me through the Udemy page.