Skip to content
Snippets Groups Projects
Select Git revision
  • 01a604bcd0af615bc34832db8ed3065979a9271c
  • master default protected
  • 100-upgrade-framework-and-dependencies
  • 65-improve-app-metadata
  • Release_1.8.0_80 protected
  • Release_1.7.2_79 protected
  • Release_1.7.1_78 protected
  • Release_1.7.0_77 protected
  • Release_1.6.0_76 protected
  • Release_1.5.0_75 protected
  • Release_1.4.0_74 protected
  • Release_1.3.2_73 protected
  • Release_1.3.1_72 protected
  • Release_1.3.0_71 protected
  • Release_1.2.1_70 protected
  • Release_1.2.0_69 protected
  • Release_1.1.3_68 protected
  • Release_1.1.2_67 protected
  • Release_1.1.1_66 protected
  • Release_1.1.0_65 protected
  • Release_1.0.63_64 protected
  • Release_1.0.62_63 protected
  • Release_1.0.61_62 protected
  • Release_1.0.60_61 protected
24 results

game_board.dart

Blame
  • game_board.dart 5.19 KiB
    import 'package:flutter/material.dart';
    import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
    
    import 'package:random/cubit/activity/activity_cubit.dart';
    import 'package:random/models/activity/activity.dart';
    import 'package:random/models/settings/settings_activity.dart';
    import 'package:random/ui/painters/cell_painter.dart';
    import 'package:random/ui/widgets/game/game_score.dart';
    
    class GameBoardWidget extends StatefulWidget {
      const GameBoardWidget({
        super.key,
        required this.activity,
        required this.widgetSize,
      });
    
      final Activity activity;
      final Size widgetSize;
    
      @override
      State<GameBoardWidget> createState() => _GameBoardWidget();
    }
    
    class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMixin {
      List<List<Animation<double>?>> animations = [];
    
      void resetAnimations(ActivitySettings activitySettings) {
        final int boardSize = activitySettings.boardSizeValue;
    
        animations = List.generate(
          boardSize,
          (i) => List.generate(
            boardSize,
            (i) => null,
          ),
        );
      }
    
      void removeCell(BuildContext context, int x, int y) {
        final ActivityCubit activityCubit = BlocProvider.of<ActivityCubit>(context);
        final Activity updatedGame = activityCubit.state.currentActivity;
    
        // "remove" cell, update counters
        updatedGame.increaseScore(updatedGame.getCellValue(x, y));
        updatedGame.increaseMovesCount();
        updatedGame.updateCellValue(x, y, null);
        setState(() {});
    
        // "move down" cells
        final controller = AnimationController(
          vsync: this,
          duration: const Duration(milliseconds: 750),
        )..addListener(() {
            if (mounted) {
              setState(() {});
            }
          });
    
        if (mounted) {
          setState(() {});
        }
    
        Animation<double> animation = Tween(
          begin: 0.0,
          end: 1.0,
        ).animate(CurvedAnimation(
          curve: Curves.bounceOut,
          parent: controller,
        ))
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              // Update cell values
              for (var i = 0; i < y; i++) {
                updatedGame.updateCellValue(x, (y - i), updatedGame.getCellValue(x, (y - i) - 1));
              }
              updatedGame.setRandomCellValue(x, 0, updatedGame.activitySettings);
    
              resetAnimations(updatedGame.activitySettings);
              setState(() {});
    
              controller.dispose();
            }
          });
    
        for (var i = 0; i < y; i++) {
          animations[(y - i) - 1][x] = animation;
        }
    
        controller.forward().orCancel;
      }
    
      Widget buildBoard() {
        final double widgetWidth = widget.widgetSize.width;
        final double widgetHeight = widget.widgetSize.height;
    
        final int rowsCount = widget.activity.activitySettings.boardSizeValue;
        final int columnsCount = widget.activity.activitySettings.boardSizeValue;
    
        final double cellWidth = widgetWidth / columnsCount;
        final double cellHeight = widgetHeight / rowsCount;
    
        if (animations.isEmpty) {
          resetAnimations(widget.activity.activitySettings);
        }
    
        final List<Widget> cells = [];
    
        for (var y = 0; y < rowsCount; y++) {
          for (var x = 0; x < columnsCount; x++) {
            final int? value = widget.activity.getCellValue(x, y);
    
            if (value != null) {
              final Animation<double>? translation = animations[y][x];
    
              final Widget cellContent = CustomPaint(
                size: Size(cellWidth, cellHeight),
                willChange: false,
                painter: CellPainter(value: value),
              );
    
              final Widget cellWidget = Positioned(
                left: (x * cellWidth).toDouble(),
                top: ((y + (translation?.value ?? 0)) * cellHeight).toDouble(),
                child: SizedBox(
                  width: cellWidth,
                  height: cellHeight,
                  child: cellContent,
                ),
              );
    
              cells.add(cellWidget);
            }
          }
        }
    
        return Container(
          width: widgetWidth,
          height: widgetHeight,
          color: Colors.black,
          child: Stack(
            children: cells,
          ),
        );
      }
    
      Widget interactiveBoard(BuildContext context) {
        final double widgetWidth = widget.widgetSize.width;
        final double widgetHeight = widget.widgetSize.height;
    
        final int rowsCount = widget.activity.activitySettings.boardSizeValue;
        final int columnsCount = widget.activity.activitySettings.boardSizeValue;
    
        return GestureDetector(
          child: buildBoard(),
          onTapUp: (details) {
            bool canRemoveCell = true;
            for (var row in animations) {
              for (var cell in row) {
                if (cell != null) {
                  canRemoveCell = false;
                }
              }
            }
    
            if (canRemoveCell) {
              double xTap = details.localPosition.dx;
              double yTap = details.localPosition.dy;
    
              int x = (xTap / widgetWidth * columnsCount).toInt();
              int y = (yTap / widgetHeight * rowsCount).toInt();
              printlog('[$x,$y]');
    
              removeCell(context, x, y);
            } else {
              printlog('animation in progress...');
            }
          },
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            interactiveBoard(context),
            GameScoreWidget(activity: widget.activity),
          ],
        );
      }
    }