Using a simple 2D physical engine on the Flutter
Tags: flutter, physics, engine
Published: 2022-09-01 11:26:54

We will implement a 2D physical engine using a simple package in Flutter.
In this article, we will implement it using a package, and in the next article, I will introduce how I developed this package.

![Examples](https://velog.velcdn.com/images/edge/post/d44d2282-3f98-4abb-befa-239305e3eb60/image.png)

## Easy Physics 2D
The package to be used for physical engine implementation is a package called Easy Physics 2D.
[Easy Physics 2D](https://pub.dev/packages/easy_physics_2d)
![Easy Physics 2D](https://velog.velcdn.com/images/edge/post/ed8b250b-7248-4dd4-abd8-488c74c01c03/image.png)
What this package can implement is the collision, rotation, and acceleration of the ball.
Currently, there is not much that can be done with version 0.0.1, but it will continue to be updated later.

## Installation
1.  Add this package to your `pubspec.yaml` file.
	```
		dependencies:
			easy_physics_2d: '^0.0.1'
	```
2. Install it.
   ``` 
	   $ pub get
   ```
3. Import.
	```
	    import 'package:easy_physics_2d/easy_physics_2d.dart';
	```
## Usage
```dart
	List<dynamic> objList = [];
	var ball;
	
	@override
	void initState(){
		super.initState();
		ball = myBall(  
					xPoint: 100,  
					yPoint: 200,  
					xVelocity: 0,  
					yVelocity: 0,  
					ballRadius: 30,  
					ballMass: 0.5,  
					angularVelocity: 0,  
				);
		objList = [ball];
	}

	GravityField(  
		objects: objList,  
		mapX: 350,  
		mapY: 350,  
		mapColor: Colors.white  
	),
```
This is the most basic code for using a package. You can add a `GravityField` widget and add a list of physical objects that you want to put in the field.
```dart
	GravityField(  
		objects: objList,  
		gravity: 1000,  
		mapX: 350,  
		mapY: 350,  
		mapColor: Colors.white,
		gravity: 1500,
		frictionConstant: 0.8,
		elasticConstant: 0.9,
	),
```
You can change the detailed properties of the field by changing `gravity`, `frictionConstant` and `elasticConstant`.

For the ball objects, you can also change designs.
```dart
class _HomePageState extends State<HomePage> {  
	Paint paint1 = Paint()  
	  ..color = Color(0xff263e63)  
	  ..style = PaintingStyle.stroke  
	  ..strokeWidth = 2;  

	Paint paint2 = Paint()  
	  ..color = Color(0xff15693b)  
	  ..style = PaintingStyle.stroke  
	  ..strokeWidth = 2;  

	List<Paint> paintList = [];  

	Path draw1 = Path();  
	Path draw2 = Path();  
  
	var ball;  
	var ball2;  
  
	@override  
	void initState() {  
		super.initState();  
		for (double i = 0; i < 20 - 1; i++) {  
			draw1.arcTo(Rect.fromCircle(radius: i, center: Offset(0, 0,)), 0, (1.5 * pi), true);  
			draw2.arcTo(Rect.fromCircle(radius: i, center: Offset(0, 0,)), 1.5 * pi, 0.5 * pi, true);  
		}  

		paintList=[paint1, paint2];  

		ball = myBall(  
		        xPoint: 100,  
				yPoint: 200,  
				xVelocity: 0,  
				yVelocity: 0,  
				ballRadius: 30,  
				ballMass: 0.5,  
				angularVelocity: 0,  
				ballPaint: paintList,
				ballPath: [draw1, draw2], 
		  );  
		ball2 = myBall(  
		        xPoint: 150,  
				yPoint: 100,  
				xVelocity: 0,  
				yVelocity: 0,  
				ballRadius: 20,  
				ballMass: 0.5,  
				angularVelocity: 0,  
				 
		);  
		objList = [ball, ball2];  
	}
}
```
with the parameter `ballPath` and `ballPaint`, you can change `Path`  and Colors of the Ball. At this time, the length of `ballPath` List and the length of `ballPaint` List should be the same, and they should be defined in initState.

Each object has the following instance methods, which are easy to use.
```dart
var ball = myBall(  
	        xPoint: 100,  
			yPoint: 200,  
			xVelocity: 0,  
			yVelocity: 0,  
			ballRadius: 30,  
			ballMass: 0.5,  
			angularVelocity: 0,  
		); 
		 
double n;
double m;
int range1 = 100;
int range2 = 1500;
double x, y;

ball.addXpos(n); //return void
ball.subXpos(n); //return void
ball.addYpos(n); //return void
ball.subYpos(n); //return void

ball.addXvel(m); //return void
ball.subXvel(m); //return void
ball.addYvel(m); //return void
ball.subYvel(m); //return void

ball.stop(); //return void
ball.shuffle(range1, range2); //return void : set velocity randomly range1 to range2

ball.setPosition(x, y); //return void
ball.addAngle(n); //return void

ball.isBallRegion(x, y); //return true if (x, y) is in Ball area

ball.updateDraw(); //return void: if you want tochange the position, you should run this method.
```
If you want to move the `Ball`, please use the instance method to control it.

## Example Code
The code below is 2D World implemented using this package.
You can enter the link and play it yourself.
[Flutter Physics World!](https://flutter-physics.web.app/#/)

Github Code : [Code](https://github.com/RGLie/easy_physics_2d/blob/master/example/lib/main.dart)

![Flutter Physics](https://velog.velcdn.com/images/edge/post/97367cb0-5dcf-463a-ace9-282cd27eeb26/image.png)
There are three buttons and a slider below.
Press the first button to stop the ball in that position. Gravity continues to be applied because only the speed becomes zero.
The second button randomly specifies the speed of the ball.
The third slider sets the gravity.

## Conclusion
It was a toy project that I had been working on since a few months ago. I'm quite proud to have finished in any way. Since there are still so many things to revise and supplement, such updates and revisions will continue to be recorded on blogs.

Finish is Better than Perfect!