Android開(kāi)發(fā)實(shí)現(xiàn)的簡(jiǎn)單五子棋游戲示例
本文實(shí)例講述了Android開(kāi)發(fā)實(shí)現(xiàn)的簡(jiǎn)單五子棋游戲。分享給大家供大家參考,具體如下:
我剛剛在Android上寫(xiě)的一個(gè)五子棋的小程序,在這里跟大家分享一下。
寫(xiě)完以后感覺(jué)Android的SDK,雖然也是使用Java的,但是跟Java ME還是有很大不一樣。
首先就是Android的SDK沒(méi)有實(shí)現(xiàn)所有的Java ME標(biāo)準(zhǔn),原來(lái)運(yùn)行在KJava上的應(yīng)用程序是不能在Android上直接跑的。
另外就是Android的SDK有大量的API是Android自己的,需要開(kāi)發(fā)人員去了解。
Android的開(kāi)發(fā)框架也跟別的不一樣,需要學(xué)習(xí)一下。
這個(gè)五子棋游戲是我參照Android 的Snake這個(gè)Demo還有別的例子,加上自己的需求寫(xiě)出來(lái)的。
其中實(shí)現(xiàn)了棋盤(pán)、下棋、判斷輸贏、重新開(kāi)局等功能。目前暫時(shí)沒(méi)有實(shí)現(xiàn)機(jī)器智能走棋子的功能。
Android的觸屏功能是比較好用的,前一段時(shí)間見(jiàn)人演示的G1,觸屏很好用,而且Android的“Window” 窗、"Shade"簾加上觸摸,顯得很炫。
呃,這個(gè)五子棋,也是用觸摸屏實(shí)現(xiàn)走棋的。點(diǎn)一下棋盤(pán)的位子,把棋子落到棋盤(pá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; /*棋盤(pán)一共10×10格 * 棋盤(pán)居中 * * * */ //public class GobangView extends View implements Runnable { public class GobangView extends View{ protected static int GRID_SIZE = 10; protected static int GRID_WIDTH = 30; // 棋盤(pán)格的寬度 protected static int CHESS_DIAMETER = 26; // 棋的直徑 protected static int mStartX;// 棋盤(pán)定位的左上角X protected static int mStartY;// 棋盤(pán)定位的左上角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(); } //這里畫(huà)棋子后來(lái)沒(méi)有用圖片畫(huà),而是直接畫(huà)了圓。因?yàn)槲易龅膱D片不好看。 // 初始化黑白棋的Bitmap public void init() { mGameState = 1; //設(shè)置游戲?yàn)殚_(kāi)始狀態(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()){//如果棋盤(pán)滿了 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()){//如果棋盤(pán)滿了 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); // 畫(huà)棋盤(pán) { 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); } } //畫(huà)棋盤(pán)的外邊框 paintRect.setStrokeWidth(4); canvas.drawRect(mStartX, mStartY, mStartX + GRID_WIDTH*GRID_SIZE, mStartY + GRID_WIDTH*GRID_SIZE, paintRect); } //畫(huà)棋子 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)畫(huà) //canvas.drawBitmap(mChessBW[0], mStartX + (i+1) * GRID_WIDTH - CHESS_DIAMETER/2 , mStartY + (j+1)* GRID_WIDTH - CHESS_DIAMETER/2 , mPaint); //通過(guò)圓形來(lái)畫(huà) { 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)畫(huà) //canvas.drawBitmap(mChessBW[1], mStartX + (i+1) * GRID_WIDTH - CHESS_DIAMETER/2 , mStartY + (j+1)* GRID_WIDTH - CHESS_DIAMETER/2 , mPaint); //通過(guò)圓形來(lái)畫(huà) { 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開(kāi)發(fā)入門(mén)與進(jìn)階教程》、《Android調(diào)試技巧與常見(jiàn)問(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)畫(huà)效果的實(shí)現(xiàn)
- 基于android實(shí)現(xiàn)五子棋開(kāi)發(fā)
- Android自定義View實(shí)現(xiàn)五子棋游戲
- Android自定義View實(shí)現(xiàn)五子棋小游戲
- android簡(jiǎn)單自定義View實(shí)現(xiàn)五子棋
- Android自定義View實(shí)現(xiàn)五子棋游戲
- Android游戲開(kāi)發(fā)之黑白棋
- Android實(shí)現(xiàn)中國(guó)象棋游戲(局域網(wǎng)版)
相關(guān)文章
Android ViewPagerIndicator詳解及實(shí)例代碼
這篇文章主要介紹了Android ViewPagerIndicator詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-05-05Android使用Flutter實(shí)現(xiàn)錄音插件
這篇文章主要介紹了基于flutter實(shí)現(xiàn)錄音功能,介紹了如何錄音,如何把文件存放到本地,這些都是我們平常使用這個(gè)功能會(huì)遇到的問(wèn)題。在使用的過(guò)程中遇到的問(wèn)題也有列出,需要的朋友可以參考下2022-08-08Android獲取手機(jī)屏幕寬高、狀態(tài)欄高度以及字符串寬高信息的方法
這篇文章主要介紹了Android獲取手機(jī)屏幕寬高、狀態(tài)欄高度以及字符串寬高信息的方法,涉及Android獲取文字寬高、狀態(tài)欄高度、textView寬度及屏幕尺寸的相關(guān)技巧,需要的朋友可以參考下2015-04-04Android Studio3.0升級(jí)后使用注意事項(xiàng)及解決方法
這篇文章主要介紹了Android Studio3.0升級(jí)后使用注意事項(xiàng)及解決方法,需要的朋友參考下吧2017-12-12Android實(shí)現(xiàn)列表元素動(dòng)態(tài)效果
本文將利用AnimatedList組件實(shí)現(xiàn)列表元素的一些動(dòng)態(tài)效果,例如添加元素時(shí)的漸現(xiàn)效果,刪除元素逐漸消失的效果等,感興趣的小伙伴可以了解一下2022-03-03Android 中使用 ViewPager實(shí)現(xiàn)屏幕頁(yè)面切換和頁(yè)面輪播效果
ViewPager是谷歌官方給我們提供的一個(gè)兼容低版本安卓設(shè)備的軟件包,里面包囊了只有在安卓3.0以上可以使用的api。下面我們就展示下ViewPager可以實(shí)現(xiàn)的兩種簡(jiǎn)單效果,感興趣的朋友一起看看吧2016-12-12Android binder 匿名服務(wù)實(shí)現(xiàn)雙向通信的解決方案
這篇文章主要介紹了Android binder 匿名服務(wù)實(shí)現(xiàn)雙向通信的解決方案,當(dāng)然,這種方案是可行的,只是需要client和server都向servicemanager注冊(cè)一個(gè)服務(wù),實(shí)現(xiàn)起來(lái)有點(diǎn)麻煩,不太建議這么做,需要的朋友可以參考下2024-04-04Android App中使用ViewPager實(shí)現(xiàn)滑動(dòng)分頁(yè)的要點(diǎn)解析
這篇文章主要介紹了Android App中使用ViewPager實(shí)現(xiàn)滑動(dòng)分頁(yè)的要點(diǎn)解析,還附帶了一個(gè)禁止ViewPager左右滑動(dòng)的方法,需要的朋友可以參考下2016-06-06