Flutter에서 간단한 패키지를 사용하여 2D물리엔진을 구현해볼 것이다.
이번 글에서는 패키지를 사용하여 구현할 것이며, 다음 글에서는 필자가 이 패키지를 어떻게 구현했는지 알아볼 것이다.
물리 엔진 구현을 위해 사용할 패키지는 Easy Physics 2D라는 패키지이다.
Easy Physics 2D
이 패키지를 통해 구현할 수 있는 것은 공의 충돌, 회전, 가속이다.
현재는 버전이 0.0.1로 할 수 있는 것이 많지 않지만 추후 계속 업데이트 할 예정이다.
pubspec.yaml
파일에 추가한다. dependencies:
easy_physics_2d: '^0.0.1'
$ pub get
import 'package:easy_physics_2d/easy_physics_2d.dart';
가장 기본적인 사용법을 알아본다.
List<dynamic> objList = [];
var ball;
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
),
위의 코드는 이 패키지 사용을 위한 가장 기본적인 코드이다. GravityField
위젯을 추가하고 object를 추가하여 원하는 물체를 중력장에 넣을 수 있다.
GravityField(
objects: objList,
gravity: 1000,
mapX: 350,
mapY: 350,
mapColor: Colors.white,
gravity: 1500,
frictionConstant: 0.8,
elasticConstant: 0.9,
),
중력에 관한 세세한 속성들을 변경할 수 있다. gravity
, frictionConstant
, elasticConstant
등을 바꾸면 된다.
myBall()
로 ball을 추가할 때 원하는 대로 디자인도 변경 할 수 있다.
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;
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];
}
}
ballPath
와 ballPaint
파라미터를 통해 Ball의 Path
와 Paint
를 변경할 수 있다. 하나의 Path
에는 하나의 Paint
가 대응 되므로 ballPath
에 들어갈 리스트와 ballPaint
에 들어갈 리스트의 길이는 같아야 한다. 그리고 이들은 initState에서 선언되어야한다.
또한 Ball 객체에는 다음과 같은 인스턴스 메소드가 있다.
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.
Ball
의 속성을 변경하고 싶다면 꼭 위의 인스턴스 객체를 사용하길 바란다. (ex. 이동)
아래의 코드는 이 패키지를 사용하여 구현한 2D World 이다.
링크에 들어가 직접 플레이할 수 있다.
Flutter Physics World!
Github Code : Code
아래에 3개의 버튼과 슬라이더가 있다.
첫번째 버튼을 누르면 공을 그 위치에서 정지시킨다. 속도만 0이 되기 때문에 중력은 계속 받는다.
두번재 버튼은 공의 속도를 랜덤하게 지정한다.
세번째 슬라이더는 중력을 설정한다.
몇달 전 부터 간간히 손 대고 있던 토이 프로젝트였다. 어떤식으로든 일단 끝내어 상당히 뿌듯하다. 아직 수정하고 보완해야 할 부분이 매우 많기에 그런 업데이트 내용들과 수정 내용들을 계속해서 블로그에 기록할 예정이다.
Finish is Better than Perfect!