Flutter使用CustomPaint自定义五子棋

2023-07-13  本文已影响0人  itfitness

效果展示

实现方法

这里我们使用CustomPaint实现,然后继承CustomPainter实现自定义的Painter,在Painter中进行绘制,而棋子我们自定义一个Chess类

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: CustomPaint(
            size: Size(400,400),
            painter: MyChessPainter(chess_data: chess_data),
          ),
      ),
    );
}
class Chess{
  int x_position;
  int y_position;
  Color chess_color;
  Chess({required this.x_position,required this.y_position,required this.chess_color});
}
class MyChessPainter extends CustomPainter{
  List<Chess> chess_data;
  MyChessPainter({required this.chess_data});
  @override
  void paint(Canvas canvas, Size size) {
    //画棋盘
    drawChessboard(canvas, size);
    //画线
    drawChessLine(canvas,size);
    //画棋子
    drawChess(canvas,size);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }

  ///画棋盘
  void drawChessboard(Canvas canvas, Size size) {
    var paint = Paint()
        ..isAntiAlias = true
        ..style = PaintingStyle.fill //填充
        ..color = Color(0xFFDCC48C);
    Rect rect = Rect.fromLTRB(0, 0, size.width, size.height);
    canvas.drawRect(rect, paint);
  }
  ///画线
  void drawChessLine(Canvas canvas, Size size) {
    var paint = Paint()
      ..isAntiAlias = true
      ..style = PaintingStyle.stroke
      ..color = Colors.black;
    double xOffset = size.width / 15;
    for(int i = 0; i <= 15; i++){
      canvas.drawLine(Offset(i * xOffset, 0), Offset(i * xOffset,size.height), paint);
    }

    double yOffset = size.height / 15;
    for(int i = 0; i <= 15; i++){
      canvas.drawLine(Offset(0,i * yOffset), Offset(size.width,i * yOffset), paint);
    }
  }

  ///画棋子
  void drawChess(Canvas canvas, Size size) {
    var paint = Paint()
      ..isAntiAlias = true
      ..style = PaintingStyle.fill
      ..color = Colors.black;
    double xOffset = size.width / 15;
    double yOffset = size.height / 15;

    if(chess_data.isNotEmpty){
      for(int i = 0; i < chess_data.length ; i++){
        paint.color = chess_data[i].chess_color;
        canvas.drawCircle(Offset(xOffset * chess_data[i].x_position,chess_data[i].y_position * yOffset), xOffset / 3, paint);
      }
    }
  }

}

因为需要根据点击的位置来计算棋子落下的位置,所以我们这里使用GestureDetector,通过里面的onTapDown函数获取点击的位置来计算棋子的位置,另外我们需要两个变量一个存储棋子,另一个判断是白棋还是黑子

List<Chess> chess_data = [];
bool _current_chess_black = true;
@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: GestureDetector(
          onTapDown: (details){
            final tapPosition = details.localPosition;
            final x = tapPosition.dx;
            final y = tapPosition.dy;

            double xOffset = 400 / 15;
            double yOffset = 400 / 15;
            double x_position = x / xOffset;
            double y_position = y / yOffset;

            for(int i = 0 ; i < chess_data.length ; i++){
              if(x_position.round() == chess_data[i].x_position && y_position.round() == chess_data[i].y_position){
                return;
              }
            }
            setState(() {
              chess_data.add(Chess(x_position: x_position.round(), y_position: y_position.round(),chess_color: _current_chess_black ? Colors.black : Colors.white));
              _current_chess_black = !_current_chess_black;
            });
            print("坐标:$x,$y");
          },
          child: CustomPaint(
            size: Size(400,400),
            painter: MyChessPainter(chess_data: chess_data),
          ),
        ),
      ),
    );
  }
上一篇 下一篇

猜你喜欢

热点阅读