前言:
最近在园子里看见别人写的一篇文章,做的一个小游戏,但是只能在一个方向实现五颗棋子连珠,带着强烈的兴趣,自己实现了一下,所有方向都没有问题了
概述:
- 环境:Android Studio 3.42
- 语言:Java
- 特点:简单,易懂,效果爆炸
展示:
原理:首先创建一个自定义五子棋的视图
ChessBoardView
,在onDraw()
方法里绘制棋盘的网格线以及棋子,并判断游戏是否结束,然后在点击事件不断重绘,最后在xml文件里引用
- 五子棋视图
创建视图
public class ChessBoardView extends View {
绘制网格线
//画网格线
private void drawBoardLine(Canvas canvas){
for (int i=0;i<Constants.MAX_LINE;i++){
int startX = (int)(mLineWidth / 2);
int endX = (int)(mWidth - mLineWidth / 2);
int y = (int)((0.5+i)*mLineWidth);
canvas.drawLine(startX,y,endX,y,paint);
canvas.drawLine(y,startX,y,endX,paint);
}
}
绘制棋子
//绘制棋子
private void drawChess(Canvas canvas){
for (int i =0,n=mWhiteChess.size();i<n;i++){
Point whitePoint = mWhiteChess.get(i);
float left = (whitePoint.x+(1-rate)/2)*mLineWidth;
float top = (whitePoint.y+(1-rate)/2)*mLineWidth;
canvas.drawBitmap(mWhiteBitmap,left,top,null);
}
for (int i =0,n=mBlackChess.size();i<n;i++){
Point blackPoint = mBlackChess.get(i);
float left = (blackPoint.x+(1-rate)/2)*mLineWidth;
float top = (blackPoint.y+(1-rate)/2)*mLineWidth;
canvas.drawBitmap(mBlackBitmap,left,top,null);
}
}
判断游戏是否结束
//检查游戏是否结束
private void checkGameOver(){
CheckWinner checkWinner = new CheckWinner();
boolean whiteWin = checkWinner.checkFiveInLineWinner(mWhiteChess);
boolean blackWin = checkWinner.checkFiveInLineWinner(mBlackChess);
if (whiteWin || blackWin){
mIsGameOver = true;
mIsWhiteWinner = whiteWin;
String text = mIsWhiteWinner ? "白棋胜利" : "黑棋胜利";
Toast.makeText(getContext(),text,Toast.LENGTH_SHORT).show();
}
}
这里判断游戏是否结束类似于五子棋的大脑,所以我们另外写一个类,专门用来判断五子棋的输赢,下面我会提到
在onDraw()
方法调用
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制棋盘的网格线
drawBoardLine(canvas);
//绘制棋子
drawChess(canvas);
checkGameOver();
}
- xml文件引用
<me.jrl.demo4.ChessBoardView
android:id="@+id/boardView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"/>
- 五子棋的大脑
CheckWinner
创建CheckWinner
public class CheckWinner {
判断当前棋子各个方向棋子的数量,达到五个则返回true
private boolean check(int x, int y, List<Point> points, int checkOri) {
int count = 1;
for (int i = 1; i < Constants.MAX_COUNT_IN_LINE; i++) {
switch (checkOri) {
case Constants.HORIZONTAL:
point1 = new Point(x - i, y);
break;
case Constants.VERTICAL:
point1 = new Point(x, y - i);
break;
case Constants.LEFT_DIAGONAL:
point1 = new Point(x - i, y + i);
break;
case Constants.RIGHT_DIAGONAL:
point1 = new Point(x - i, y - i);
break;
default:
break;
}
if (points.contains(point1)) {
count++;
} else {
break;
}
}
for (int i = 1; i < Constants.MAX_COUNT_IN_LINE; i++) {
switch (checkOri) {
case Constants.HORIZONTAL:
point2 = new Point(x + i, y);
break;
case Constants.VERTICAL:
point2 = new Point(x, y + i);
break;
case Constants.LEFT_DIAGONAL:
point2 = new Point(x + i, y - i);
break;
case Constants.RIGHT_DIAGONAL:
point2 = new Point(x + i, y + i);
break;
}
if (points.contains(point2)) {
count++;
} else {
break;
}
}
if (count == Constants.MAX_COUNT_IN_LINE) {
return true;
}
return false;
}
最后将黑白棋盘里的棋子都用来遍历是否在一个方向有五颗棋子
private Point point1, point2;
private int checkModel = Constants.HORIZONTAL;
public boolean checkFiveInLineWinner(List<Point> points) {
for (Point point : points) {
int x = point.x;
int y = point.y;
if (check(x, y, points, checkModel)) {
return true;
} else if (check(x, y, points, Constants.VERTICAL)) {
return true;
} else if (check(x, y, points, Constants.LEFT_DIAGONAL)) {
return true;
} else if (check(x, y, points, Constants.RIGHT_DIAGONAL)) {
return true;
} else {
return false;
}
}
return false;
}
总结
通过这个小项目,我们可以进一步了解Android的绘画机制,以及MVC模型,感谢大家的阅读,附上源码
[提取码:rnmk](链接: https://pan.baidu.com/s/13vlRZkXOBPWdliDHAeQQZw)