本文主要跟大家分享一下我在Android上写的一个五子棋的小程序。首先说说我对Android的感觉,Android SDK虽然也使用Java,但跟Java ME有很多不同,Android SDK没有实现所有的Java ME标准,原来运行在KJava上的应用程序是不能在Android上直接运行的,另外就是Android SDK有大量自己的API,需要Android开发人员去学习。

       Android五子棋游戏简介

       这个五子棋游戏是我参照Android的Snake这个Demo还有别的例子,加上自己的需求写出来的。其中实现了棋盘、下棋、判断输赢、重新开局等功能。目前暂时没有实现机器智能走棋子的功能。

       Android的触屏功能是比较好用的,而且Android的“Window” 窗、"Shade"帘加上触摸,显得很炫。呃,这个五子棋,也是用触摸屏实现走棋的。点一下棋盘的位子,把棋子落到棋盘上。

       Android五子棋游戏界面

       先贴个图看看效果吧。

Android五子棋游戏开发

       Android五子棋游戏的实现代码

       好了,下面直接贴代码:

Java代码
  1. /*  
  2.  * Five In a Row. (五子棋)  
  3.  * 这是一个简单的五子棋程序,是我自己的一个练习,贴出来跟大家分享。  
  4.  * 希望跟大家一起多交流。 我的GoogleTalk: lixinso <at> gmail.com  
  5.  *   
  6.  *   
  7.  */   
  8. //----------------------   
  9. //TBD:AI,悔棋   
  10. //---------------------   
  11.   
  12. package lixinsong.game.gobang;   
  13.   
  14. import android.app.Activity;   
  15. import android.os.Bundle;   
  16. import android.util.Log;   
  17. import android.view.View;   
  18. import android.widget.TextView;   
  19. //这是主程序,继承自Activity,实现onCreate方法。:   
  20.   
  21.   
  22. public class gobang extends Activity {   
  23.     GobangView gbv;   
  24.        
  25.     /** Called when the activity is first created. */  
  26.     @Override  
  27.     public void onCreate(Bundle savedInstanceState) {   
  28.         super.onCreate(savedInstanceState);   
  29.   
  30.         setContentView(R.layout.main);   
  31.   
  32.            
  33.         gbv = (GobangView)this.findViewById(R.id.gobangview);   
  34.         gbv.setTextView((TextView)this.findViewById(R.id.text));   
  35.   
  36. }  

       上面代码中的R.id.gobangview是在res中定义的View:

XML/HTML代码
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent">  
  5.   
  6.     <lixinsong.game.gobang.GobangView android:id="@+id/gobangview"  
  7.         android:layout_width="fill_parent"    
  8.         android:layout_height="fill_parent"  
  9.         android:text="aaaaa" tileSize="24" />  
  10.   
  11.     <RelativeLayout  
  12.         android:layout_width="wrap_content"  
  13.         android:layout_height="wrap_content"  
  14.         android:layout_centerInParent="true" >  
  15.            
  16.         <TextView    
  17.             android:id="@+id/text"    
  18.             android:text="hahahhaha"  
  19.             android:visibility="visible"    
  20.             android:layout_width="wrap_content"  
  21.             android:layout_height="wrap_content"  
  22.             android:layout_centerInParent="true"  
  23.             android:gravity="center_horizontal"    
  24.             android:textColor="#ffff0000"  
  25.             android:textStyle="bold"  
  26.             android:textSize="24sp" />  
  27.                
  28.         </RelativeLayout>  
  29.   
  30. </FrameLayout>  
Java代码
  1. //五子棋的View   
  2.   
  3.     
  4.   
  5. package lixinsong.game.gobang;   
  6.   
  7. import android.content.Context;   
  8. import android.content.res.Resources;   
  9. import android.graphics.Bitmap;   
  10. import android.graphics.Canvas;   
  11. import android.graphics.Color;   
  12. import android.graphics.Paint;   
  13. import android.graphics.Paint.Style;   
  14. import android.graphics.drawable.Drawable;   
  15. import android.util.AttributeSet;   
  16. import android.util.Log;   
  17. import android.view.KeyEvent;   
  18. import android.view.MotionEvent;   
  19. import android.view.View;   
  20. import android.widget.TextView;   
  21.   
  22. /*棋盘一共10×10格   
  23.  * 棋盘居中  
  24.  *  
  25.  *   
  26.  *   
  27.  */  
  28. //public class GobangView extends View implements Runnable {   
  29. public class GobangView extends View{   
  30.   
  31.        
  32.     protected static int GRID_SIZE = 10;   
  33.     protected static int GRID_WIDTH = 30// 棋盘格的宽度   
  34.     protected static int CHESS_DIAMETER = 26// 棋的直径   
  35.     protected static int mStartX;// 棋盘定位的左上角X   
  36.     protected static int mStartY;// 棋盘定位的左上角Y   
  37.   
  38.     private Bitmap[] mChessBW; // 黑棋和白棋   
  39.     private static int[][] mGridArray; // 网格   
  40.        
  41.     boolean key = false;   
  42.   
  43.     int wbflag = 1//该下白棋了=2,该下黑棋了=1. 这里先下黑棋(黑棋以后设置为机器自动下的棋子)   
  44.     int mLevel = 1//游戏难度   
  45.     int mWinFlag = 0;   
  46.     private final int BLACK=1;   
  47.     private final int WHITE=2;   
  48.        
  49.     int mGameState = GAMESTATE_RUN; //游戏阶段:0=尚未游戏,1=正在进行游戏,2=游戏结束   
  50.     static final int GAMESTATE_PRE = 0;   
  51.     static final int GAMESTATE_RUN = 1;   
  52.     static final int GAMESTATE_PAUSE = 2;   
  53.     static final int GAMESTATE_END = 3;   
  54.        
  55.     //private TextView mStatusTextView; //  根据游戏状态设置显示的文字   
  56.     public TextView mStatusTextView; //  根据游戏状态设置显示的文字   
  57.        
  58.     private Bitmap btm1;   
  59.     private final Paint mPaint = new Paint();   
  60.        
  61.     CharSequence mText;   
  62.     CharSequence STRING_WIN = "White win! /n Press Fire Key to start new game.";   
  63.     CharSequence STRING_LOSE = "Black win! /n Press Fire Key to start new game.";   
  64.     CharSequence STRING_EQUAL = "Cool! You are equal! /n Press Fire Key to start new Game.";   
  65.   
  66.     public GobangView(Context context, AttributeSet attrs, int defStyle) {   
  67.         super(context, attrs, defStyle);   
  68.       }   
  69.   
  70.     public GobangView(Context context, AttributeSet attrs) { //好像调用的是这个构造函数,为什么不是前面的呢   
  71.         super(context, attrs);   
  72.         this.setFocusable(true);  //20090530   
  73.         this.setFocusableInTouchMode(true);   
  74.            
  75.         init();   
  76.     }   
  77.   
  78.      
  79.     //这里画棋子后来没有用图片画,而是直接画了圆。因为我做的图片不好看。   
  80.     // 初始化黑白棋的Bitmap   
  81.     public void init() {   
  82.         mGameState = 1//设置游戏为开始状态   
  83.         wbflag = BLACK; //初始为先下黑棋   
  84.         mWinFlag = 0//清空输赢标志。   
  85.         mGridArray = new int[GRID_SIZE-1][GRID_SIZE-1];   
  86.            
  87.         mChessBW = new Bitmap[2];   
  88.   
  89.         Bitmap bitmap = Bitmap.createBitmap(CHESS_DIAMETER, CHESS_DIAMETER, Bitmap.Config.ARGB_8888);   
  90.         Canvas canvas = new Canvas(bitmap);   
  91.         Resources r = this.getContext().getResources();   
  92.   
  93.         Drawable tile = r.getDrawable(R.drawable.chess1);   
  94.         tile.setBounds(00, CHESS_DIAMETER, CHESS_DIAMETER);   
  95.         tile.draw(canvas);   
  96.         mChessBW[0] = bitmap;   
  97.   
  98.         tile = r.getDrawable(R.drawable.chess2);   
  99.         tile.setBounds(00, CHESS_DIAMETER, CHESS_DIAMETER);   
  100.         tile.draw(canvas);   
  101.         mChessBW[1] = bitmap;   
  102.   }   
  103.   
  104.        
  105.     public void setTextView(TextView tv){   
  106.         mStatusTextView =tv;   
  107.         mStatusTextView.setVisibility(View.INVISIBLE);   
  108.     }   
  109.   
  110.     @Override  
  111.     protected void onSizeChanged(int w, int h, int oldw, int oldh) {   
  112.         mStartX = w / 2 - GRID_SIZE * GRID_WIDTH / 2;   
  113.         mStartY = h / 2 - GRID_SIZE * GRID_WIDTH / 2;   
  114.     }   
  115.        
  116.      @Override  
  117.     public boolean onTouchEvent(MotionEvent event){   
  118.         switch (mGameState) {   
  119.         case GAMESTATE_PRE:   
  120.             break;   
  121.         case GAMESTATE_RUN: {   
  122.                 int x;   
  123.                 int y;   
  124.                 float x0 = GRID_WIDTH - (event.getX() - mStartX) % GRID_WIDTH;   
  125.                 float y0 = GRID_WIDTH - (event.getY() - mStartY) % GRID_WIDTH;   
  126.                 if (x0 < GRID_WIDTH / 2) {   
  127.                     x = (int) ((event.getX() - mStartX) / GRID_WIDTH);   
  128.                 } else {   
  129.                     x = (int) ((event.getX() - mStartX) / GRID_WIDTH) - 1;   
  130.                 }   
  131.                 if (y0 < GRID_WIDTH / 2) {   
  132.                     y = (int) ((event.getY() - mStartY) / GRID_WIDTH);   
  133.                 } else {   
  134.                     y = (int) ((event.getY() - mStartY) / GRID_WIDTH) - 1;   
  135.                 }   
  136.                 if ((x >= 0 && x < GRID_SIZE - 1)   
  137.                         && (y >= 0 && y < GRID_SIZE - 1)) {   
  138.                     if (mGridArray[x][y] == 0) {   
  139.                         if (wbflag == BLACK) {   
  140.                             putChess(x, y, BLACK);   
  141.                             //this.mGridArray[x][y] = 1;    
  142.                             if(checkWin(BLACK)){ //如果是黑棋赢了   
  143.                                 mText = STRING_LOSE;   
  144.                                 mGameState = GAMESTATE_END;   
  145.                                 showTextView(mText);   
  146.                             }else if(checkFull()){//如果棋盘满了   
  147.                                 mText = STRING_EQUAL;   
  148.                                 mGameState = GAMESTATE_END;   
  149.                                 showTextView(mText);   
  150.                             }   
  151.                                
  152.                             wbflag = WHITE;   
  153.                         } else if (wbflag == WHITE) {   
  154.                             putChess(x, y, WHITE);   
  155.                             //this.mGridArray[x][y] = 2;   
  156.                             if(checkWin(WHITE)){   
  157.                                 mText = STRING_WIN;   
  158.                                 mGameState = GAMESTATE_END;   
  159.                                 showTextView(mText);   
  160.                             }else if(checkFull()){//如果棋盘满了   
  161.                                 mText = STRING_EQUAL;   
  162.                                 mGameState = GAMESTATE_END;   
  163.                                 showTextView(mText);   
  164.                             }   
  165.                             wbflag = BLACK;   
  166.                         }   
  167.                     }   
  168.                 }   
  169.             }   
  170.                
  171.             break;   
  172.         case GAMESTATE_PAUSE:   
  173.             break;   
  174.         case GAMESTATE_END:   
  175.             break;   
  176.         }   
  177.            
  178.         this.invalidate();   
  179.         return true;   
  180.            
  181.     }    
  182.        
  183.     @Override  
  184.     public boolean onKeyDown(int keyCode, KeyEvent msg) {   
  185.         Log.e("KeyEvent.KEYCODE_DPAD_CENTER"" " + keyCode);   
  186.            
  187.         if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER){   
  188.             switch(mGameState){   
  189.             case GAMESTATE_PRE:   
  190.                 break;   
  191.             case GAMESTATE_RUN:   
  192.                 break;   
  193.             case GAMESTATE_PAUSE:   
  194.                 break;   
  195.             case GAMESTATE_END:   
  196.             {//游戏结束后,按CENTER键继续   
  197.                    
  198.                 Log.e("Fire Key Pressed:::""FIRE");   
  199.                 mGameState = GAMESTATE_RUN;   
  200.                 this.setVisibility(View.VISIBLE);   
  201.                 this.mStatusTextView.setVisibility(View.INVISIBLE);   
  202.                 this.init();   
  203.                 this.invalidate();   
  204.                    
  205.                    
  206.             }   
  207.                 break;              
  208.             }   
  209.         }   
  210.            
  211.         return super.onKeyDown(keyCode, msg);   
  212.     }   
  213.   
  214.     @Override  
  215.     public void onDraw(Canvas canvas) {   
  216.   
  217.         canvas.drawColor(Color.YELLOW);   
  218.   
  219.         // 画棋盘   
  220.         {   
  221.             Paint paintRect = new Paint();   
  222.             paintRect.setColor(Color.GRAY);   
  223.             paintRect.setStrokeWidth(2);   
  224.             paintRect.setStyle(Style.STROKE);   
  225.   
  226.             for (int i = 0; i < GRID_SIZE; i++) {   
  227.                 for (int j = 0; j < GRID_SIZE; j++) {   
  228.                     int mLeft = i * GRID_WIDTH + mStartX;   
  229.                     int mTop = j * GRID_WIDTH + mStartY;   
  230.                     int mRright = mLeft + GRID_WIDTH;   
  231.                     int mBottom = mTop + GRID_WIDTH;   
  232.                     canvas.drawRect(mLeft, mTop, mRright, mBottom, paintRect);   
  233.                 }   
  234.             }   
  235.                
  236.             //画棋盘的外边框   
  237.             paintRect.setStrokeWidth(4);   
  238.             canvas.drawRect(mStartX, mStartY, mStartX + GRID_WIDTH*GRID_SIZE, mStartY + GRID_WIDTH*GRID_SIZE, paintRect);   
  239.         }   
  240.   
  241.         //画棋子   
  242.           
  243.         for (int i = 0; i < GRID_SIZE-1; i++) {   
  244.             for (int j = 0; j < GRID_SIZE-1; j++) {   
  245.                 if(mGridArray[i][j] == BLACK){   
  246.                     //通过图片来画   
  247.                     //canvas.drawBitmap(mChessBW[0], mStartX + (i+1) * GRID_WIDTH - CHESS_DIAMETER/2 , mStartY + (j+1)* GRID_WIDTH - CHESS_DIAMETER/2 , mPaint);   
  248.                        
  249.                     //通过圆形来画   
  250.                      {   
  251.                         Paint paintCircle = new Paint();   
  252.                         paintCircle.setColor(Color.BLACK);   
  253.                         canvas.drawCircle(mStartX + (i+1) * GRID_WIDTH, mStartY + (j+1)* GRID_WIDTH, CHESS_DIAMETER/2, paintCircle);   
  254.                     }    
  255.                        
  256.                 }else if(mGridArray[i][j] == WHITE){   
  257.                     //通过图片来画   
  258.                     //canvas.drawBitmap(mChessBW[1], mStartX + (i+1) * GRID_WIDTH - CHESS_DIAMETER/2 , mStartY + (j+1)* GRID_WIDTH - CHESS_DIAMETER/2 , mPaint);   
  259.                        
  260.                     //通过圆形来画   
  261.                     {   
  262.                         Paint paintCircle = new Paint();   
  263.                         paintCircle.setColor(Color.WHITE);   
  264.                         canvas.drawCircle(mStartX + (i+1) * GRID_WIDTH, mStartY + (j+1)* GRID_WIDTH, CHESS_DIAMETER/2, paintCircle);   
  265.                     }   
  266.                 }   
  267.             }   
  268.         }   
  269.     }   
  270.        
  271.     public void putChess(int x, int y, int blackwhite){   
  272.         mGridArray[x][y] = blackwhite;   
  273.     }   
  274.        
  275.     public boolean checkWin(int wbflag){   
  276.         for(int i = 0; i < GRID_SIZE - 1 ; i++ ) //i表示列(根据宽度算出来的)   
  277.             for(int j = 0; j < GRID_SIZE - 1; j++){//i表示行(根据高度算出来的)   
  278.                 //检测横轴五个相连   
  279.                 if(((i+4) < (GRID_SIZE - 1))&&   
  280.                    (mGridArray[i][j] == wbflag) && (mGridArray[i+1][j] == wbflag)&& (mGridArray[i + 2][j] == wbflag) && (mGridArray[i + 3][j] == wbflag) && (mGridArray[i + 4][j] == wbflag)){   
  281.                     Log.e("check win or loss:", wbflag + "win");   
  282.                        
  283.                     mWinFlag = wbflag;   
  284.                 }   
  285.                    
  286.                 //纵轴5个相连   
  287.                 if(((j+4) < (GRID_SIZE - 1))&&   
  288.                            (mGridArray[i][j] == wbflag) && (mGridArray[i][j+1] == wbflag)&& (mGridArray[i ][j+ 2] == wbflag) && (mGridArray[i ][j+ 3] == wbflag) && (mGridArray[i ][j+ 4] == wbflag)){   
  289.                             Log.e("check win or loss:", wbflag + "win");   
  290.                                
  291.                             mWinFlag = wbflag;   
  292.                         }   
  293.                    
  294.                 //左上到右下5个相连   
  295.                 if(((j+4) < (GRID_SIZE - 1))&& ((i+4) < (GRID_SIZE - 1)) &&   
  296.                            (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)){   
  297.                             Log.e("check win or loss:", wbflag + "win");   
  298.                                
  299.                             mWinFlag = wbflag;   
  300.                         }   
  301.                    
  302.                 //右上到左下5个相连   
  303.                 if(((i-4) >= 0)&& ((j+4) < (GRID_SIZE - 1)) &&   
  304.                            (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)){   
  305.                             Log.e("check win or loss:", wbflag + "win");   
  306.                                
  307.                             mWinFlag = wbflag;   
  308.                         }   
  309.         }   
  310.            
  311.         if( mWinFlag == wbflag){   
  312.             return true;       
  313.         }else  
  314.             return false;   
  315.            
  316.            
  317.     }   
  318.        
  319.     public boolean checkFull(){   
  320.         int mNotEmpty = 0;   
  321.         for(int i = 0; i < GRID_SIZE -1; i ++)   
  322.             for(int j = 0; j < GRID_SIZE - 1; j ++){   
  323.                 if(mGridArray[i][j] != 0) mNotEmpty +=1;   
  324.             }   
  325.            
  326.         if(mNotEmpty == (GRID_SIZE-1)*(GRID_SIZE-1)) return true;   
  327.         else return false;   
  328.     }   
  329.        
  330.     public void showTextView(CharSequence mT){   
  331.         this.mStatusTextView.setText(mT);   
  332.         mStatusTextView.setVisibility(View.VISIBLE);   
  333.            
  334.     }   
  335.   
  336. }  

 

本文发布:Android开发网
本文地址:http://www.jizhuomi.com/android/game/152.html
2012年8月10日
发布:鸡啄米 分类:Android游戏开发 浏览: 评论:1