flutter中国象棋


import 'dart:math';

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Chinese Chess',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ChineseChessGame(),
    );
  }
}

class ChineseChessGame extends StatefulWidget {
  @override
  _ChineseChessGameState createState() => _ChineseChessGameState();
}

class _ChineseChessGameState extends State {

  @override
  Widget build(BuildContext context) {
    return Scaffold(

      appBar: AppBar(
        title: const Text('中国象棋'),
      ),
      body: ChessBoard(),
    );
  }
}


class ChessBoard extends StatefulWidget {
  @override
  _ChessBoardState createState() => _ChessBoardState();
}

class _ChessBoardState extends State {
  // 定义棋盘大小和格子大小
  final int boardSize = 9; // 中国象棋棋盘是9x10的网格
  final double gridSize = 50.0; // 每个格子的大小
  List chessList = [];
  Chess? selectedChess = null;
  List chessCmpList = [];

  @override
  void initState() {
    super.initState();
    newGame();
    chessCmpList=createPieces();
  }
  void newGame() {
    chessList = getInitChesses();

  }

  List getInitChesses() {
    List list = [];
    list = [
      Chess(text: "車", color: Colors.black, offset: const Offset(0, 0)),
      Chess(text: "馬", color: Colors.black, offset: const Offset(1, 0)),
      Chess(text: "象", color: Colors.black, offset: const Offset(2, 0)),
      Chess(text: "士", color: Colors.black, offset: const Offset(3, 0)),
      Chess(text: "将", color: Colors.black, offset: const Offset(4, 0)),
      Chess(text: "士", color: Colors.black, offset: const Offset(5, 0)),
      Chess(text: "象", color: Colors.black, offset: const Offset(6, 0)),
      Chess(text: "馬", color: Colors.black, offset: const Offset(7, 0)),
      Chess(text: "車", color: Colors.black, offset: const Offset(8, 0)),
      Chess(text: "炮", color: Colors.black, offset: const Offset(1, 2)),
      Chess(text: "炮", color: Colors.black, offset: const Offset(7, 2)),
      Chess(text: "兵", color: Colors.black, offset: const Offset(0, 3)),
      Chess(text: "兵", color: Colors.black, offset: const Offset(2, 3)),
      Chess(text: "兵", color: Colors.black, offset: const Offset(4, 3)),
      Chess(text: "兵", color: Colors.black, offset: const Offset(6, 3)),
      Chess(text: "兵", color: Colors.black, offset: const Offset(8, 3)),
      //======
      Chess(text: "車", color: Colors.red, offset: const Offset(0, 9)),
      Chess(text: "馬", color: Colors.red, offset: const Offset(1, 9)),
      Chess(text: "象", color: Colors.red, offset: const Offset(2, 9)),
      Chess(text: "士", color: Colors.red, offset: const Offset(3, 9)),
      Chess(text: "将", color: Colors.red, offset: const Offset(4, 9)),
      Chess(text: "士", color: Colors.red, offset: const Offset(5, 9)),
      Chess(text: "象", color: Colors.red, offset: const Offset(6, 9)),
      Chess(text: "馬", color: Colors.red, offset: const Offset(7, 9)),
      Chess(text: "車", color: Colors.red, offset: const Offset(8, 9)),
      Chess(text: "炮", color: Colors.red, offset: const Offset(1, 7)),
      Chess(text: "炮", color: Colors.red, offset: const Offset(7, 7)),
      Chess(text: "兵", color: Colors.red, offset: const Offset(0, 6)),
      Chess(text: "兵", color: Colors.red, offset: const Offset(2, 6)),
      Chess(text: "兵", color: Colors.red, offset: const Offset(4, 6)),
      Chess(text: "兵", color: Colors.red, offset: const Offset(6, 6)),
      Chess(text: "兵", color: Colors.red, offset: const Offset(8, 6)),
    ];
    return list;
  }

  bool existChess(Offset offsetIndex) {
  for (Chess chess in chessList) {
        if (chess.offset.dx == offsetIndex.dx && chess.offset.dy == offsetIndex.dy) {
          return true;
        }
      }
    return false;
  }
  // bool checkExistChess(List offsets) {
  //   for(Offset offset in offsets) {
  //     if(existChess(offset))
  //       return true;
  //   }
  //   return false;
  // }


