美文网首页程序员
Flutter 拼图小游戏

Flutter 拼图小游戏

作者: 一天清晨 | 来源:发表于2020-08-20 14:46 被阅读0次

    效果图

    1597904550873.gif

    主要实现功能

    • 选取系统相册图片
    • 切割图片
    • 打乱图片
    • 移动图片

    选取系统相册

    用的是flutter的image_picker的图片选择器.自己集成一下就可以。不再多说

    image_picker: 0.6.7+4
    

    切割图片

    新建一个类继承CustomPainter, 去进行图片操作,

    import 'package:flutter/material.dart';
    import 'dart:ui' as ui;
    /// 图片裁剪
    class ImageClipper extends CustomPainter {
      final ui.Image image;
      final double left;
      final double top;
      final double right;
      final double bottom;
      final int currentIndex;
    
      ImageClipper(this.image, this.left, this.top, this.right, this.bottom,
          this.currentIndex);
      @override
      void paint(Canvas canvas, Size size) {
        Paint paint = Paint();
        canvas.drawImageRect(
            image,
            Rect.fromLTRB(image.width * left, image.height * top,
                image.width * right, image.height * bottom),
            Rect.fromLTWH(0, 0, size.width, size.height),
            paint);
      }
    
      @override
      bool shouldRepaint(CustomPainter oldDelegate) {
        return false;
      }
    }
    

    然后显示出来

    Container(
          color: Colors.green,
          child: GestureDetector(
            child: CustomPaint(
              painter: clipper,
              size: Size(80, 80),
            ),
            onTap: () {
              tapList.add(clipper.currentIndex);
              showAnimation(clipper.currentIndex);
            },
          ),
        );
    

    上面代码添加了,点击方法。用来进行模块移动, 其中clipper就是切割好的图片,返回来的对象,
    比较重要的一点是选择的需要对选择好了的本地图片处理一下

    Future<ui.Image> _loadImge() async {
        ImageStream imageStream = FileImage(imgPath).resolve(ImageConfiguration());
        Completer<ui.Image> completer = Completer<ui.Image>();
        void imageListener(ImageInfo info, bool synchronousCall) {
          ui.Image image = info.image;
          completer.complete(image);
          imageStream.removeListener(ImageStreamListener(imageListener));
        }
        imageStream.addListener(ImageStreamListener(imageListener));
        return completer.future;
      }
    
      clip(left, top, right, bottom, currentIndex) async {
        ui.Image uiImage;
        _loadImge().then((image) {
          uiImage = image;
        }).whenComplete(() {
          clipperList
              .add(ImageClipper(uiImage, left, top, right, bottom, currentIndex));
          setState(() {});
        });
      }
    

    打乱图片

    这个可以用shuffle()函数去处理,但是打乱之后的数组,不一定能够通过移动完成拼图
    所以采用了一个相当于比较稳的方法,这里提供一下思路。循环次数去进行点击移动操作,记录点击的图片模块,进行移动,这样自动还原的时候把记录的数组进行倒叙之后,在进行移动就可以还原了。。完美
    感兴趣的同学可以用A*搜索算法。

    移动图片

    更换数组位置即可。这个比较简单了

    int emptyIndex = 0;
        int currentIndex = 0;
        ImageClipper emptyClipper;
        for (int i = 0; i < clipperList.length; i++) {
          if (clipperList[i].currentIndex == 8) {
            emptyIndex = i;
            emptyClipper = clipperList[i];
          }
          if (clipperList[i].currentIndex == current) {
            currentIndex = i;
          }
        }
      // 判断是否可以移动
        if (isCanMove(emptyIndex, currentIndex)) {
          // 不移动
          clipperList[emptyIndex] = clipperList[currentIndex];
          clipperList[currentIndex] = emptyClipper;
          if (mounted) {
            setState(() {});
          // 判断是否完成
            isSuccess();
          }
        }
    

    针对9宫格来说。没有写通用的。😊

     bool isCanMove(empty, current) {
        bool isCanMove = false;
        switch (empty) {
          case 0:
            {
              if (current == 1 || current == 3) isCanMove = true;
              break;
            }
          case 1:
            {
              if (current == 0 || current == 2 || current == 4) isCanMove = true;
              break;
            }
          case 2:
            {
              if (current == 1 || current == 5) isCanMove = true;
              break;
            }
          case 3:
            {
              if (current == 0 || current == 4 || current == 6) isCanMove = true;
              break;
            }
          case 4:
            {
              if (current == 1 || current == 3 || current == 5 || current == 7)
                isCanMove = true;
              break;
            }
          case 5:
            {
              if (current == 2 || current == 4 || current == 8) isCanMove = true;
              break;
            }
          case 6:
            {
              if (current == 3 || current == 7) isCanMove = true;
              break;
            }
          case 7:
            {
              if (current == 4 || current == 6 || current == 8) isCanMove = true;
              break;
            }
          case 8:
            {
              if (current == 5 || current == 7) isCanMove = true;
              break;
            }
          default:
        }
        return isCanMove;
      }
    

    相关文章

      网友评论

        本文标题:Flutter 拼图小游戏

        本文链接:https://www.haomeiwen.com/subject/slwsjktx.html