前言:
最近在園子里看見別人寫的一篇文章赫段,做的一個小游戲,但是只能在一個方向?qū)崿F(xiàn)五顆棋子連珠奠旺,帶著強(qiáng)烈的興趣宦棺,自己實(shí)現(xiàn)了一下,所有方向都沒有問題了
概述:
- 環(huán)境:Android Studio 3.42
- 語言:Java
- 特點(diǎn):簡單箕戳,易懂某残,效果爆炸
展示:
image.png
image.png
原理:首先創(chuàng)建一個自定義五子棋的視圖
ChessBoardView
,在onDraw()
方法里繪制棋盤的網(wǎng)格線以及棋子陵吸,并判斷游戲是否結(jié)束玻墅,然后在點(diǎn)擊事件不斷重繪,最后在xml文件里引用
- 五子棋視圖
創(chuàng)建視圖
public class ChessBoardView extends View {
繪制網(wǎng)格線
//畫網(wǎng)格線
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);
}
}
判斷游戲是否結(jié)束
//檢查游戲是否結(jié)束
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();
}
}
這里判斷游戲是否結(jié)束類似于五子棋的大腦壮虫,所以我們另外寫一個類澳厢,專門用來判斷五子棋的輸贏,下面我會提到
在onDraw()
方法調(diào)用
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//繪制棋盤的網(wǎng)格線
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
創(chuàng)建CheckWinner
public class CheckWinner {
判斷當(dāng)前棋子各個方向棋子的數(shù)量,達(dá)到五個則返回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;
}
總結(jié)
通過這個小項(xiàng)目囚似,我們可以進(jìn)一步了解Android的繪畫機(jī)制剩拢,以及MVC模型,感謝大家的閱讀饶唤,附上源碼
[提取碼:rnmk](鏈接: https://pan.baidu.com/s/13vlRZkXOBPWdliDHAeQQZw)