[Flutter] 1차원 배열 지하 감옥을 Offset 값 + 그리기로 변환

코드는 DartPard 등에서 직접 수행할 수 있습니다.
※ 미궁에 접근하지 않으면 무작위로 생성됩니다.

1차원 정렬 디스크 관리를 Offset 값으로 변환


배경.

  • "[Flutter] 선언문을 쓰는 방법으로 게임을 만들고 싶어요."은 매우 흥미롭고 상태 관리를 이해하기에 가장 적합
  • 섀시(메쉬) 관리 + 그리기 섹션에서 Offset(기본 기준점과의 거리: Ax, Ay) 활용
  • 이 부분에서 1차원 배열로 지하 감옥 등을 만드는 지하 감옥을 유용해 보려고 한다.
    (1은 벽이고 0은 통로 등)
  • 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 
    1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 
    1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
    

    사전 지식

  • Offset 값(왼쪽 위 모서리(x, y) = (0, 0))
  • 예: 3×3
  • (0.0, 0.0)
    (1.0, 0.0)
    (2.0, 0.0)
    (0.0, 1.0)
    (1.0, 1.0)
    (2.0, 1.0)
    (0.0, 2.0)
    (1.0, 2.0)
    (2.0, 2.0)
  • 1차원 배열(왼쪽 위 부도0)
  • 예: 3×3(길이 9의 정렬)
  • 0
    1
    2
    3
    4
    5
    6
    7
    8

    Step1:Dart

  • 1차원 스토리지에 "1"을 저장하는 위치에 해당하는 Offset 값을 저장합니다.
  • BOARD_SIZE: 디스크의 한 줄 또는 한 열의 격자 수
  • dungeon: 1차원 어레이(전체 1)
  • dungeonOffset: Offset 값으로 저장되는 2D 정렬
  • 활용
    void main() {
      const BOARD_SIZE = 3;
      List<int> dungeon = [1, 1, 1, 1, 1, 1, 1, 1, 1];
      List<List<double>> dungeonOffset = [];
    
      for (int i = 0; i < dungeon.length; i++) {
        if (dungeon[i] == 1) {
          if (i >= BOARD_SIZE) {
            int x = (i % BOARD_SIZE);
            int y = (i ~/ BOARD_SIZE).toInt();
            print('(x, y) = (${x.toDouble()}, ${y.toDouble()})');
            dungeonOffset.add([x.toDouble(), y.toDouble()]);
          } else {
            int x = i;
            int y = 0;
            print('(x, y) = (${x.toDouble()}, ${y.toDouble()})');
            dungeonOffset.add([x.toDouble(), y.toDouble()]);
          }
        }
      }
      print(dungeonOffset);
    }
    
    (x, y) = (0, 0)
    (x, y) = (1, 0)
    (x, y) = (2, 0)
    (x, y) = (0, 1)
    (x, y) = (1, 1)
    (x, y) = (2, 1)
    (x, y) = (0, 2)
    (x, y) = (1, 2)
    (x, y) = (2, 2)
    [[0, 0], [1, 0], [2, 0], [0, 1], [1, 1], [2, 1], [0, 2], [1, 2], [2, 2]]
    

    Step2:Flutter

  • 저장된 Offset 값을 이용하여 Flutter로 화면에 그리기
  • 3×3 예제
  • import 'package:flutter/material.dart';
    
    void main() {
      runApp(App());
    }
    
    class App extends StatelessWidget {
      
      Widget build(BuildContext context) {
        // Step1
        const BOARD_SIZE = 3;
        List<int> dungeon = [1, 1, 1, 1, 1, 1, 1, 1, 1];
        List<List<double>> dungeonOffset = [];
    
        for (int i = 0; i < dungeon.length; i++) {
          if (dungeon[i] == 1) {
            if (i >= BOARD_SIZE) {
              int x = (i % BOARD_SIZE);
              int y = (i ~/ BOARD_SIZE).toInt();
              dungeonOffset.add([x.toDouble(), y.toDouble()]);
            } else {
              int x = i;
              int y = 0;
              dungeonOffset.add([x.toDouble(), y.toDouble()]);
            }
          }
        }
        ////////////////////////////////////////////////////////////
    
        return MaterialApp(
          home: Scaffold(
            body: LayoutBuilder(
              builder: (context, constraint) {
                final gridSize = constraint.maxWidth / BOARD_SIZE;
                return Stack(
                  children: [
                    GridView.builder(
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: BOARD_SIZE,
                      ),
                      itemCount: BOARD_SIZE * BOARD_SIZE,
                      itemBuilder: (context, index) => Container(
                        color: index.isEven
                            ? Colors.green.withOpacity(0.4)
                            : Colors.lightGreen.withOpacity(0.4),
                      ),
                    ),
                    for (final element in dungeonOffset)
                      Positioned(
                        top: element[1] * gridSize,
                        left: element[0] * gridSize,
                        child: Container(
                          width: gridSize,
                          height: gridSize,
                          decoration: BoxDecoration(
                            color: Colors.lightGreen,
                            shape: BoxShape.rectangle,
                          ),
                        ),
                      ),
                  ],
                );
              },
            ),
          ),
        );
      }
    }
    
  • 15×15 예

  • 변경BOARD_SIZEdungeon
  • import 'package:flutter/material.dart';
    
    void main() {
      runApp(App());
    }
    
    class App extends StatelessWidget {
      
      Widget build(BuildContext context) {
        // Step1
        const BOARD_SIZE = 15;
        List<int> dungeon = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
        List<List<double>> dungeonOffset = [];
    
        for (int i = 0; i < dungeon.length; i++) {
          if (dungeon[i] == 1) {
            if (i >= BOARD_SIZE) {
              int x = (i % BOARD_SIZE);
              int y = (i ~/ BOARD_SIZE).toInt();
              dungeonOffset.add([x.toDouble(), y.toDouble()]);
            } else {
              int x = i;
              int y = 0;
              dungeonOffset.add([x.toDouble(), y.toDouble()]);
            }
          }
        }
        print(dungeonOffset);
        ////////////////////////////////////////////////////////////
    
        return MaterialApp(
          home: Scaffold(
            body: LayoutBuilder(
              builder: (context, constraint) {
                final gridSize = constraint.maxWidth / BOARD_SIZE;
                return Stack(
                  children: [
                    GridView.builder(
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: BOARD_SIZE,
                      ),
                      itemCount: BOARD_SIZE * BOARD_SIZE,
                      itemBuilder: (context, index) => Container(
                        color: index.isEven
                            ? Colors.green.withOpacity(0.4)
                            : Colors.lightGreen.withOpacity(0.4),
                      ),
                    ),
                    for (final element in dungeonOffset)
                      Positioned(
                        top: element[1] * gridSize,
                        left: element[0] * gridSize,
                        child: Container(
                          width: gridSize,
                          height: gridSize,
                          decoration: BoxDecoration(
                            color: Colors.lightGreen,
                            shape: BoxShape.rectangle,
                          ),
                        ),
                      ),
                  ],
                );
              },
            ),
          ),
        );
      }
    }
    

    시험을 준비하다

  • 실제 Offset 클래스로 변환한 경우
  • Offset(x.toDouble(), y.toDouble())진행add,

  • 정렬[Offset(0.0, 0.0), Offset(1.0, 0.0),・・・]
  • 좋은 웹페이지 즐겨찾기