Skip to content

Instantly share code, notes, and snippets.

@PlugFox
Created January 13, 2025 21:59
Show Gist options
  • Save PlugFox/a74b5b478f357d79d301086ac869db68 to your computer and use it in GitHub Desktop.
Save PlugFox/a74b5b478f357d79d301086ac869db68 to your computer and use it in GitHub Desktop.
Flutter chess example
import 'dart:math' as math;
import 'dart:ui';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
class _Binding = BindingBase
with
GestureBinding,
SchedulerBinding,
ServicesBinding,
PaintingBinding,
SemanticsBinding,
RendererBinding;
/// Биндинь - соединение между движком Flutter и движком рендеринга
final binding = () {
final instance = _Binding()..deferFirstFrame();
return instance;
}();
void main() {
final dispatcher = binding.platformDispatcher;
final views = dispatcher.views;
if (views.isEmpty) {
SystemNavigator.pop();
return;
}
final view = views.first;
// Получаем информацию о размерах экрана
final windowSize = view.physicalSize;
final pixelRatio = view.devicePixelRatio;
final logicalSize = windowSize / pixelRatio;
// Создаем рекордер для записи команд рисования
final recorder = PictureRecorder();
final canvas = Canvas(recorder);
// Определяем размеры и положение шахматной доски
// Центрируем доску на экране
final boardSize = math.min(logicalSize.width, logicalSize.height) * 0.8;
final rect = Rect.fromCenter(
center: Offset(logicalSize.width / 2, logicalSize.height / 2),
width: boardSize,
height: boardSize,
);
// Рисуем доску и фигуры
drawChessboard(canvas, rect);
drawPieces(canvas, rect);
drawBoardBorder(canvas, rect);
drawCoordinates(canvas, rect);
// Создаем PictureLayer и сохраняем в нем результат рисования
final pictureLayer = PictureLayer(rect)..picture = recorder.endRecording();
// Создаем корневой слой и добавляем в него наш PictureLayer
final rootLayer = OffsetLayer()..append(pictureLayer);
// Создаем сцену и отправляем ее на отрисовку
final sceneBuilder = SceneBuilder()
..pushClipRect(rect) // Обрезаем всё за пределами доски
..pop();
final scene = rootLayer.buildScene(sceneBuilder);
view.render(scene);
// Добавляем обработчик изменения размера окна
dispatcher
..onError = (error, stackTrace) {
print('! Error: $error\n$stackTrace'); // ignore: avoid_print
return true;
}
..onMetricsChanged = () {
// ...
}
..onLocaleChanged = () {
// ...
}
..onDrawFrame = () {
// ...
}
..onViewFocusChange = (event) {
// ...
};
binding.allowFirstFrame();
}
void drawChessboard(Canvas canvas, Rect rect) {
final paint = Paint();
final cellSize = rect.width / 8;
// Рисуем базовый фон доски
canvas.drawRect(rect, Paint()..color = const Color(0xFFE5C9A7));
// Рисуем темные клетки
paint.color = const Color(0xFF7A4F31);
for (var row = 0; row < 8; row++) {
for (var col = 0; col < 8; col++) {
if ((row + col) % 2 == 1) {
canvas.drawRect(
Rect.fromLTWH(
rect.left + col * cellSize,
rect.top + row * cellSize,
cellSize,
cellSize,
),
paint,
);
}
}
}
}
void drawPieces(Canvas canvas, Rect rect) {
final cellSize = rect.width / 8;
final paint = Paint()
..style = PaintingStyle.fill
..strokeWidth = 2.0;
const black = Color(0xFF000000), white = Color(0xFFFFFFFF);
// Функция для рисования фигуры
void Function({required bool isWhite}) drawPiece(int col, int row) =>
({required isWhite}) {
final center = Offset(
rect.left + (col + 0.5) * cellSize,
rect.top + (row + 0.5) * cellSize,
);
paint.color = isWhite ? white : black;
// Рисуем базовую форму фигуры (упрощенно)
canvas.drawCircle(center, cellSize * 0.4, paint);
// Добавляем обводку
paint
..style = PaintingStyle.stroke
..color = isWhite ? black : white;
canvas.drawCircle(center, cellSize * 0.4, paint);
paint.style = PaintingStyle.fill;
};
// Расставляем фигуры начальной позиции
for (var col = 0; col < 8; col++) {
// Черные пешки
drawPiece(col, 1)(isWhite: false);
// Белые пешки
drawPiece(col, 6)(isWhite: true);
}
// Расставляем основные фигуры
for (var col = 0; col < 8; col++) {
drawPiece(col, 0)(isWhite: false); // Черные фигуры
drawPiece(col, 7)(isWhite: true); // Белые фигуры
}
}
void drawBoardBorder(Canvas canvas, Rect rect) {
final paint = Paint()
..color = const Color(0xFF4A3728)
..style = PaintingStyle.stroke
..strokeWidth = 4.0;
// Рисуем внешнюю рамку
canvas.drawRect(rect, paint);
}
void drawCoordinates(Canvas canvas, Rect rect) {
final textStyle = TextStyle(
color: const Color(0xFF000000),
fontSize: rect.width / 30,
fontWeight: FontWeight.bold,
);
final cellSize = rect.width / 8;
// Рисуем буквы (a-h)
for (var i = 0; i < 8; i++) {
final letter = String.fromCharCode('a'.codeUnitAt(0) + i);
final textSpan = TextSpan(text: letter, style: textStyle);
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
)..layout();
textPainter.paint(
canvas,
Offset(
rect.left + i * cellSize + cellSize / 2 - textPainter.width / 2,
rect.bottom + 5,
),
);
}
// Рисуем цифры (1-8)
for (var i = 0; i < 8; i++) {
final number = (8 - i).toString();
final textSpan = TextSpan(text: number, style: textStyle);
final textPainter = TextPainter(
text: textSpan,
textDirection: TextDirection.ltr,
)..layout();
textPainter.paint(
canvas,
Offset(
rect.left - textPainter.width - 5,
rect.top + i * cellSize + cellSize / 2 - textPainter.height / 2,
),
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment