오늘은 플러터로 지렁이 게임을 만들어 보려고 한다.
지렁이가 무언갈 먹고 꼬리를 길어지는 류의 게임 (냠냠)
일단 구현할 것은 다음과 같다.
맵을 격자무늬로 나누었다. 한 사각형의 크기를 20x20으로 잡아서 화면에 맞게 적당히 출력하였다.
Wrap(
children: [
for (var j = 0; j < yMax; j++) // 상하
for (var i = 0; i < xMax; i++) // 좌우
Container(
width: rectSize,
height: rectSize,
decoration: BoxDecoration(
border: Border.all(color: Colors.black),
color: Color(0xF0333333),
),
),
],
),
지렁이에 대한 구현은 맵에 생상을 바꿔 칠하는 것으로 대신하기로 했다.
지렁이는 (0, 0) 의 위치에서 생성 및 시작한다.
그리고 지렁이 정보를 관리할 객체를 생성한다.
class Snake{
Point head;
int get x => head.x;
int get y => head.y;
moveLeft() => head = Point(x - 1, y);
moveRight() => head = Point(x + 1, y);
moveUp() => head = Point(x, y - 1);
moveDown() => head = Point(x, y + 1);
}
지렁이의 머리위치를 저장할 head 변수를 생성하는데, 이 Point는 격자의 (x, y)가 될 것이다.
이제 기본적인 맵과 지렁이 구현이 끝났다.👍
다음은 지렁이의 움직임에 대한 구현이다.
지렁이의 움직임은 GestureDetector
로 기본적인 동작만 가능하도록 구현할 것이다.
GestureDetector(
onPanStart: (_) => startPosition = _.globalPosition,
onPanUpdate: onMove,
child: GridMap(),
),
onMove(DragUpdateDetails _) {
Offset _offset = startPosition ?? Offset(0, 0);
double gapX = (_.globalPosition.dx - _offset.dx);
double gapY = (_.globalPosition.dy - _offset.dy);
if (gapX.abs() > gapY.abs()) {
if (gapX > 0) {
snake.moveRight();
} else if (gapX < 0) {
snake.moveLeft();
}
} else {
if (gapY > 0) {
snake.moveDown();
} else if (gapY < 0) {
snake.moveUp();
}
}
setState(() {});
}
벽 충돌 감지는 index overflow에 대한 예외를 처리하면 된다.
꼬리 충돌 감지는 자신의 위치와 다음 갈곳을 비교하여 꼬리의 위치와 비교하면 된다.
class Snake{
...
int maxLength = 0;
Queue<Point> tail = Queue();
}
지렁이 객체에 꼬리를 만들기위해 Queue
를 이용한다.
이 이외에도 지렁이와 구현과 비슷하게 벽과 아이템을 생성하고 고도화를 진행하여 나만의 지렁이 게임을 만들 수 있다.
타 지렁이 게임을 보면 지렁이의 움직임이 멈추지 않고 연속적으로 이뤄진다. 다음에 수정하게 된다면? 이를 구현해볼까한다.
그리고, 아직까지는 개발하는 것보다 글로 정리해서 일지를 작성하는게 더 힘든 것 같다..
https://pub.dev/packages/snake
펍 데브에서 인상깊게본 라이브러리 있어서 공유합니다 ㅎㅎ 글도 잘읽었어용