  void clickEventProcess(Offset offset) {
    setState(() {
      print('点击位置: ${offset}');
      // 更新棋盘状态
      Offset? tempOffsetIndex = findClickedOffsetIndex(offset);
      if (tempOffsetIndex == null) {
        return;
      }
      //在棋盘内
      //检查是否选中棋子
      Chess? chess = findClickedChess(tempOffsetIndex);
      if (chess == null) {
        //未选中棋子
        if (selectedChess == null) {
          //之前也没有选中棋子,不进行处理
        } else {
          //之前选中棋子,判断是否可以移动棋子
          if (chess != selectedChess && canMove(selectedChess!, tempOffsetIndex)) {
            selectedChess!.offset = tempOffsetIndex;
            selectedChess?.setSelected();
            selectedChess = null;
          }
        }
      } else {
        if (selectedChess == null) {
          selectedChess ??= chess;
          selectedChess?.setSelected();
        } else {
          if (selectedChess == chess) {

          } else {
            if (chess.color != selectedChess?.color && canEat(selectedChess!, tempOffsetIndex)) {
              selectedChess!.offset = tempOffsetIndex;
              selectedChess?.setSelected();
              chessList.remove(chess);
              selectedChess=null;
            }else if(chess.color == selectedChess?.color){
              selectedChess?.setSelected();
              selectedChess = chess;
              selectedChess?.setSelected();
            }
          }
        }
      }
    });
  }

