Flutter/블럭 퍼즐 맞추기(Android)
[Flutter] 위젯 원하는 위치에 배치하기(Positioned) & 테트리스 모양 만들기
FDG
2023. 6. 5. 00:24
Positioned을 이용하면 원하는 위치에 픽셀 단위로 배치를 할 수 있다.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class TetrisBlocks {
final List<List<int>> shape;
TetrisBlocks(this.shape);
}
class MyApp extends StatelessWidget {
final TetrisBlocks iTetrisBlocks = TetrisBlocks([
[1, 1, 1, 1],
]);
final TetrisBlocks jTetrisBlocks = TetrisBlocks([
[1, 0, 0],
[1, 1, 1],
]);
final TetrisBlocks lTetrisBlocks = TetrisBlocks([
[0, 0, 1],
[1, 1, 1],
]);
final TetrisBlocks oTetrisBlocks = TetrisBlocks([
[1, 1],
[1, 1],
]);
final TetrisBlocks sTetrisBlocks = TetrisBlocks([
[0, 1, 1],
[1, 1, 0],
]);
final TetrisBlocks tTetrisBlocks = TetrisBlocks([
[0, 1, 0],
[1, 1, 1],
]);
final TetrisBlocks zTetrisBlocks = TetrisBlocks([
[1, 1, 0],
[0, 1, 1],
]);
final TetrisBlocks zFlipTetrisBlocks = TetrisBlocks([
[0, 1, 1],
[1, 1, 0],
]);
final TetrisBlocks thumbTetrisBlocks = TetrisBlocks([
[0, 1],
[1, 1],
[1, 1],
]);
final TetrisBlocks halfITetrisBlocks = TetrisBlocks([
[1],
[1],
]);
final TetrisBlocks bigOTetrisBlocks = TetrisBlocks([
[1, 1],
[1, 1],
[1, 1],
]);
List<List<int>> _rotateShape(List<List<int>> shape) {
int rows = shape.length;
int columns = shape[0].length;
List<List<int>> rotatedShape =
List.generate(columns, (index) => List.generate(rows, (index) => 0));
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
rotatedShape[j][rows - i - 1] = shape[i][j];
}
}
return rotatedShape;
}
Widget _buildTetrisBlocks(TetrisBlocks tetrisBlocks, int rotation, Color c,
double size, double gap) {
List<List<int>> rotatedShape = tetrisBlocks.shape;
for (int i = 0; i < rotation; i++) {
rotatedShape = _rotateShape(rotatedShape);
}
return Column(
children: rotatedShape.map((row) {
return Row(
children: row.map((block) {
return Container(
width: size,
height: size,
color: block == 1 ? c : Colors.transparent,
margin: EdgeInsets.all(gap),
);
}).toList(),
);
}).toList(),
);
}
@override
Widget build(BuildContext context) {
double gapSize = 0;
double blockSize = 20;
double gridSize = blockSize + gapSize;
double hCenter = MediaQuery.of(context).size.width / 2;
double vCenter = MediaQuery.of(context).size.height / 2;
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Tetris Shapes')),
body: Center(
child: Stack(
children: [
Positioned(
top: vCenter + gridSize * 0,
left: hCenter + gridSize * 0,
child: _buildTetrisBlocks(
iTetrisBlocks, 0, Colors.red, blockSize, gapSize),
),
Positioned(
top: vCenter + gridSize * 1,
left: hCenter + gridSize * 0,
child: _buildTetrisBlocks(
iTetrisBlocks, 1, Colors.grey, blockSize, gapSize),
),
Positioned(
top: vCenter + gridSize * 1,
left: hCenter + gridSize * 1,
child: _buildTetrisBlocks(
oTetrisBlocks, 0, Colors.green, blockSize, gapSize),
),
Positioned(
top: vCenter + gridSize * 2,
left: hCenter + gridSize * 1,
child: _buildTetrisBlocks(
lTetrisBlocks, 0, Colors.cyan, blockSize, gapSize),
),
Positioned(
top: vCenter + gridSize * 3,
left: hCenter + gridSize * 3,
child: _buildTetrisBlocks(
tTetrisBlocks, 3, Colors.yellow, blockSize, gapSize),
),
Positioned(
top: vCenter + gridSize * 0,
left: hCenter + gridSize * 3,
child: _buildTetrisBlocks(
tTetrisBlocks, 3, Colors.orange, blockSize, gapSize),
),
Positioned(
top: vCenter + gridSize * 4,
left: hCenter + gridSize * 0,
child: _buildTetrisBlocks(
zFlipTetrisBlocks, 0, Colors.black, blockSize, gapSize),
),
Positioned(
top: vCenter + gridSize * 5,
left: hCenter + gridSize * 2,
child: _buildTetrisBlocks(thumbTetrisBlocks, 1,
Colors.deepOrange, blockSize, gapSize),
),
Positioned(
top: vCenter + gridSize * 5,
left: hCenter + gridSize * -1,
child: _buildTetrisBlocks(
jTetrisBlocks, 0, Colors.blue, blockSize, gapSize),
),
Positioned(
top: vCenter + gridSize * 4,
left: hCenter + gridSize * -2,
child: _buildTetrisBlocks(
jTetrisBlocks, 1, Colors.amber, blockSize, gapSize),
),
Positioned(
top: vCenter + gridSize * 3,
left: hCenter + gridSize * -2,
child: _buildTetrisBlocks(
halfITetrisBlocks, 1, Colors.lime, blockSize, gapSize),
),
Positioned(
top: vCenter + gridSize * 0,
left: hCenter + gridSize * -2,
child: _buildTetrisBlocks(
bigOTetrisBlocks, 0, Colors.teal, blockSize, gapSize),
),
],
),
),
),
);
}
}
결과