Android 小游戏之五子棋 代码简单实现
2017-07-14 14:25
651 查看
鸿洋写的五子棋教程
public class WuZhiQiView extends View { //自定义的五子棋View //画一个棋盘,在中间画一个一个的小正方形,主要实现在onDraw method //画棋子,主要实现在onDraw method //点击那里实现具体判断具体位置,在具体位置画棋子 //实现输赢判断机制 protected static int GRID_SIZE = 15; //一排有几个格子 ,线要比实际多一条 protected static int GRID_WIDTH = 20; //棋盘格的宽度 --下面做了自动适配屏幕 --这里数字无效 protected static int CHESS_DIAMETER = 16; // 棋的直径 --下面做了自动适配屏幕 --这里数字无效 protected static int mStartX;// 棋盘定位的左上角X protected static int mStartY;// 棋盘定位的左上角Y private static int[][] mGridArray; // 网格 ---进行标识棋子的位置 -- 用来画旗子和判断输赢 boolean key = false;//是否下棋了 int wbflag = 1; //该下白棋了=2,该下黑棋了=1. 这里先下黑棋(黑棋以后设置为机器自动下的棋子) int mWinFlag = 0;//游戏赢了的标志 为1就是黑棋赢了 2为白棋子赢了 private final int BLACK = 1;//黑棋 private final int WHITE = 2;//白棋 int mGameState = GAMESTATE_RUN; //游戏阶段:0=尚未游戏,1=正在进行游戏,3=游戏结束 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 final Paint mPaint = new Paint();//是声明用来画棋子图片的笔,没用上 CharSequence mText; CharSequence STRING_WIN = "白方棋子赢,按返回键重新开始"; CharSequence STRING_LOSE = "黑方棋子赢,按返回键重新来过"; CharSequence STRING_EQUAL = "Cool! You are equal! /n Press Fire Key to start new Game."; private static Bitmap mBitmap; //记录这一刻的画面 ---不用每次画棋盘和旗子 private Canvas mMCanvas; //在画布上操作mBitmap的画面 --- 进行给上次的bitmap添加一个旗子就可以了 public WuZhiQiView(Context context, AttributeSet attrs) { super(context, attrs); this.setFocusable(true);//设置获取焦点 setFocusableInTouchMode(true);//设置可以触摸 init();//画棋子 } @Override public boolean dispatchTouchEvent(MotionEvent event) { return super.dispatchTouchEvent(event); } private void init() {//画棋子等逻辑 mGameState = 1; //设置游戏为开始状态 wbflag = BLACK; //初始为先下黑棋 mWinFlag = 0; //清空输赢标志。 mGridArray = new int[GRID_SIZE + 1][GRID_SIZE + 1];//初始化网格的大小 } public TextView mStatusTextView; // 根据游戏状态设置显示的文字 --- 这里只是简单的显示谁赢了 public void setTextView(TextView tv) { //给外面的接口显示输赢信息 // TODO 可以自己修改 mStatusT 4000 extView = tv; mStatusTextView.setVisibility(View.INVISIBLE);//显示输赢的textView } public int dip2px(float dpValue) { //dp 转 px final float scale = getResources().getDisplayMetrics().density; return (int) (dpValue * scale + 0.5f); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { GRID_WIDTH = w/GRID_SIZE-dip2px(2);//自行匹配屏幕 CHESS_DIAMETER =GRID_WIDTH -dip2px(5);//自行匹配棋子的宽度 mStartX = w / 2 - GRID_SIZE * GRID_WIDTH / 2;//棋盘定位的左上角X mStartY = h / 2 - GRID_SIZE * GRID_WIDTH / 2;//棋盘定位的左上角Y } int x;//记录触摸最后棋子落子的位置(是在数据里的角标记录) int y;//记录触摸最后棋子落子的位置 //触摸事件的处理 @Override public boolean onTouchEvent(MotionEvent event) {//处理棋子落子后的逻辑 key = true; switch (mGameState) {//游戏状态 case GAMESTATE_PRE://游戏未开始 break; case GAMESTATE_RUN: {//游戏开始 float x0 = GRID_WIDTH - (event.getX() - mStartX) % GRID_WIDTH;//是否是触摸了网格上面的x float y0 = GRID_WIDTH - (event.getY() - mStartY) % GRID_WIDTH;//是否是触摸了网格上面的y if (x0 < GRID_WIDTH / 2) {//判断是否超过了网格线的一半 x = (int) ((event.getX() - mStartX) / GRID_WIDTH) + 1;//x为网格的线上 } else { x = (int) ((event.getX() - mStartX) / GRID_WIDTH);//x为网格的线上 上一格 } if (y0 < GRID_WIDTH / 2) {//判断是否超过了网格线的一半 y = (int) ((event.getY() - mStartY) / GRID_WIDTH) + 1; } else { y = (int) ((event.getY() - mStartY) / GRID_WIDTH); } 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;//标记另一方下子 this.invalidate();//重画界面 } 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; this.invalidate();//重画界面 } } } } break; case GAMESTATE_PAUSE://游戏暂停 break; case GAMESTATE_END://游戏结束 break; } return true; } @Override public boolean onKeyDown(int keyCode, KeyEvent msg) {//复写返回按钮,重新开始 if (keyCode == KeyEvent.KEYCODE_BACK) { switch (mGameState) { case GAMESTATE_PRE://游戏状态,游戏准备前 break; case GAMESTATE_RUN: break; case GAMESTATE_PAUSE: break; case GAMESTATE_END: {//游戏结束后,按CENTER键继续 mGameState = GAMESTATE_RUN;//改变游戏状态 this.setVisibility(View.VISIBLE);//本view可见 this.mStatusTextView.setVisibility(View.INVISIBLE);//提示信息不可见 this.init();//重画棋子等,重走逻辑 flag = false; this.invalidate();//重画 } break; } } return true;//复写方法,自己处理 } boolean flag; @Override public void onDraw(Canvas canvas) {// 画棋盘 canvas.drawColor(Color.YELLOW); if (flag == false) {//控制画棋盘的次数,只画一次棋盘,提高绘制效率 mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); mMCanvas = new Canvas(mBitmap); // 画棋盘 //画棋盘的外边框 mPaint.setColor(Color.GRAY);//设置画笔的颜色,灰色 mPaint.setStyle(Paint.Style.STROKE);//设置风格是描边 mPaint.setStrokeWidth(4); mMCanvas.drawRect(mStartX, mStartY, mStartX + GRID_WIDTH * GRID_SIZE, mStartY + GRID_WIDTH * GRID_SIZE, mPaint); mPaint.setStrokeWidth(2);//设置线条宽度 //画中间的格子 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; mMCanvas.drawRect(mLeft, mTop, mRright, mBottom, mPaint);//画一段一段小矩形,形成棋盘 } } flag = true; } mPaint.setStyle(Paint.Style.FILL_AND_STROKE); //设置风格是描边和填充 if (mGridArray[x][y] == BLACK) { //画黑棋子 mPaint.setColor(Color.BLACK); mMCanvas.drawCircle(mStartX + x * GRID_WIDTH, mStartY + y * GRID_WIDTH, CHESS_DIAMETER / 2, mPaint); } else if (mGridArray[x][y] == WHITE) { //画白棋 mPaint.setColor(Color.WHITE); mMCanvas.drawCircle(mStartX + x * GRID_WIDTH, mStartY + y * GRID_WIDTH, CHESS_DIAMETER / 2, mPaint); } canvas.drawBitmap(mBitmap, 0, 0, mPaint); } 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表示列(根据宽度算出来的) for (int j = 0; j < GRID_SIZE - 1; j++) {//i表示行(根据高度算出来的) //检测横轴五个相连 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个相连 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个相连 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个相连 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) {//显示提示文本 if(mStatusTextView==null) return; this.mStatusTextView.setText(mT); mStatusTextView.setVisibility(View.VISIBLE); } }
相关文章推荐
- android小游戏——2048 核心功能的实现与简单的代码重构(2)
- Android 小游戏2048 代码简单实现
- Android小游戏2048的简单实现
- Android实现用代码简单安装和卸载APK的方法
- (转)Android百度地图之位置定位和附近查找代码简单实现 (上)
- Android GridViewd 简单代码实现
- Android-使用xUtils实现简单断点续传(主要代码)
- Android jni aes加解密,实现文件的加解密,具体实现可以自行修改,上面的代码为简单介绍,下面的是JNI端实现文件加解密,可以修改为字符串加解密
- Android实现下载工具的简单代码
- Android侧滑效果简单实现代码
- Android平台Camera实时滤镜实现方法探讨(十)--代码地址以及简单介绍(20160118更新)
- 提示代码Android之Toast简单实现不循环提示
- 【Android:简单夜间模式切换实现】夜间模式切换,完整代码奉上!
- Android ContentProvider的实现及简单实例代码
- android实现简单的画画板实例代码
- js猜数字小游戏的简单实现代码
- android之自定义View和ViewGroup(六)(代码篇,实现简单的走势图,柱状图同理)
- 一个简单的Android客户端从服务器端获取json数据并解析的实现代码
- Android实现简单Launcher的代码示例
- java和Android文件下载断点续传和图片下载代码实现,可直接复制简单实现