  bool canMove(Chess selectedChess, Offset tempOffset) {
    if (tempOffset.dx < 0 || tempOffset.dx > 8 || tempOffset.dy < 0 || tempOffset.dy > 9) {
      return false;
    }

    if (selectedChess.text == "将") {
      if(selectedChess.color==Colors.black){
        if (tempOffset.dx < 3 || tempOffset.dx > 5 || tempOffset.dy < 0 || tempOffset.dy > 2) {
          return false;
        }
      }else {
        if (tempOffset.dx < 3 || tempOffset.dx > 5 || tempOffset.dy < 7 || tempOffset.dy > 9) {
          return false;
        }
      }
      if( !((distance(selectedChess.offset.dx, tempOffset.dx )==1.0&&distance(selectedChess.offset.dy, tempOffset.dy )==0)||(distance
        (selectedChess.offset.dx, tempOffset.dx )==0&&distance(selectedChess.offset.dy, tempOffset.dy )==1))){
        return false;
      }
    } else if (selectedChess.text == "士") {
      if(selectedChess.color==Colors.black){
        if (tempOffset.dx < 3 || tempOffset.dx > 5 || tempOffset.dy < 0 || tempOffset.dy > 2) {
          return false;
        }
        if( !(distance(selectedChess.offset.dx, tempOffset.dx )==1.0&&distance(selectedChess.offset.dy, tempOffset.dy )==1.0)){
          return false;
        }
      }else {
          if (tempOffset.dx < 3 || tempOffset.dx > 5 || tempOffset.dy < 7 || tempOffset.dy > 9) {
            return false;
          }
          if( !(distance(selectedChess.offset.dx, tempOffset.dx )==1.0&&distance(selectedChess.offset.dy, tempOffset.dy )==1.0)){
            return false;
          }
        }
    } else if (selectedChess.text == "象") {
      if (tempOffset.dx < 0 || tempOffset.dx > 8 || tempOffset.dy < 0 || tempOffset.dy > 9) {
        return false;
      }
      if(selectedChess.color==Colors.black){
        if(tempOffset.dy > 4)
          return false;
      }else{
        if(tempOffset.dy <5)
          return false;
      }
      if(!(distance(selectedChess.offset.dx,tempOffset.dx)==2.0&&distance(selectedChess.offset.dy,tempOffset.dy)==2.0)){
        print("象必须走田");
        return false;
      }
      // todo 判断是否被阻挡
      if(distance(selectedChess.offset.dx,tempOffset.dx)==2.0&&distance(selectedChess.offset.dy,tempOffset.dy)==2.0){
        if(existChess(Offset((selectedChess.offset.dx+tempOffset.dx)/2,(selectedChess.offset.dy+tempOffset.dy)/2))){
          print("象眼阻塞");
          return false;
        }
      }


    } else if (selectedChess.text == "馬") {
      if (tempOffset.dx < 0 || tempOffset.dx > 8 || tempOffset.dy < 0 || tempOffset.dy > 9) {
        return false;
      }
      if(!(distance(selectedChess.offset.dx,tempOffset.dx)==2.0&&distance(selectedChess.offset.dy,tempOffset.dy)==1.0||distance
        (selectedChess.offset.dx,tempOffset.dx)==1.0&&distance(selectedChess.offset.dy,tempOffset.dy)==2.0)){
        print("马必须走日");
        return false;
      }

      if(distance(selectedChess.offset.dx,tempOffset.dx)==2.0){
        if(existChess(Offset((selectedChess.offset.dx+tempOffset.dx)/2,selectedChess.offset.dy))){
          print("撇脚马");
          return false;
        }
      }
      if(distance(selectedChess.offset.dy,tempOffset.dy)==2.0){
        if(existChess(Offset(selectedChess.offset.dx,(selectedChess.offset.dy+tempOffset.dy)/2))){
          print("撇脚马");
          return false;
        }
      }
      // todo 判断是否被阻挡
    } else if (selectedChess.text == "車") {
      if (tempOffset.dx < 0 || tempOffset.dx > 8 || tempOffset.dy < 0 || tempOffset.dy > 9) {
        return false;
      }
      if(selectedChess.offset.dx != tempOffset.dx&& selectedChess.offset.dy != tempOffset.dy){
        return false;
      }
      // todo 判断是否被阻挡
      if(selectedChess.offset.dx == tempOffset.dx&&distance(selectedChess.offset.dy, tempOffset.dy)>1){

        for (int i = 1; i < distance(selectedChess.offset.dy, tempOffset.dy).toInt(); i++) {
          if(existChess(Offset(selectedChess.offset.dx,min(tempOffset.dy, selectedChess.offset.dy)+i))){
            print("猪被挡");
            return false;
          }
        }
      }

      if(selectedChess.offset.dy == tempOffset.dy&&distance(selectedChess.offset.dx, tempOffset.dx)>1){

        for (int i = 1; i < distance(selectedChess.offset.dx, tempOffset.dx).toInt(); i++) {
          if(existChess(Offset(min(tempOffset.dx, selectedChess.offset.dx)+i,selectedChess.offset.dy))){
            print("猪被挡");
            return false;
          }
        }
      }


    } else if (selectedChess.text == "炮") {
      if (tempOffset.dx < 0 || tempOffset.dx > 8 || tempOffset.dy < 0 || tempOffset.dy > 9) {
        return false;
      }
      if(selectedChess.offset.dx != tempOffset.dx&& selectedChess.offset.dy != tempOffset.dy){
        return false;
      }
      if(selectedChess.offset.dx == tempOffset.dx&&distance(selectedChess.offset.dy, tempOffset.dy)>1){

        for (int i = 1; i < distance(selectedChess.offset.dy, tempOffset.dy).toInt(); i++) {
          if(existChess(Offset(selectedChess.offset.dx,min(tempOffset.dy, selectedChess.offset.dy)+i))){
            print("炮被挡");
            return false;
          }
        }
      }

      if(selectedChess.offset.dy == tempOffset.dy&&distance(selectedChess.offset.dx, tempOffset.dx)>1){

        for (int i = 1; i < distance(selectedChess.offset.dx, tempOffset.dx).toInt(); i++) {
          if(existChess(Offset(min(tempOffset.dx, selectedChess.offset.dx)+i,selectedChess.offset.dy))){
            print("炮被挡");
            return false;
          }
        }
      }

      // todo 判断是否被阻挡
    } else if (selectedChess.text == "兵") {
      if (tempOffset.dx < 0 || tempOffset.dx > 8 || tempOffset.dy < 0 || tempOffset.dy > 9) {
        return false;
      }
      if(selectedChess.color==Colors.black){
        if(tempOffset.dyselectedChess.offset.dy){
          return false;
        }
        if(tempOffset.dx!=selectedChess.offset.dx&&selectedChess.offset.dy>6){
          return false;
        }
      }
      if( !((distance(selectedChess.offset.dx, tempOffset.dx )==1.0&&distance(selectedChess.offset.dy, tempOffset.dy )==0)||(distance
        (selectedChess.offset.dx, tempOffset.dx )==0&&distance(selectedChess.offset.dy, tempOffset.dy )==1))){
        return false;
      }
    }

  return  true;
}


