效果展示
实现方法
这里我们使用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),
),
),
),
);
}