import 'dart:math'; import 'package:flutter/material.dart'; class BoardPainter extends CustomPainter { const BoardPainter(this.currentTetrimino); final int currentTetrimino; void drawPixels( List<List<int>> pixels, Canvas canvas, double drawSize, Color pixelColor, ) { int blockWidth = 1; int blockHeight = 1; for (List<int> pixel in pixels) { int x = pixel[0] + 1; int y = pixel[1] + 1; if (x > blockWidth) { blockWidth = x; } if (y > blockHeight) { blockHeight = y; } } final double pixelSize = drawSize / (max(blockWidth, blockHeight) + 2); final double xOffset = (blockHeight > blockWidth) ? (blockHeight - blockWidth) * pixelSize / 2 : 0; final double yOffset = (blockWidth > blockHeight) ? (blockWidth - blockHeight) * pixelSize / 2 : 0; // Fill background final paintPixelBackground = Paint(); paintPixelBackground.color = pixelColor; paintPixelBackground.style = PaintingStyle.fill; for (List<int> pixel in pixels) { final int x = pixel[0]; final int y = pixel[1]; final Rect pixelBackground = Rect.fromPoints( Offset(xOffset + pixelSize * (x + 1), yOffset + pixelSize * (y + 1)), Offset(xOffset + pixelSize * (x + 2), yOffset + pixelSize * (y + 2))); canvas.drawRect(pixelBackground, paintPixelBackground); } // Border lines final paintPixelBorder = Paint(); paintPixelBorder.color = Colors.grey.shade200; paintPixelBorder.style = PaintingStyle.stroke; paintPixelBorder.strokeWidth = 4; for (List<int> pixel in pixels) { final int x = pixel[0]; final int y = pixel[1]; final Rect rectBackground = Rect.fromPoints( Offset(xOffset + pixelSize * (x + 1), yOffset + pixelSize * (y + 1)), Offset(xOffset + pixelSize * (x + 2), yOffset + pixelSize * (y + 2))); canvas.drawRect(rectBackground, paintPixelBorder); } } @override void paint(Canvas canvas, Size size) { final double drawSize = min(size.width, size.height); // Fill background final paintBackground = Paint(); paintBackground.color = Colors.grey.shade800; paintBackground.style = PaintingStyle.fill; final Rect rectBackground = Rect.fromPoints(const Offset(0, 0), Offset(drawSize, drawSize)); canvas.drawRect(rectBackground, paintBackground); // Add tetrimino switch (currentTetrimino) { // empty case 0: break; // straight case 1: drawPixels([ [0, 0], [1, 0], [2, 0], [3, 0] ], canvas, drawSize, Colors.cyan); break; // square case 2: drawPixels([ [0, 0], [0, 1], [1, 0], [1, 1] ], canvas, drawSize, Colors.amber); break; // T case 3: drawPixels([ [0, 0], [1, 0], [2, 0], [1, 1] ], canvas, drawSize, Colors.purple); break; // L case 4: drawPixels([ [0, 0], [0, 1], [0, 2], [1, 2] ], canvas, drawSize, Colors.deepOrange); break; // skew case 5: drawPixels([ [0, 0], [0, 1], [1, 1], [1, 2] ], canvas, drawSize, Colors.green); break; default: } } @override bool shouldRepaint(CustomPainter oldDelegate) { return false; } }