  bool canEat(Chess selectedChess, Offset tempOffset) {
    if (tempOffset.dx < 0 || tempOffset.dx > 8 || tempOffset.dy < 0 || tempOffset.dy > 9) {
      return false;
    }

    if (selectedChess.text == "将") {
      if(selectedChess.color==Colors.black){
        if (tempOffset.dx < 3 || tempOffset.dx > 5 || tempOffset.dy < 0 || tempOffset.dy > 2) {
          return false;
        }
      }else {
        if (tempOffset.dx < 3 || tempOffset.dx > 5 || tempOffset.dy < 7 || tempOffset.dy > 9) {
          return false;
        }
      }
      if( !((distance(selectedChess.offset.dx, tempOffset.dx )==1.0&&distance(selectedChess.offset.dy, tempOffset.dy )==0)||(distance
        (selectedChess.offset.dx, tempOffset.dx )==0&&distance(selectedChess.offset.dy, tempOffset.dy )==1))){
        return false;
      }
    } else if (selectedChess.text == "士") {
      if(selectedChess.color==Colors.black){
        if (tempOffset.dx < 3 || tempOffset.dx > 5 || tempOffset.dy < 0 || tempOffset.dy > 2) {
          return false;
        }
        if( !(distance(selectedChess.offset.dx, tempOffset.dx )==1.0&&distance(selectedChess.offset.dy, tempOffset.dy )==1.0)){
          return false;
        }
      }else {
        if (tempOffset.dx < 3 || tempOffset.dx > 5 || tempOffset.dy < 7 || tempOffset.dy > 9) {
          return false;
        }
        if( !(distance(selectedChess.offset.dx, tempOffset.dx )==1.0&&distance(selectedChess.offset.dy, tempOffset.dy )==1.0)){
          return false;
        }
      }
    } else if (selectedChess.text == "象") {
      if (tempOffset.dx < 0 || tempOffset.dx > 8 || tempOffset.dy < 0 || tempOffset.dy > 4) {
        return false;
      }
      if(selectedChess.color==Colors.black){
        if(tempOffset.dy > 4) {
          return false;
        }
      }else{
        if(tempOffset.dy <5) {
          return false;
        }
      }
      if(!(distance(selectedChess.offset.dx,tempOffset.dx)==2.0&&distance(selectedChess.offset.dy,tempOffset.dy)==2.0)){
        print("象必须走田");
        return false;
      }
      // todo 判断是否被阻挡
      if(distance(selectedChess.offset.dx,tempOffset.dx)==2.0&&distance(selectedChess.offset.dy,tempOffset.dy)==2.0){
        if(existChess(Offset((selectedChess.offset.dx+tempOffset.dx)/2,(selectedChess.offset.dy+tempOffset.dy)/2))){
          print("象眼阻塞");
          return false;
        }
      }


    } else if (selectedChess.text == "馬") {
      if (tempOffset.dx < 0 || tempOffset.dx > 8 || tempOffset.dy < 0 || tempOffset.dy > 9) {
        return false;
      }
      if(!(distance(selectedChess.offset.dx,tempOffset.dx)==2.0&&distance(selectedChess.offset.dy,tempOffset.dy)==1.0||distance
        (selectedChess.offset.dx,tempOffset.dx)==1.0&&distance(selectedChess.offset.dy,tempOffset.dy)==2.0)){

        return false;
      }
      if(distance(selectedChess.offset.dx,tempOffset.dx)==2.0){
        if(existChess(Offset((selectedChess.offset.dx+tempOffset.dx)/2,selectedChess.offset.dy))){
          print("撇脚马");
          return false;
        }
      }
      if(distance(selectedChess.offset.dy,tempOffset.dy)==2.0){
        if(existChess(Offset(selectedChess.offset.dx,(selectedChess.offset.dy+tempOffset.dy)/2))){
          print("撇脚马");
          return false;
        }
      }
      // todo 判断是否被阻挡
    } else if (selectedChess.text == "車") {
      if (tempOffset.dx < 0 || tempOffset.dx > 8 || tempOffset.dy < 0 || tempOffset.dy > 9) {
        return false;
      }
      if(selectedChess.offset.dx != tempOffset.dx&& selectedChess.offset.dy != tempOffset.dy){
        return false;
      }
      // todo 判断是否被阻挡
      if(selectedChess.offset.dx == tempOffset.dx&&distance(selectedChess.offset.dy, tempOffset.dy)>1){

        for (int i = 1; i < distance(selectedChess.offset.dy, tempOffset.dy).toInt(); i++) {
          if(existChess(Offset(selectedChess.offset.dx,min(tempOffset.dy, selectedChess.offset.dy)+i))){
            print("猪被挡");
            return false;
          }
        }
      }

      if(selectedChess.offset.dy == tempOffset.dy&&distance(selectedChess.offset.dx, tempOffset.dx)>1){

        for (int i = 1; i < distance(selectedChess.offset.dx, tempOffset.dx).toInt(); i++) {
          if(existChess(Offset(min(tempOffset.dx, selectedChess.offset.dx)+i,selectedChess.offset.dy))){
            print("猪被挡");
            return false;
          }
        }
      }


    } else if (selectedChess.text == "炮") {
      if (tempOffset.dx < 0 || tempOffset.dx > 8 || tempOffset.dy < 0 || tempOffset.dy > 9) {
        return false;
      }
      if(selectedChess.offset.dx != tempOffset.dx&& selectedChess.offset.dy != tempOffset.dy){
        return false;
      }
      if(selectedChess.offset.dx == tempOffset.dx&&distance(selectedChess.offset.dy, tempOffset.dy)>1){
        int count = 0;
        for (int i = 1; i < distance(selectedChess.offset.dy, tempOffset.dy).toInt(); i++) {
          if(existChess(Offset(selectedChess.offset.dx,min(tempOffset.dy, selectedChess.offset.dy)+i))){
           count++;
          }
        }
        if(count!=1){
          print("炮需隔一个子");
        }
      }

      if(selectedChess.offset.dy == tempOffset.dy&&distance(selectedChess.offset.dx, tempOffset.dx)>1){

        for (int i = 1; i < distance(selectedChess.offset.dx, tempOffset.dx).toInt(); i++) {
          if(existChess(Offset(min(tempOffset.dx, selectedChess.offset.dx)+i,selectedChess.offset.dy))){
            print("炮被挡");
            return false;
          }
        }
      }

      // todo 判断是否被阻挡
    } else if (selectedChess.text == "兵") {
      if (tempOffset.dx < 0 || tempOffset.dx > 8 || tempOffset.dy < 0 || tempOffset.dy > 9) {
        return false;
      }
      if(selectedChess.color==Colors.black){
        if(tempOffset.dyselectedChess.offset.dy){
          return false;
        }
        if(tempOffset.dx!=selectedChess.offset.dx&&selectedChess.offset.dy>6){
          return false;
        }
      }
      if( !((distance(selectedChess.offset.dx, tempOffset.dx )==1.0&&distance(selectedChess.offset.dy, tempOffset.dy )==0)||(distance
        (selectedChess.offset.dx, tempOffset.dx )==0&&distance(selectedChess.offset.dy, tempOffset.dy )==1))){
        return false;
      }
    }

    return  true;
  }


double distance(double a,double b){
  double c=a-b;
  if(c<0) {
    return -c;
  }
  return c;
}
  Chess? findClickedChess(Offset offset) {
    for (Chess chess in chessList) {
      if (chess.offset.dx == offset.dx && chess.offset.dy == offset.dy) {
        return chess;
      }
    }
    return null;
  }


Offset? findClickedOffsetIndex(Offset offset) {
  for (int i = 0; i < 9; i++) {
    for (int j = 0; j < 10; j++) {
      if (80 + i * 50 <= offset.dx && 80 + i * 50 + 50 >= offset.dx && 80 + j * 50 <= offset.dy && 80 + j * 50 + 50 >= offset.dy) {
        return Offset(i * 1.0, j * 1.0);
      }
    }
  }
  return null;
}

@override
Widget build(BuildContext context) {
    chessCmpList=createPieces();
    return Row(
      children: [
        Expanded(flex: 7, child:  GestureDetector(
            onTapDown: (details) {
              // 处理点击事件
              clickEventProcess(details.localPosition);
            },
            child: CustomPaint(
              size: Size(boardSize * gridSize, (boardSize + 1) * gridSize), // 象棋棋盘是9x10
              painter: ChessBoardPainter(chessList:chessList),
              child: const Stack(
                children: [],//createPieces(), // 创建棋子并定位
              ),
            )
        )), // 棋盘占70%
        Expanded(flex: 3, child: buildControllPanel()), // 控制面板占30%
      ],
    )
  ;
}

