五子棋 - Fivechess

代码下载  -   公共邮箱(注意看邮件时间,省得被些无聊东东...)java

邮箱: code_share@163.com  密码:code_share1android

2011年4月16日 00:06 (星期六) canvas


先上效果图app

啥也不说了, 跟snake差很少
ide

package com.taln.fivechess; import com.taln.fivechess.R; import android.app.Activity; import android.os.Bundle; import android.widget.TextView; public class FiveChess extends Activity { private ChessView chessview ; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //下面两个无关紧要, main.xml已经有定义此view chessview = (ChessView)this.findViewById(R.id.chessview); chessview.setTextView((TextView)this.findViewById(R.id.text)); } } package com.taln.fivechess; import android.content.Context; public class ChessView extends View { private static final int GRID_COUNT = 16; private static final int GRID_SIZE = 19; private static int[][] myGrid; private static final int CHESS_SIZE = 15; private static int mStartX; private static int mStartY; private Bitmap[] mChess; Paint myPaint = new Paint(); private int BLACK = 1; private int WHITE = 2; private boolean isBlack; private boolean isWhite; private int winFlag; protected int myMode; private static final int START = 1; private static final int RUNNING = 2; private static final int LOSE = 3; private TextView myTextView; String mText; String TEXT_START = "Press CENTER Key to start the game."; String TEXT_WIN = "White win! \n Press CENTER Key to start new game."; String TEXT_LOSE = "Black win! \n Press CENTER Key to start new game."; //这里调用的是这个构造 public ChessView(Context context, AttributeSet attrs) { super(context, attrs); this.setFocusable(true); this.setFocusableInTouchMode(true); initGame(); System.out.println("ChessView(Context context, AttributeSet attrs) is invoked" ) ; } //若是用到了values包下定义的属性文件attrs.xml可能会调用它, 我也没有试.有兴趣能够试一下 public ChessView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.setFocusable(true); this.setFocusableInTouchMode(true); initGame(); System.out.println(" ChessView(Context context, AttributeSet attrs, int defStyle) is invoked" ) ; } public void initGame() { myMode = RUNNING ; myGrid = new int[GRID_COUNT][GRID_COUNT]; winFlag = 0; isBlack = true; isWhite = false; mChess = new Bitmap[2];//定义黑白棋子 Bitmap bitmap = Bitmap.createBitmap(CHESS_SIZE, CHESS_SIZE, 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_SIZE, CHESS_SIZE); tile.draw(canvas);//设置图片要画时所在的画布.此时bitmap就拥有的图片和画布以及本身的属性,完整了 mChess[0] = bitmap; tile = r.getDrawable(R.drawable.chess2); tile.setBounds(0, 0, CHESS_SIZE, CHESS_SIZE); tile.draw(canvas); mChess[1] = bitmap; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { //横竖屏切换时设置棋盘.够一个格子,画出来,最后不够的那个分红两半,左右一边一半 mStartX = ((w - (GRID_COUNT * GRID_SIZE)) / 2); mStartY = ((h - (GRID_COUNT * GRID_SIZE)) / 2); super.onSizeChanged(w, h, oldw, oldh); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(Color.YELLOW); myPaint.setStrokeWidth(2); //线的宽度 myPaint.setStyle(Style.STROKE); for (int i = 0; i < GRID_COUNT; i++) { for (int j = 0; j < GRID_COUNT; j++) { //画网格,左上角和右下角,定位一个正方形 int point1X = mStartX + i * GRID_SIZE; int point1Y = mStartY + j * GRID_SIZE; int point2X = point1X + GRID_SIZE; int point2Y = point1Y + GRID_SIZE; canvas.drawRect(point1X, point1Y, point2X, point2Y, myPaint); } } for (int i = 0; i < GRID_COUNT-1; i++) { //画棋子,判断myGrid[i][j] == BLACK时画黑棋... Paint chessPaint = new Paint(); for (int j = 0; j < GRID_COUNT-1; j++) { if(myGrid[i][j] == BLACK){ { chessPaint.setColor(Color.BLACK); canvas.drawCircle(mStartX + (i+1) * GRID_SIZE, mStartY + (j+1)* GRID_SIZE, CHESS_SIZE/2, chessPaint); } }else if(myGrid[i][j] == WHITE){ { chessPaint.setColor(Color.WHITE); canvas.drawCircle(mStartX + (i+1) * GRID_SIZE, mStartY + (j+1)* GRID_SIZE, CHESS_SIZE/2, chessPaint); } } } } if(myMode == START){ //刚开始时显示的提示 showTextView(TEXT_START); } super.onDraw(canvas); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { if(myMode == START){ myMode = RUNNING; } switch (myMode) { case START: break; case RUNNING: break; case LOSE: { myMode = RUNNING; this.setVisibility(View.VISIBLE); this.myTextView.setVisibility(View.INVISIBLE); this.initGame(); //view若是想要从新自动调用onDraw,必须先调用invalidate() this.invalidate(); } break; } } return super.onKeyDown(keyCode, event); } @Override public boolean onTouchEvent(MotionEvent e) { switch (myMode) { case START: { break; } case RUNNING: { int x, y;//touch的位置 float x0 = GRID_SIZE - (e.getX() - mStartX) % GRID_SIZE; float y0 = GRID_SIZE - (e.getY() - mStartY) % GRID_SIZE; if (x0 < GRID_SIZE / 2) { //根据四舍五入,靠近哪一边,棋子就画在哪一边 x = (int) (e.getX() - mStartX) / GRID_SIZE; } else { x = (int) (e.getX() - mStartX) / GRID_SIZE - 1; } if (y0 < GRID_SIZE / 2) { y = (int) (e.getY() - mStartY) / GRID_SIZE; } else { y = (int) (e.getY() - mStartY) / GRID_SIZE - 1; } if (x >= 0 && x < GRID_COUNT && y >= 0 && y < GRID_COUNT) { //若是下的棋子没有过界 if (myGrid[x][y] == 0) { if (isBlack ) { myGrid[x][y] = BLACK; if(checkWin(BLACK)){//检查是否连成五子 mText = TEXT_LOSE; myMode = LOSE; showTextView(mText); } isBlack = false; isWhite = true; }else if (isWhite) { myGrid[x][y] = WHITE; if(checkWin(WHITE)){ mText = TEXT_WIN; myMode = LOSE; showTextView(mText); } isBlack = true; isWhite = false; } } }break; } case LOSE: { break; } } this.invalidate(); return true; } public boolean checkWin(int blackOrWhite) { for(int i = 0; i < GRID_COUNT - 1 ; i++ ) for(int j = 0; j < GRID_COUNT - 1; j++){ if(((i+4) < (GRID_COUNT - 1))&& (myGrid[i][j] == blackOrWhite) && (myGrid[i+1][j] == blackOrWhite)&& (myGrid[i + 2][j] == blackOrWhite) && (myGrid[i + 3][j] == blackOrWhite) && (myGrid[i + 4][j] == blackOrWhite)){ Log.e("check win or loss:", blackOrWhite + "win"); winFlag = blackOrWhite; } if(((j+4) < (GRID_COUNT - 1))&& (myGrid[i][j] == blackOrWhite) && (myGrid[i][j+1] == blackOrWhite) && (myGrid[i ][j+ 2] == blackOrWhite) && (myGrid[i ][j+ 3] == blackOrWhite) && (myGrid[i ][j+ 4] == blackOrWhite)){ Log.e("check win or loss:", blackOrWhite + "win"); winFlag = blackOrWhite; } if(((j+4) < (GRID_COUNT - 1)) && ((i+4) < (GRID_COUNT - 1)) && (myGrid[i][j] == blackOrWhite) && (myGrid[i+1][j+1] == blackOrWhite) && (myGrid[i + 2 ][j+ 2] == blackOrWhite) && (myGrid[i + 3][j+ 3] == blackOrWhite) && (myGrid[i + 4 ][j+ 4] == blackOrWhite)){ Log.e("check win or loss:", blackOrWhite + "win"); winFlag = blackOrWhite; } if(((i-4) >= 0)&& ((j+4) < (GRID_COUNT - 1)) && (myGrid[i][j] == blackOrWhite) && (myGrid[i-1][j+1] == blackOrWhite) && (myGrid[i - 2 ][j+ 2] == blackOrWhite) && (myGrid[i - 3][j+ 3] == blackOrWhite) && (myGrid[i - 4 ][j+ 4] == blackOrWhite)){ Log.e("check win or loss:", blackOrWhite + "win"); winFlag = blackOrWhite; } } if( winFlag == blackOrWhite){ return true; }else return false; } public void setTextView(TextView textview) { myTextView = textview; myTextView.setVisibility(View.INVISIBLE); } public void showTextView(String s){ myTextView.setText(s); myTextView.setVisibility(View.VISIBLE); } public void setMode(int mode){ myMode = mode ; myTextView.setText(TEXT_START); myTextView.setVisibility(View.VISIBLE); } } <?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" > <com.taln.fivechess.ChessView android:id="@+id/chessview" android:layout_width="fill_parent" android:layout_height="fill_parent" /> <RelativeLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" > <TextView android:id="@+id/text" 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:textSize="24sp" /> </RelativeLayout> </FrameLayout>