本文執行個體為大家分享了Android五子棋遊戲的具體代碼,供大家參考,具體内容如下
1、效果圖:

2、GobangPanel棋盤面闆:
public class GobangPanel extends View {
private int mPanelWidth;//棋盤的寬度
private float mLineHeight;//行,高要為float
private int MAX_LINE = 15;//棋盤行數
private int MAX_COUNT_IN_LINE = 5;//設定赢棋子個數(6子棋設定為6)
private Paint mPaint = new Paint();//畫筆
private Bitmap mWhitePiece;//白色棋子
private Bitmap mBlackPiece;//黑色棋子
private float ratioPieceOfLineHeight = 3 * 1.0f / 4;//2個棋子間3/4距離
//白旗先手,目前輪到白棋了
private boolean mIsWhite = true;
private ArrayList<Point mWhiteArray = new ArrayList< ();//白棋數組
private List<Point mBlackArray = new ArrayList< ();//黑騎數組
private boolean mIsGameOver;//遊戲是否結束
private boolean mIsWhiteWinner;//白色棋子赢 true白子赢,false黑色赢
public GobangPanel(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
/**
* 初始化畫筆參數
*/
private void init() {
mPaint.setColor(0x88000000);//Paint顔色 半透明灰色
mPaint.setAntiAlias(true);//抗鋸齒(邊界明顯變模糊)
mPaint.setDither(true);//設定防抖動(圖檔柔和)
mPaint.setStyle(Paint.Style.STROKE);//樣式
//黑、白棋資源圖檔
mWhitePiece = BitmapFactory.decodeResource(getResources(), R.mipmap.white_bg);
mBlackPiece = BitmapFactory.decodeResource(getResources(), R.mipmap.black_bg);
}
/**
* 自定義View尺寸的規則
*/
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//寬和高
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int width = Math.max(widthSize, heightSize); //最大值
if (widthMode == MeasureSpec.UNSPECIFIED) {
width = heightSize;
} else if (heightMode == MeasureSpec.UNSPECIFIED) {
width = widthSize;
}
setMeasuredDimension(width, width);
}
/**
* 控件大小發生改變時調用
*/
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mPanelWidth = w;//棋盤的寬高
mLineHeight = mPanelWidth * 1.0f / MAX_LINE;
int pieceWidth = (int) (mLineHeight * ratioPieceOfLineHeight); //比例
mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece, pieceWidth, pieceWidth, false);//棋子跟随控件變化
mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece, pieceWidth, pieceWidth, false);
}
//觸摸焦點
public boolean onTouchEvent(MotionEvent event) {
if (mIsGameOver) return false;
int action = event.getAction();
if (action == MotionEvent.ACTION_UP) {
int x = (int) event.getX();
int y = (int) event.getY();
Point p = getValidPoint(x, y);
if (mWhiteArray.contains(p) || mBlackArray.contains(p)) {
return false;
}
if (mIsWhite) {
mWhiteArray.add(p);
} else {
mBlackArray.add(p);
}
invalidate();//重繪棋子
mIsWhite = !mIsWhite;
}
return true;//感興趣交給其處理
}
private Point getValidPoint(int x, int y) {
return new Point((int) (x / mLineHeight), (int) (y / mLineHeight));
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawBoard(canvas);
drawPieces(canvas);
checkGameOver();
}
private static final String TAG = "GobangPanel";
/**
* 遊戲結束方法
*/
public void checkGameOver() {
boolean whiteWin = checkFiveInLine(mWhiteArray);
boolean blackWin = checkFiveInLine(mBlackArray);
//黑棋或白棋赢遊戲結束
if (whiteWin || blackWin) {
mIsGameOver = true;
mIsWhiteWinner = whiteWin;
if (null != listener) {
listener.onFinish(mIsWhiteWinner);
Log.e(TAG, "checkGameOver: 111111" );
}
Log.e(TAG, "checkGameOver: 222222" );
}
}
/**
* 判斷棋子是否5個相鄰【5個相連隻有4中情況分别是:水準、垂直、左斜和右斜】
*/
private boolean checkFiveInLine(List<Point points) {
for (Point p : points) {
int x = p.x;
int y = p.y;
boolean win = checkLevel(x, y, points);
if (win) return true;
win = checkVetical(x, y, points);
if (win) return true;
win = checkLeftWin(x, y, points);
if (win) return true;
win = checkRightWin(x, y, points);
if (win) return true;
}
return false;
}
/**
* 判斷x,y位置的棋子是否【水準】有相鄰的五個一緻
*/
private boolean checkLevel(int x, int y, List<Point points) {
int count = 1;
//橫向左邊棋子個數
for (int i = 1; i < MAX_COUNT_IN_LINE; i++) {
//如果有加1,沒有重新計算是否有五個,否者中斷
if (points.contains(new Point(x - i, y))) {
count++;
} else {
break;
}
}
//有5個時則赢
if (count == MAX_COUNT_IN_LINE) return true;
//橫向右邊棋子個數
for (int i = 1; i < MAX_COUNT_IN_LINE; i++) {
//如果有加1,沒有重新計算是否有五個,否者中斷
if (points.contains(new Point(x + i, y))) {
count++;
} else {
break;
}
}
//有5個時則赢
if (count == MAX_COUNT_IN_LINE) return true;
return false;
}
/**
* 判斷x,y位置的棋子是否[垂直]有相鄰的五個一緻
*/
private boolean checkVetical(int x, int y, List<Point points) {
int count = 1;
//上下棋子個數
for (int i = 1; i < MAX_COUNT_IN_LINE; i++) {
//如果有加1,沒有重新計算是否有五個,否者中斷
if (points.contains(new Point(x, y - i))) {
count++;
} else {
break;
}
}
//有5個時則赢,return true;
if (count == MAX_COUNT_IN_LINE) return true;
for (int i = 1; i < MAX_COUNT_IN_LINE; i++) {
//如果有加1,沒有重新計算是否有五個,否者中斷
if (points.contains(new Point(x, y + i))) {
count++;
} else {
break;
}
}
//有5個時則赢
if (count == MAX_COUNT_IN_LINE) return true;
return false;
}
/**
* 判斷x,y位置的棋子是否【左斜和右斜】有相鄰的五個一緻
*/
private boolean checkLeftWin(int x, int y, List<Point points) {
int count = 1;
//橫向上下棋子個數
for (int i = 1; i < MAX_COUNT_IN_LINE; i++) {
//如果有加1,沒有重新計算是否有五個,否者中斷
if (points.contains(new Point(x - i, y + i))) {
count++;
} else {
break;
}
}
//有5個時則赢,return true;
if (count == MAX_COUNT_IN_LINE) return true;
for (int i = 1; i < MAX_COUNT_IN_LINE; i++) {
//如果有加1,沒有重新計算是否有五個,否者中斷
if (points.contains(new Point(x + i, y - i))) {
count++;
} else {
break;
}
}
//有5個時則赢
if (count == MAX_COUNT_IN_LINE) return true;
return false;
}
/**
* 判斷x,y位置的棋子是否【右斜】有相鄰的五個一緻
*/
private boolean checkRightWin(int x, int y, List<Point points) {
int count = 1;
//橫向上下棋子個數
for (int i = 1; i < MAX_COUNT_IN_LINE; i++) {
//如果有加1,沒有重新計算是否有五個,否者中斷
if (points.contains(new Point(x - i, y - i))) {
count++;
} else {
break;
}
}
//有5個時則赢,return true;
if (count == MAX_COUNT_IN_LINE) return true;
for (int i = 1; i < MAX_COUNT_IN_LINE; i++) {
//如果有加1,沒有重新計算是否有五個,否者中斷
if (points.contains(new Point(x + i, y + i))) {
count++;
} else {
break;
}
}
//有5個時則赢
if (count == MAX_COUNT_IN_LINE) return true;
return false;
}
private void drawPieces(Canvas canvas) {
//白色棋子
for (int i = 0, n = mWhiteArray.size(); i < n; i++) {
Point whitePoint = mWhiteArray.get(i);
canvas.drawBitmap(mWhitePiece,
(whitePoint.x + (1 - ratioPieceOfLineHeight) / 2) * mLineHeight,
(whitePoint.y + (1 - ratioPieceOfLineHeight) / 2) * mLineHeight, null);
}
//黑色棋子
for (int i = 0, n = mBlackArray.size(); i < n; i++) {
Point blackPoint = mBlackArray.get(i);
canvas.drawBitmap(mBlackPiece,
(blackPoint.x + (1 - ratioPieceOfLineHeight) / 2) * mLineHeight,
(blackPoint.y + (1 - ratioPieceOfLineHeight) / 2) * mLineHeight, null);
}
}
/**
* 畫格子棋盤
*/
private void drawBoard(Canvas canvas) {
int w = mPanelWidth;
float lineHeight = mLineHeight;
for (int i = 0; i < MAX_LINE; i++) {
int startx = (int) (lineHeight / 2);//橫坐标起點,終點
int endX = (int) (w - lineHeight / 2);
int y = (int) ((0.5 + i) * lineHeight);
canvas.drawLine(startx, y, endX, y, mPaint);
canvas.drawLine(y, startx, y, endX, mPaint);
}
}
/**
* 再來一局
*/
public void start() {
if (null != mWhiteArray && null != mBlackArray) {
mWhiteArray.clear();//清除資料
mBlackArray.clear();
}
mIsGameOver = false;
mIsWhiteWinner = false;
invalidate(); //再次調用
}
/**
* 背景運作時,調用此方法,防止資料丢失
*/
private static final String INSTANCE = "instance";
private static final String INSTANCE_GAME_OVER = "instance_game_over"; //遊戲結束
private static final String INSTANCE_WHITE_ARRAY = "instance_white_array"; //白
private static final String INSTANCE_BLACK_ARRAY = "instance_black_array";
/**
* 儲存資料
*/
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putParcelable(INSTANCE, super.onSaveInstanceState());
bundle.putBoolean(INSTANCE_GAME_OVER, mIsGameOver);
bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY, mWhiteArray);
bundle.putParcelableArrayList(INSTANCE_BLACK_ARRAY, mWhiteArray);
return bundle;
}
/**
* 恢複時調用
*/
protected void onRestoreInstanceState(Parcelable state) {
if (state instanceof Bundle) {
Bundle bundle = (Bundle) state;
mIsGameOver = bundle.getBoolean(INSTANCE_GAME_OVER);
mWhiteArray = bundle.getParcelableArrayList(INSTANCE_WHITE_ARRAY);
mBlackArray = bundle.getParcelableArrayList(INSTANCE_BLACK_ARRAY);
super.onRestoreInstanceState(bundle.getParcelable(INSTANCE));
return;
}
super.onRestoreInstanceState(state);
}
/**
* 遊戲結束回調
*/
public OnFinishListener listener;
public void setListener(OnFinishListener listener) {
this.listener = listener;
}
public interface OnFinishListener {
void onFinish(boolean mIsWhiteWinner);
}
}
複制
3、使用MainActivity
public class MainActivity extends AppCompatActivity {
private GobangPanel panel;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
panel = this.findViewById(R.id.gobang_panel);
panel.setListener(new GobangPanel.OnFinishListener() {
@Override
public void onFinish(boolean mIsWhiteWinner) {
initDialog(mIsWhiteWinner);
}
});
}
/**
* 初始化彈框
*/
private void initDialog(boolean mIsWhiteWinner) {
AlertDialog dialog = new AlertDialog.Builder(this)
//.setTitle("這是标題")
.setMessage(mIsWhiteWinner ? "白棋勝利,是否重新開始?" : "黑棋勝利,是否重新開始?")
//.setIcon(R.mipmap.ic_launcher)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {//添加"Yes"按鈕
@Override
public void onClick(DialogInterface dialogInterface, int i) {
panel.start();
}
})
// .setNegativeButton("取消", new DialogInterface.OnClickListener() {//添加取消
// @Override
// public void onClick(DialogInterface dialogInterface, int i) {
// Toast.makeText(MainActivity.this, "這是取消按鈕", Toast.LENGTH_SHORT).show();
// }
// })
//方法一:setCanceledOnTouchOutside(false);按對話框以外的地方不起作用。按傳回鍵起作用
//方法二:setCanceleable(false);按對話框以外的地方不起作用。按傳回鍵也不起作用
.setCancelable(false)
.create();
dialog.show();
}
}
複制
對應布局檔案:activity_main:
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fff"
tools:context=".MainActivity"
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
<com.helloworld.game.GobangPanel
android:id="@+id/gobang_panel"
android:layout_width="1000dp"
android:layout_height="1000dp"
android:layout_centerInParent="true" /
</ScrollView
</HorizontalScrollView
複制
以上就是本文的全部内容,希望對大家的學習有所幫助。