  List createPieces() {

    // 这里只是一个示例,实际应用中需要根据棋局状态动态生成棋子
    for (Chess chess in chessList) {
      chessCmpList.add(Positioned(
          top: chess
              .getPosition()
              .dy,
          left: chess
              .getPosition()
              .dx,
          child: chess));
    }
    return chessCmpList;
  }

 Widget buildControllPanel() {
    return Center(child:Row(
      children: [
        TextButton(onPressed: (){
          setState(() {
            newGame();
          });
        }, child: const Text("重新开始")),
        TextButton(onPressed: (){}, child: const Text("悔棋"))
      ]
    ));
 }
  }

class Chess extends StatefulWidget {
  final String text;
  final Color color;
  Offset offset;
  bool selected = false;
  bool alive = true;

  void setSelected() {
    selected = !selected;
  }

  Chess({required this.text, required this.color, required this.offset});

  Offset getPosition() {
    return Offset(80.0 + offset.dx * 50, 80.0 + offset.dy * 50);
  }


  @override
  State createState() {
    return _ChessState();
  }
}

class _ChessState extends State {
  late String text;
  late Color color;
  late Offset offset;
  late bool selected = false;
  @override
  void initState() {
    super.initState();
    text=widget.text;
    color=widget.color;
    offset=widget.offset;
    selected=widget.selected;
  }
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 40, // 设置你想要的宽度
      height: 40, // 设置你想要的高度(应与宽度相同以保持圆形)
      decoration: BoxDecoration(
        color: selected ? Colors.blue : color, // 背景颜色
        shape: BoxShape.circle, // 设置为圆形
      ),
      child: Stack(children: [
        const SizedBox(
          width: 40,
          height: 40,
        ),
        Positioned(
          top: 3,
          left: 8,
          child: Text(
            text,
            style: const TextStyle(
              color: Colors.white, // 文字颜色,从构造函数传入
              fontSize: 24.0, // 文字大小
            ),
          ),
        )
      ]),
    );
  }
}

