Android開發(fā)實(shí)現(xiàn)的簡(jiǎn)單五子棋游戲示例
本文實(shí)例講述了Android開發(fā)實(shí)現(xiàn)的簡(jiǎn)單五子棋游戲。分享給大家供大家參考,具體如下:
我剛剛在Android上寫的一個(gè)五子棋的小程序,在這里跟大家分享一下。
寫完以后感覺Android的SDK,雖然也是使用Java的,但是跟Java ME還是有很大不一樣。
首先就是Android的SDK沒有實(shí)現(xiàn)所有的Java ME標(biāo)準(zhǔn),原來(lái)運(yùn)行在KJava上的應(yīng)用程序是不能在Android上直接跑的。
另外就是Android的SDK有大量的API是Android自己的,需要開發(fā)人員去了解。
Android的開發(fā)框架也跟別的不一樣,需要學(xué)習(xí)一下。
這個(gè)五子棋游戲是我參照Android 的Snake這個(gè)Demo還有別的例子,加上自己的需求寫出來(lái)的。
其中實(shí)現(xiàn)了棋盤、下棋、判斷輸贏、重新開局等功能。目前暫時(shí)沒有實(shí)現(xiàn)機(jī)器智能走棋子的功能。
Android的觸屏功能是比較好用的,前一段時(shí)間見人演示的G1,觸屏很好用,而且Android的“Window” 窗、"Shade"簾加上觸摸,顯得很炫。
呃,這個(gè)五子棋,也是用觸摸屏實(shí)現(xiàn)走棋的。點(diǎn)一下棋盤的位子,把棋子落到棋盤上。
先貼個(gè)圖看看效果吧。

