直接上效果图
原理
从棋盘到棋子,到开始下棋的各类点击事件,均在 ChessView 中实现,这个 View 没有提供自定义属性(因为我觉得没有必要~~~)。
项目GitHub地址:https://github.com/hunlianyun/Wuziqi
实现步骤
- 新建一个棋子类,这个类非常简单,代码如下:
public class Chess {
public enum Color {BLACK, WHITE, NONE}
private Color color;
public Chess(){
this.color = Color.NONE;
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
}
每个棋子类有三种状态,即 WHITE,BLACK,NONE。这里我们使用枚举来表示这三种状态。
2. 自定义 ChessView 类,这个类就是核心类了,我们这个五子棋的所有逻辑都是在这个类里面实现。构造方法初始化各个字段,代码如下:
public ChessView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// 初始化字段 mEveryPlay,悔棋会用到
initEveryPlay();
// 初始化每个棋子,设置属性为 NONE
initChess();
// 初始化棋盘画笔
initBoardPaint();
// 初始化棋子画笔
initChessPaint();
// 初始化背景画笔
initBgPaint();
}
各个方法的具体实现如下:
private void initEveryPlay() {
// 初始化 List 大小,此方法不影响 list.size() 返回值
mEveryPlay = new ArrayList<>(225);
}
private void initChess() {
mChessArray = new Chess[15][15];
for (int i = 0; i < mChessArray.length; i++) {
for (int j = 0; j < mChessArray[i].length; j++) {
mChessArray[i][j] = new Chess();
}
}
}
private void initChessPaint() {
mChessPaint = new Paint();
mChessPaint.setColor(android.graphics.Color.WHITE);
mChessPaint.setAntiAlias(true);
}
private void initBoardPaint() {
mBoardPaint = new Paint();
mBoardPaint.setColor(android.graphics.Color.BLACK);
mBoardPaint.setStrokeWidth(2);
}
private void initBgPaint() {
mBgPaint = new Paint();
mBgPaint.setColor(android.graphics.Color.GRAY);
mBgPaint.setAntiAlias(true);
}
3. 重写 onMeasure() 方法,强制将 View 大小变为正方形,代码如下:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int min = widthSize < heightSize ? widthSize : heightSize;
// 五子棋标准棋盘线条数目为 15 x 15,为了后面计算坐标方便,我们将 View 的宽高处理为 16 的整数倍
min = min / 16 * 16;
setMeasuredDimension(min, min);
}
之所以设置为 16 的整数倍而不是 15,是因为如果设置成 15,那么棋盘的背景就会跟棋盘最边界的线条重合,此时如果有棋子落在边界,棋子将不能显示完全。
4. 重点来了,重写 onDraw() 方法,绘制出棋盘,代码如下:
@Override
protected void onDraw(Canvas canvas) {
int height = getMeasuredHeight();
int width = getMeasuredWidth();
int avg = height / 16;
canvas.drawRect(