class ChessBoardPainter extends CustomPainter {
  List chessList;
  ChessBoardPainter({required this.chessList});
  @override
  void paint(Canvas canvas, Size size) {

    // 绘制棋盘线
    final Paint linePaint = Paint()
      ..color = Colors.lightBlue
      ..strokeWidth = 1.5;
    int header = 100;

    // 绘制竖线
    for (int col = 0; col < 9; col++) {
      canvas.drawLine(Offset(header + col * 50.0, header + 0), Offset(header + col * 50.0, header + 200), linePaint);
    }

    // 绘制竖线
    for (int col = 0; col < 9; col++) {
      canvas.drawLine(Offset(header + col * 50.0, header + 250), Offset(header + col * 50.0, header + 450), linePaint);
    }
    canvas.drawLine(Offset(header + 0 * 50.0, header + 0), Offset(header + 0 * 50.0, header + 450), linePaint);
    canvas.drawLine(Offset(header + 8 * 50.0, header + 0), Offset(header + 8 * 50.0, header + 450), linePaint);

    canvas.drawLine(Offset(header + 3 * 50.0, header + 0), Offset(header + 5 * 50.0, header + 100), linePaint);
    canvas.drawLine(Offset(header + 3 * 50.0, header + 100), Offset(header + 5 * 50.0, header + 0), linePaint);

    canvas.drawLine(Offset(header + 3 * 50.0, header + 350), Offset(header + 5 * 50.0, header + 450), linePaint);
    canvas.drawLine(Offset(header + 5 * 50.0, header + 350), Offset(header + 3 * 50.0, header + 450), linePaint);

    // 绘制横线
    for (int row = 0; row < 10; row++) {
      canvas.drawLine(Offset(header + 0, header + row * 50.0), Offset(header + 400, header + row * 50.0), linePaint);
    }

    // 特殊标记(如楚河汉界)
    final TextPainter textPainter = TextPainter(textDirection: TextDirection.ltr);
    textPainter.text = const TextSpan(
      text: '楚        河                                      汉        界',
      style: TextStyle(fontSize: 18.0, color: Colors.green, fontWeight: FontWeight.bold,fontFamily:"华文行楷" ),

    );
    textPainter.layout();
    textPainter.paint(canvas, Offset(header + 50, header + 215));

    for(Chess chess in chessList){
      Paint chessPaint = Paint()
        ..color = chess.color
        ..strokeWidth = 1.0;
      canvas.drawCircle(chess.getPosition()+const Offset(20,20), 20, chessPaint);

      TextPainter textPainter2 = TextPainter(textDirection: TextDirection.ltr);
      textPainter.text =  TextSpan(
        text: chess.text,
        style: const TextStyle(fontSize: 26.0, color: Colors.white, fontWeight: FontWeight.bold,fontFamily:"华文行楷" ),

      );
      textPainter.layout();
      textPainter.paint(canvas, chess.getPosition()+const Offset(6,6));

    }

  }

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

// 定义棋盘和控制面板的widget

你可能感兴趣的:(flutter,游戏程序)