Basic physics simulations in Flutter
Ever wondered how you could merge the concepts of physics straight into your Flutter application? Well, look no further since this Answer has got you covered! After reading this, you'll be ready to dive into more advanced applications using simulations.
Note: Before proceeding with the answer, ensure that your Flutter setup is complete.
A physics simulation is a computer-based model that replicates the behavior of physical systems in a virtual environment.
It basically tries to copy how real-world things move and interact with each other based on the rules of physics. Therefore, this helps us see how objects would behave in different situations without having to do actual physical experiments.
Flutter's physics module
Flutter offers a physics library that contains different simulations that work differently based on physics concepts.
For instance, gravity simulation works by implementing a gravity environment to aid falls, while a spring simulation focuses on the stiffness of the spring or the mass of the object.
Basic simulation walkthrough
Let's delve into the provided code to understand how it creates a simple physics simulation using Flutter's animation and physics packages.
Necessary Flutter imports
import 'package:flutter/material.dart';import 'package:flutter/physics.dart';void main() {runApp(PhysicsSimulation());}
In this part, we import the required Flutter packages:
flutter/material.dartfor widgets and UI elements, andflutter/physics.dartfor physics simulations.
Stateful widgets
class PhysicsSimulation extends StatefulWidget {@override_PhysicsSimulationState createState() => _PhysicsSimulationState();}
Here, we define a StatefulWidget named
PhysicsSimulation. It allows us to create a widget whose state can change over time. This could be due to interactivity or other customizations.
PhysicsSimulationState class
class _PhysicsSimulationState extends State<PhysicsSimulation>with SingleTickerProviderStateMixin {AnimationController _controller;SpringSimulation _simulation;@overridevoid initState() {super.initState();_controller = AnimationController(vsync: this);_controller.addListener(() {_simulation = SpringSimulation(SpringDescription(mass: 1.0,stiffness: 50.0,damping: 1.0,),_controller.value,200.0,_controller.velocity,);setState(() {});});_simulation = SpringSimulation(SpringDescription(mass: 1.0,stiffness: 50.0,damping: 1.0,),0.0,200.0,0.0,);_controller.animateWith(_simulation);}
In the
_PhysicsSimulationStateclass, we extend the classSingleTickerProviderStateMixinto provide the_controllerwith a ticker that allows it to receive updates whenever the animation is ticking.In the
initStatemethod, we initialize the_controller, which is responsible for controlling our animation. We then add a listener to_controller, so that whenever the animation value changes, the listener gets executed. Inside the listener, we update the_simulationobject based on changing positions and velocity.The
_simulationobject represents a spring simulation that basically represents the physics behavior of the animation. It uses theSpringDescriptionclass so that we can define the properties of the spring, like mass, stiffness, and damping.In this example, we set the mass to 1.0, stiffness to 50.0, and damping to 1.0. These values determine how our animation runs, including the smoothness and movement of the
The
_controller.valuerepresents the current position and_controller.velocityrepresents the current velocity of the animation. We use these values to update the_simulationobject.After setting up the
_controllerand_simulation, we call_controller.animateWith(_simulation)to start the animation with the defined spring simulation.
dispose method
@overridevoid dispose() {_controller.dispose();super.dispose();}
In the
disposemethod, we ensure to dispose of the_controllerto release extra resources, which helps avoid memory leaks.
build method
@overrideWidget build(BuildContext context) {return MaterialApp(home: Scaffold(backgroundColor: Colors.grey[100],appBar: AppBar(title: Text('Simple Physics Simulation'),centerTitle: true,backgroundColor: Colors.blueGrey[900],),body: Center(child: Container(width: 100,height: 100,color: Colors.blue[800],margin: EdgeInsets.only(left: _simulation.x(_controller.value)),),),),);}
In the
buildmethod, we create our UI finally. We use aMaterialAppas the root widget with aScaffoldas its home. TheScaffoldprovides a kind of a basic structure, including the app bar and the body content.The app bar displays the title "Simple Physics Simulation."
In the body, we center a
Containerwith a size of 100 x 100 and a background color ofColors.blue[800]. The container's horizontal position is set by_simulation.x(_controller.value), which calculates the position of the container based on the changing animation value.As the animation runs, the container will move horizontally just like a spring. This results in a pretty cool smooth motion effect.
Complete code
A very basic and easy-to-implement physics simulation is now ready! We can test it using the executable code below.
Feel free to experiment with the code and then click "Run".
import 'package:flutter/material.dart';
import 'package:flutter/physics.dart';
void main() {
runApp(PhysicsSimulation());
}
class PhysicsSimulation extends StatefulWidget {
@override
_PhysicsSimulationState createState() => _PhysicsSimulationState();
}
class _PhysicsSimulationState extends State<PhysicsSimulation>
with SingleTickerProviderStateMixin {
AnimationController _controller;
SpringSimulation _simulation;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this);
_controller.addListener(() {
_simulation = SpringSimulation(
SpringDescription(
mass: 1.0,
stiffness: 50.0,
damping: 1.0,
),
_controller.value,
200.0,
_controller.velocity,
);
setState(() {});
});
_simulation = SpringSimulation(
SpringDescription(
mass: 1.0,
stiffness: 50.0,
damping: 1.0,
),
0.0,
200.0,
0.0,
);
_controller.animateWith(_simulation);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.grey[100],
appBar: AppBar(
title: Text('Simple Physics Simulation'),
centerTitle: true,
backgroundColor: Colors.blueGrey[900],
),
body: Center(
child: Container(
width: 100,
height: 100,
color: Colors.blue[800],
margin: EdgeInsets.only(left: _simulation.x(_controller.value)),
),
),
),
);
}
}
Starting screen
This is how our screen is rendered initially.
Simulation in action
Let's see gravity take over our Flutter application now!
End notes
This is a basic example of a physics-based animation in Flutter. The animation controller and spring simulation work together to create a simple physics simulation that animates the container's position in response to the defined physics properties.
Note: Don't forget to read the advanced physics simulations in Flutter Answer!
Explore other Flutter Answers
Note: Explore the Flutter series here!
What does the stiffness parameter refer to in the SpringSimulation?
Free Resources