好了,下面直接貼代碼:
/*
* Five In a Row. (五子棋)
* 這是一個(gè)簡(jiǎn)單的五子棋程序,是我自己的一個(gè)練習(xí),貼出來(lái)跟大家分享。
* 希望跟大家一起多交流。 我的GoogleTalk: lixinso <at> gmail.com
*
*
*/
//----------------------
//TBD:AI,悔棋
//---------------------
package lixinsong.game.gobang;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
//這是主程序,繼承自Activity,實(shí)現(xiàn)onCreate方法。:
public class gobang extends Activity {
GobangView gbv;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gbv = (GobangView)this.findViewById(R.id.gobangview);
gbv.setTextView((TextView)this.findViewById(R.id.text));
}
里面的R.id.gobangview是在res中定義的View。
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <lixinsong.game.gobang.GobangView android:id="@+id/gobangview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="aaaaa" tileSize="24" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" > <TextView android:id="@+id/text" android:text="hahahhaha" android:visibility="visible" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:gravity="center_horizontal" android:textColor="#ffff0000" android:textStyle="bold" android:textSize="24sp" /> </RelativeLayout> </FrameLayout>
五子棋的View
package lixinsong.game.gobang;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
/*棋盤一共10×10格
* 棋盤居中
*
*
*
*/
//public class GobangView extends View implements Runnable {
public class GobangView extends View{
protected static int GRID_SIZE = 10;
protected static int GRID_WIDTH = 30; // 棋盤格的寬度
protected static int CHESS_DIAMETER = 26; // 棋的直徑
protected static int mStartX;// 棋盤定位的左上角X
protected static int mStartY;// 棋盤定位的左上角Y
private Bitmap[] mChessBW; // 黑棋和白棋
private static int[][] mGridArray; // 網(wǎng)格
boolean key = false;
int wbflag = 1; //該下白棋了=2,該下黑棋了=1. 這里先下黑棋(黑棋以后設(shè)置為機(jī)器自動(dòng)下的棋子)
int mLevel = 1; //游戲難度
int mWinFlag = 0;
private final int BLACK=1;
private final int WHITE=2;
int mGameState = GAMESTATE_RUN; //游戲階段:0=尚未游戲,1=正在進(jìn)行游戲,2=游戲結(jié)束
static final int GAMESTATE_PRE = 0;
static final int GAMESTATE_RUN = 1;
static final int GAMESTATE_PAUSE = 2;
static final int GAMESTATE_END = 3;
//private TextView mStatusTextView; // 根據(jù)游戲狀態(tài)設(shè)置顯示的文字
public TextView mStatusTextView; // 根據(jù)游戲狀態(tài)設(shè)置顯示的文字
private Bitmap btm1;
private final Paint mPaint = new Paint();
CharSequence mText;
CharSequence STRING_WIN = "White win! /n Press Fire Key to start new game.";
CharSequence STRING_LOSE = "Black win! /n Press Fire Key to start new game.";
CharSequence STRING_EQUAL = "Cool! You are equal! /n Press Fire Key to start new Game.";
public GobangView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public GobangView(Context context, AttributeSet attrs) { //好像調(diào)用的是這個(gè)構(gòu)造函數(shù),為什么不是前面的呢
super(context, attrs);
this.setFocusable(true); //20090530
this.setFocusableInTouchMode(true);
init();
}
//這里畫棋子后來(lái)沒有用圖片畫,而是直接畫了圓。因?yàn)槲易龅膱D片不好看。
// 初始化黑白棋的Bitmap
public void init() {
mGameState = 1; //設(shè)置游戲?yàn)殚_始狀態(tài)
wbflag = BLACK; //初始為先下黑棋
mWinFlag = 0; //清空輸贏標(biāo)志。
mGridArray = new int[GRID_SIZE-1][GRID_SIZE-1];
mChessBW = new Bitmap[2];
Bitmap bitmap = Bitmap.createBitmap(CHESS_DIAMETER, CHESS_DIAMETER, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Resources r = this.getContext().getResources();
Drawable tile = r.getDrawable(R.drawable.chess1);
tile.setBounds(0, 0, CHESS_DIAMETER, CHESS_DIAMETER);
tile.draw(canvas);
mChessBW[0] = bitmap;
tile = r.getDrawable(R.drawable.chess2);
tile.setBounds(0, 0, CHESS_DIAMETER, CHESS_DIAMETER);
tile.draw(canvas);
mChessBW[1] = bitmap;
}
public void setTextView(TextView tv){
mStatusTextView =tv;
mStatusTextView.setVisibility(View.INVISIBLE);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
mStartX = w / 2 - GRID_SIZE * GRID_WIDTH / 2;
mStartY = h / 2 - GRID_SIZE * GRID_WIDTH / 2;
}
@Override
public boolean onTouchEvent(MotionEvent event){
switch (mGameState) {
case GAMESTATE_PRE:
break;
case GAMESTATE_RUN: {
int x;
int y;
float x0 = GRID_WIDTH - (event.getX() - mStartX) % GRID_WIDTH;
float y0 = GRID_WIDTH - (event.getY() - mStartY) % GRID_WIDTH;
if (x0 < GRID_WIDTH / 2) {
x = (int) ((event.getX() - mStartX) / GRID_WIDTH);
} else {
x = (int) ((event.getX() - mStartX) / GRID_WIDTH) - 1;
}
if (y0 < GRID_WIDTH / 2) {
y = (int) ((event.getY() - mStartY) / GRID_WIDTH);
} else {
y = (int) ((event.getY() - mStartY) / GRID_WIDTH) - 1;
}
if ((x >= 0 && x < GRID_SIZE - 1)
&& (y >= 0 && y < GRID_SIZE - 1)) {
if (mGridArray[x][y] == 0) {
if (wbflag == BLACK) {
putChess(x, y, BLACK);
//this.mGridArray[x][y] = 1;
if(checkWin(BLACK)){ //如果是黑棋贏了
mText = STRING_LOSE;
mGameState = GAMESTATE_END;
showTextView(mText);
}else if(checkFull()){//如果棋盤滿了
mText = STRING_EQUAL;
mGameState = GAMESTATE_END;
showTextView(mText);
}
wbflag = WHITE;
} else if (wbflag == WHITE) {
putChess(x, y, WHITE);
//this.mGridArray[x][y] = 2;
if(checkWin(WHITE)){
mText = STRING_WIN;
mGameState = GAMESTATE_END;
showTextView(mText);
}else if(checkFull()){//如果棋盤滿了
mText = STRING_EQUAL;
mGameState = GAMESTATE_END;
showTextView(mText);
}
wbflag = BLACK;
}
}
}
}
break;
case GAMESTATE_PAUSE:
break;
case GAMESTATE_END:
break;
}
this.invalidate();
return true;
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent msg) {
Log.e("KeyEvent.KEYCODE_DPAD_CENTER", " " + keyCode);
if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER){
switch(mGameState){
case GAMESTATE_PRE:
break;
case GAMESTATE_RUN:
break;
case GAMESTATE_PAUSE:
break;
case GAMESTATE_END:
{//游戲結(jié)束后,按CENTER鍵繼續(xù)
Log.e("Fire Key Pressed:::", "FIRE");
mGameState = GAMESTATE_RUN;
this.setVisibility(View.VISIBLE);
this.mStatusTextView.setVisibility(View.INVISIBLE);
this.init();
this.invalidate();
}
break;
}
}
return super.onKeyDown(keyCode, msg);
}
@Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.YELLOW);
// 畫棋盤
{
Paint paintRect = new Paint();
paintRect.setColor(Color.GRAY);
paintRect.setStrokeWidth(2);
paintRect.setStyle(Style.STROKE);
for (int i = 0; i < GRID_SIZE; i++) {
for (int j = 0; j < GRID_SIZE; j++) {
int mLeft = i * GRID_WIDTH + mStartX;
int mTop = j * GRID_WIDTH + mStartY;
int mRright = mLeft + GRID_WIDTH;
int mBottom = mTop + GRID_WIDTH;
canvas.drawRect(mLeft, mTop, mRright, mBottom, paintRect);
}
}
//畫棋盤的外邊框
paintRect.setStrokeWidth(4);
canvas.drawRect(mStartX, mStartY, mStartX + GRID_WIDTH*GRID_SIZE, mStartY + GRID_WIDTH*GRID_SIZE, paintRect);
}
//畫棋子
for (int i = 0; i < GRID_SIZE-1; i++) {
for (int j = 0; j < GRID_SIZE-1; j++) {
if(mGridArray[i][j] == BLACK){
//通過(guò)圖片來(lái)畫
//canvas.drawBitmap(mChessBW[0], mStartX + (i+1) * GRID_WIDTH - CHESS_DIAMETER/2 , mStartY + (j+1)* GRID_WIDTH - CHESS_DIAMETER/2 , mPaint);
//通過(guò)圓形來(lái)畫
{
Paint paintCircle = new Paint();
paintCircle.setColor(Color.BLACK);
canvas.drawCircle(mStartX + (i+1) * GRID_WIDTH, mStartY + (j+1)* GRID_WIDTH, CHESS_DIAMETER/2, paintCircle);
}
}else if(mGridArray[i][j] == WHITE){
//通過(guò)圖片來(lái)畫
//canvas.drawBitmap(mChessBW[1], mStartX + (i+1) * GRID_WIDTH - CHESS_DIAMETER/2 , mStartY + (j+1)* GRID_WIDTH - CHESS_DIAMETER/2 , mPaint);
//通過(guò)圓形來(lái)畫
{
Paint paintCircle = new Paint();
paintCircle.setColor(Color.WHITE);
canvas.drawCircle(mStartX + (i+1) * GRID_WIDTH, mStartY + (j+1)* GRID_WIDTH, CHESS_DIAMETER/2, paintCircle);
}
}
}
}
}
public void putChess(int x, int y, int blackwhite){
mGridArray[x][y] = blackwhite;
}
public boolean checkWin(int wbflag){
for(int i = 0; i < GRID_SIZE - 1 ; i++ ) //i表示列(根據(jù)寬度算出來(lái)的)
for(int j = 0; j < GRID_SIZE - 1; j++){//i表示行(根據(jù)高度算出來(lái)的)
//檢測(cè)橫軸五個(gè)相連
if(((i+4) < (GRID_SIZE - 1))&&
(mGridArray[i][j] == wbflag) && (mGridArray[i+1][j] == wbflag)&& (mGridArray[i + 2][j] == wbflag) && (mGridArray[i + 3][j] == wbflag) && (mGridArray[i + 4][j] == wbflag)){
Log.e("check win or loss:", wbflag + "win");
mWinFlag = wbflag;
}
//縱軸5個(gè)相連
if(((j+4) < (GRID_SIZE - 1))&&
(mGridArray[i][j] == wbflag) && (mGridArray[i][j+1] == wbflag)&& (mGridArray[i ][j+ 2] == wbflag) && (mGridArray[i ][j+ 3] == wbflag) && (mGridArray[i ][j+ 4] == wbflag)){
Log.e("check win or loss:", wbflag + "win");
mWinFlag = wbflag;
}
//左上到右下5個(gè)相連
if(((j+4) < (GRID_SIZE - 1))&& ((i+4) < (GRID_SIZE - 1)) &&
(mGridArray[i][j] == wbflag) && (mGridArray[i+1][j+1] == wbflag)&& (mGridArray[i + 2 ][j+ 2] == wbflag) && (mGridArray[i + 3][j+ 3] == wbflag) && (mGridArray[i + 4 ][j+ 4] == wbflag)){
Log.e("check win or loss:", wbflag + "win");
mWinFlag = wbflag;
}
//右上到左下5個(gè)相連
if(((i-4) >= 0)&& ((j+4) < (GRID_SIZE - 1)) &&
(mGridArray[i][j] == wbflag) && (mGridArray[i-1][j+1] == wbflag)&& (mGridArray[i - 2 ][j+ 2] == wbflag) && (mGridArray[i - 3][j+ 3] == wbflag) && (mGridArray[i - 4 ][j+ 4] == wbflag)){
Log.e("check win or loss:", wbflag + "win");
mWinFlag = wbflag;
}
}
if( mWinFlag == wbflag){
return true;
}else
return false;
}
public boolean checkFull(){
int mNotEmpty = 0;
for(int i = 0; i < GRID_SIZE -1; i ++)
for(int j = 0; j < GRID_SIZE - 1; j ++){
if(mGridArray[i][j] != 0) mNotEmpty +=1;
}
if(mNotEmpty == (GRID_SIZE-1)*(GRID_SIZE-1)) return true;
else return false;
}
public void showTextView(CharSequence mT){
this.mStatusTextView.setText(mT);
mStatusTextView.setVisibility(View.VISIBLE);
}
}
PS:這里再為大家推薦另一款本站的js版五子棋游戲供大家參考(其AI相對(duì)簡(jiǎn)單一些)
在線五子棋游戲:
http://tools.jb51.net/games/wuziqi
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問(wèn)題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
- Android實(shí)現(xiàn)五子棋游戲(局域網(wǎng)版)
- android自定義View實(shí)現(xiàn)簡(jiǎn)單五子棋游戲
- Android自定義view之圍棋動(dòng)畫效果的實(shí)現(xiàn)
- 基于android實(shí)現(xiàn)五子棋開發(fā)
- Android自定義View實(shí)現(xiàn)五子棋游戲
- Android自定義View實(shí)現(xiàn)五子棋小游戲
- android簡(jiǎn)單自定義View實(shí)現(xiàn)五子棋
- Android自定義View實(shí)現(xiàn)五子棋游戲
- Android游戲開發(fā)之黑白棋
- Android實(shí)現(xiàn)中國(guó)象棋游戲(局域網(wǎng)版)
相關(guān)文章
android從系統(tǒng)圖庫(kù)中取圖片的實(shí)例代碼
這篇文章主要介紹了android從系統(tǒng)圖庫(kù)中取圖片的方法,涉及Android讀取及選擇圖片等相關(guān)操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07
基于android studio的layout的xml文件的創(chuàng)建方式
這篇文章主要介紹了基于android studio的layout的xml文件的創(chuàng)建方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-03-03
Android自定義控件實(shí)現(xiàn)UC瀏覽器語(yǔ)音搜索效果
這篇文章主要為大家詳細(xì)介紹了Android自定義控件實(shí)現(xiàn)UC瀏覽器語(yǔ)音搜索效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
Android畫圖之抗鋸齒paint和Canvas兩種方式實(shí)例
本篇文章主要介紹了Android畫圖之抗鋸齒paint和Canvas兩種方式實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
Android實(shí)現(xiàn)自定義圓角對(duì)話框Dialog的示例代碼
項(xiàng)目中多處用到對(duì)話框,本篇文章主要介紹了Android實(shí)現(xiàn)圓角對(duì)話框Dialog的示例代碼,有興趣的可以了解一下。2017-03-03
android12?SD如何動(dòng)態(tài)申請(qǐng)讀寫權(quán)限
這篇文章主要給大家介紹了關(guān)于android12?SD如何動(dòng)態(tài)申請(qǐng)讀寫權(quán)限的相關(guān)資料,從Android?6.0開始,權(quán)限不再是在manifest?件中粘貼?下即可,這時(shí)候權(quán)限也正式?進(jìn)?家的視野,需要的朋友可以參考下2023-07-07
Android 基于RecyclerView實(shí)現(xiàn)的歌詞滾動(dòng)自定義控件
這篇文章主要介紹了Android 基于RecyclerView實(shí)現(xiàn)的歌詞滾動(dòng)自定義控件,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03

