绘制棋盘面板:

MainActivity.java
package com.xbmu.wuziqi;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);    }}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.xbmu.wuziqi.MainActivity">    <com.xbmu.wuziqi.WuziqiPanel        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_centerInParent="true" /></RelativeLayout>
WuziqiPanel.java
package com.xbmu.wuziqi;import android.content.Context;import android.graphics.Canvas;import android.graphics.Paint;import android.util.AttributeSet;import android.view.View;/** * 五子棋面板 * Created by Administrator on 2016/5/2 0002. */public class WuziqiPanel extends View {    private int mPanelWidth;//棋盘宽度    private float mLineHeight;//棋盘每行行高    private int MAX_LINE = 10;//棋盘最大行数    //创建绘画对象    private Paint mPaint = new Paint();    public WuziqiPanel(Context context, AttributeSet attrs) {        super(context, attrs);        setBackgroundColor(0x44ff0000);        init();    }    /**初始化画笔属性*/    private void init() {        mPaint.setColor(0x88000000);//设置颜色为灰色效果        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.STROKE);    }    /**测量一个view的大小*/    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(widthMeasureSpec);        int width = Math.min(widthSize,heightSize);        if(widthMode == MeasureSpec.UNSPECIFIED){            width = heightSize;        }else if(heightMode == MeasureSpec.UNSPECIFIED){            width = widthSize;        }        //设置自身大小        setMeasuredDimension(width,width);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mPanelWidth = w;        mLineHeight = mPanelWidth*1.0f / MAX_LINE;    }    /**Draw画出View的显示内容*/    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        drawBoard(canvas);    }    private void drawBoard(Canvas canvas) {        /**         * 分析:根据棋盘的效果,我们知道棋子是下在边界的交叉点上的。可得棋盘中间有9个完整的lineHeight,         * 上下两边有半个lineHeight,总共10个lineHeight。左右也是。         */        int w = mPanelWidth;        float lineHeight = mLineHeight;        for(int i=0;i<MAX_LINE;i++){            int startX = (int) (lineHeight / 2);//起点坐标            int endX = (int) (w - lineHeight / 2);//终点坐标            int y = (int) ((0.5+i)*lineHeight);            canvas.drawLine(startX,y,endX,y,mPaint);            canvas.drawLine(y,startX,y,endX,mPaint);        }    }}
运行效果: Android五子连珠_第1张图片

绘制黑白棋子:

WuziqiPanel.java
package com.xbmu.wuziqi;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Point;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import java.util.ArrayList;import java.util.List;/** * 五子棋面板 * Created by Administrator on 2016/5/2 0002. */public class WuziqiPanel extends View {    private int mPanelWidth;//棋盘宽度    private float mLineHeight;//棋盘每行行高    private int MAX_LINE = 10;//棋盘最大行数    //创建绘画对象    private Paint mPaint = new Paint();    private Bitmap mWhitePiece;//白色棋子    private Bitmap mBlackPiece;//黑色棋子    //比例:棋子的大小是行高的3/4;    private float ratioPieceOfLineHeight = 3*1.0f / 4;    //白棋先手,当前轮到白棋。    private boolean mIsWhite = true;    private List<Point> mWhiteArray = new ArrayList<>();    private List<Point> mBlackArray = new ArrayList<>();    public WuziqiPanel(Context context, AttributeSet attrs) {        super(context, attrs);        setBackgroundColor(0x44ff0000);        init();    }    /**初始化画笔属性*/    private void init() {        mPaint.setColor(0x88000000);//设置颜色为灰色效果        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.STROKE);        mWhitePiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_w2);        mBlackPiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_b1);    }    /**测量一个view的大小*/    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(widthMeasureSpec);        int width = Math.min(widthSize,heightSize);        if(widthMode == MeasureSpec.UNSPECIFIED){            width = heightSize;        }else if(heightMode == MeasureSpec.UNSPECIFIED){            width = widthSize;        }        //设置自身大小        setMeasuredDimension(width,width);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mPanelWidth = w;        mLineHeight = mPanelWidth*1.0f / MAX_LINE;        int pieceWidth = (int) (mLineHeight * ratioPieceOfLineHeight);//棋子宽度        mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece,pieceWidth,pieceWidth,false);        mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece,pieceWidth,pieceWidth,false);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        int action = event.getAction();        if(action == MotionEvent.ACTION_DOWN){            int x = (int) event.getX();            int y = (int) event.getY();            Point p = getValidPoint(x,y);            if(mWhiteArray.contains(p) || mBlackArray.contains(p)){                return false;            }            if(mIsWhite){                mWhiteArray.add(p);            }else{                mBlackArray.add(p);            }            invalidate();//请求重绘            mIsWhite = !mIsWhite;            return true;        }        return super.onTouchEvent(event);    }    private Point getValidPoint(int x, int y) {        return new Point((int)(x/mLineHeight) ,(int)(y/mLineHeight));    }    /**Draw画出View的显示内容*/    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //绘制棋盘        drawBoard(canvas);        //绘制棋子        drawPieces(canvas);    }    private void drawPieces(Canvas canvas) {        for(int i=0,n = mWhiteArray.size(); i< n ;i++){            Point whitePoint = mWhiteArray.get(i);            canvas.drawBitmap(mWhitePiece,                    (whitePoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (whitePoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }        for(int i=0,n = mBlackArray.size(); i< n ;i++){            Point blackPoint = mBlackArray.get(i);            canvas.drawBitmap(mBlackPiece,                    (blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }    }    private void drawBoard(Canvas canvas) {        /**         * 分析:根据棋盘的效果,我们知道棋子是下在边界的交叉点上的。可得棋盘中间有9个完整的lineHeight,         * 上下两边有半个lineHeight,总共10个lineHeight。左右也是。         */        int w = mPanelWidth;        float lineHeight = mLineHeight;        for(int i=0;i<MAX_LINE;i++){            int startX = (int) (lineHeight / 2);//起点坐标            int endX = (int) (w - lineHeight / 2);//终点坐标            int y = (int) ((0.5+i)*lineHeight);            canvas.drawLine(startX,y,endX,y,mPaint);            canvas.drawLine(y,startX,y,endX,mPaint);        }    }}
运行效果: Android五子连珠_第2张图片

五子棋业务逻辑判断:

WuziqiPanel.java
package com.xbmu.wuziqi;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Point;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.Toast;import java.util.ArrayList;import java.util.List;/** * 五子棋面板 * Created by Administrator on 2016/5/2 0002. */public class WuziqiPanel extends View {    private int mPanelWidth;//棋盘宽度    private float mLineHeight;//棋盘每行行高    private int MAX_LINE = 10;//棋盘最大行数    //创建绘画对象    private Paint mPaint = new Paint();    private Bitmap mWhitePiece;//白色棋子    private Bitmap mBlackPiece;//黑色棋子    //比例:棋子的大小是行高的3/4;    private float ratioPieceOfLineHeight = 3*1.0f / 4;    //白棋先手,当前轮到白棋。    private boolean mIsWhite = true;    private List<Point> mWhiteArray = new ArrayList<>();    private List<Point> mBlackArray = new ArrayList<>();    private boolean mIsGameOver;    private boolean mIsWhiteWinner;    private int MAX_COUNT_IN_LINE = 5;    public WuziqiPanel(Context context, AttributeSet attrs) {        super(context, attrs);        setBackgroundColor(0x44ff0000);        init();    }    /**初始化画笔属性*/    private void init() {        mPaint.setColor(0x88000000);//设置颜色为灰色效果        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.STROKE);        mWhitePiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_w2);        mBlackPiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_b1);    }    /**测量一个view的大小*/    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(widthMeasureSpec);        int width = Math.min(widthSize,heightSize);        if(widthMode == MeasureSpec.UNSPECIFIED){            width = heightSize;        }else if(heightMode == MeasureSpec.UNSPECIFIED){            width = widthSize;        }        //设置自身大小        setMeasuredDimension(width,width);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mPanelWidth = w;        mLineHeight = mPanelWidth*1.0f / MAX_LINE;        int pieceWidth = (int) (mLineHeight * ratioPieceOfLineHeight);//棋子宽度        mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece,pieceWidth,pieceWidth,false);        mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece,pieceWidth,pieceWidth,false);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        int action = event.getAction();        if(action == MotionEvent.ACTION_DOWN){            int x = (int) event.getX();            int y = (int) event.getY();            Point p = getValidPoint(x,y);            if(mWhiteArray.contains(p) || mBlackArray.contains(p)){                return false;            }            if(mIsWhite){                mWhiteArray.add(p);            }else{                mBlackArray.add(p);            }            invalidate();//请求重绘            mIsWhite = !mIsWhite;            return true;        }        return super.onTouchEvent(event);    }    private Point getValidPoint(int x, int y) {        return new Point((int)(x/mLineHeight) ,(int)(y/mLineHeight));    }    /**Draw画出View的显示内容*/    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //绘制棋盘        drawBoard(canvas);        //绘制棋子        drawPieces(canvas);        //检查游戏结束        checkGameOver();    }    private void checkGameOver() {        boolean whiteWin = checkFiveInLine(mWhiteArray);        boolean blackWin = checkFiveInLine(mBlackArray);        if(whiteWin || blackWin){            mIsGameOver = true;            mIsWhiteWinner = whiteWin;            String text = mIsWhiteWinner ? "白棋胜利":"黑棋胜利";            Toast.makeText(getContext(),text,Toast.LENGTH_LONG).show();        }    }    private boolean checkFiveInLine(List<Point> points) {        for (Point p : points){            int x = p.x;            int y = p.y;            boolean win = checkHorizontal(x,y,points);            if(win) return true;            win = checkVertical(x,y,points);            if(win) return true;            win =checkLeftDiagonal(x,y,points);            if(win) return true;            win = checkRightDiagonal(x,y,points);            if(win) return true;        }        return false;    }    /**     * 判断x,y位置的棋子,是否横向有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkHorizontal(int x, int y, List<Point> points) {        int count = 1;        //左        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否纵向有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkVertical(int x, int y, List<Point> points) {        int count = 1;        //上        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x,y-i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x,y+i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否左斜有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkLeftDiagonal(int x, int y, List<Point> points) {        int count = 1;        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y+i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y-i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否右斜有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkRightDiagonal(int x, int y, List<Point> points) {        int count = 1;        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y-i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y+i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    private void drawPieces(Canvas canvas) {        for(int i=0,n = mWhiteArray.size(); i< n ;i++){            Point whitePoint = mWhiteArray.get(i);            canvas.drawBitmap(mWhitePiece,                    (whitePoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (whitePoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }        for(int i=0,n = mBlackArray.size(); i< n ;i++){            Point blackPoint = mBlackArray.get(i);            canvas.drawBitmap(mBlackPiece,                    (blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }    }    private void drawBoard(Canvas canvas) {        /**         * 分析:根据棋盘的效果,我们知道棋子是下在边界的交叉点上的。可得棋盘中间有9个完整的lineHeight,         * 上下两边有半个lineHeight,总共10个lineHeight。左右也是。         */        int w = mPanelWidth;        float lineHeight = mLineHeight;        for(int i=0;i<MAX_LINE;i++){            int startX = (int) (lineHeight / 2);//起点坐标            int endX = (int) (w - lineHeight / 2);//终点坐标            int y = (int) ((0.5+i)*lineHeight);            canvas.drawLine(startX,y,endX,y,mPaint);            canvas.drawLine(y,startX,y,endX,mPaint);        }    }}

View的存储与恢复:

WuziqiPanel.java
package com.xbmu.wuziqi;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Point;import android.os.Bundle;import android.os.Parcelable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.Toast;import java.util.ArrayList;import java.util.List;/** * 五子棋面板 * Created by Administrator on 2016/5/2 0002. */public class WuziqiPanel extends View {    private int mPanelWidth;//棋盘宽度    private float mLineHeight;//棋盘每行行高    private int MAX_LINE = 10;//棋盘最大行数    //创建绘画对象    private Paint mPaint = new Paint();    private Bitmap mWhitePiece;//白色棋子    private Bitmap mBlackPiece;//黑色棋子    //比例:棋子的大小是行高的3/4;    private float ratioPieceOfLineHeight = 3*1.0f / 4;    //白棋先手,当前轮到白棋。    private boolean mIsWhite = true;    private ArrayList<Point> mWhiteArray = new ArrayList<>();    private ArrayList<Point> mBlackArray = new ArrayList<>();    private boolean mIsGameOver;    private boolean mIsWhiteWinner;    private int MAX_COUNT_IN_LINE = 5;    public WuziqiPanel(Context context, AttributeSet attrs) {        super(context, attrs);        setBackgroundColor(0x44ff0000);        init();    }    /**初始化画笔属性*/    private void init() {        mPaint.setColor(0x88000000);//设置颜色为灰色效果        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.STROKE);        mWhitePiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_w2);        mBlackPiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_b1);    }    /**测量一个view的大小*/    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(widthMeasureSpec);        int width = Math.min(widthSize,heightSize);        if(widthMode == MeasureSpec.UNSPECIFIED){            width = heightSize;        }else if(heightMode == MeasureSpec.UNSPECIFIED){            width = widthSize;        }        //设置自身大小        setMeasuredDimension(width,width);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mPanelWidth = w;        mLineHeight = mPanelWidth*1.0f / MAX_LINE;        int pieceWidth = (int) (mLineHeight * ratioPieceOfLineHeight);//棋子宽度        mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece,pieceWidth,pieceWidth,false);        mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece,pieceWidth,pieceWidth,false);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        int action = event.getAction();        if(action == MotionEvent.ACTION_DOWN){            int x = (int) event.getX();            int y = (int) event.getY();            Point p = getValidPoint(x,y);            if(mWhiteArray.contains(p) || mBlackArray.contains(p)){                return false;            }            if(mIsWhite){                mWhiteArray.add(p);            }else{                mBlackArray.add(p);            }            invalidate();//请求重绘            mIsWhite = !mIsWhite;            return true;        }        return super.onTouchEvent(event);    }    private Point getValidPoint(int x, int y) {        return new Point((int)(x/mLineHeight) ,(int)(y/mLineHeight));    }    /**Draw画出View的显示内容*/    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //绘制棋盘        drawBoard(canvas);        //绘制棋子        drawPieces(canvas);        //检查游戏结束        checkGameOver();    }    private void checkGameOver() {        boolean whiteWin = checkFiveInLine(mWhiteArray);        boolean blackWin = checkFiveInLine(mBlackArray);        if(whiteWin || blackWin){            mIsGameOver = true;            mIsWhiteWinner = whiteWin;            String text = mIsWhiteWinner ? "白棋胜利":"黑棋胜利";            Toast.makeText(getContext(),text,Toast.LENGTH_LONG).show();        }    }    private boolean checkFiveInLine(List<Point> points) {        for (Point p : points){            int x = p.x;            int y = p.y;            boolean win = checkHorizontal(x,y,points);            if(win) return true;            win = checkVertical(x,y,points);            if(win) return true;            win =checkLeftDiagonal(x,y,points);            if(win) return true;            win = checkRightDiagonal(x,y,points);            if(win) return true;        }        return false;    }    /**     * 判断x,y位置的棋子,是否横向有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkHorizontal(int x, int y, List<Point> points) {        int count = 1;        //左        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否纵向有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkVertical(int x, int y, List<Point> points) {        int count = 1;        //上        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x,y-i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x,y+i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否左斜有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkLeftDiagonal(int x, int y, List<Point> points) {        int count = 1;        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y+i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y-i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否右斜有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkRightDiagonal(int x, int y, List<Point> points) {        int count = 1;        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y-i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y+i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    private void drawPieces(Canvas canvas) {        for(int i=0,n = mWhiteArray.size(); i< n ;i++){            Point whitePoint = mWhiteArray.get(i);            canvas.drawBitmap(mWhitePiece,                    (whitePoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (whitePoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }        for(int i=0,n = mBlackArray.size(); i< n ;i++){            Point blackPoint = mBlackArray.get(i);            canvas.drawBitmap(mBlackPiece,                    (blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }    }    private void drawBoard(Canvas canvas) {        /**         * 分析:根据棋盘的效果,我们知道棋子是下在边界的交叉点上的。可得棋盘中间有9个完整的lineHeight,         * 上下两边有半个lineHeight,总共10个lineHeight。左右也是。         */        int w = mPanelWidth;        float lineHeight = mLineHeight;        for(int i=0;i<MAX_LINE;i++){            int startX = (int) (lineHeight / 2);//起点坐标            int endX = (int) (w - lineHeight / 2);//终点坐标            int y = (int) ((0.5+i)*lineHeight);            canvas.drawLine(startX,y,endX,y,mPaint);            canvas.drawLine(y,startX,y,endX,mPaint);        }    }    private static final String INSTANCE = "instance";    private static final String INSTANCE_GAME_OVER = "instance_game_over";    private static final String INSTANCE_WHITE_ARRAY = "instance_white_array";    private static final String INSTANCE_BLACK_ARRAY = "instance_black_array";    @Override    protected Parcelable onSaveInstanceState() {        Bundle bundle = new Bundle();        bundle.putParcelable(INSTANCE,super.onSaveInstanceState());        bundle.putBoolean(INSTANCE_GAME_OVER,mIsGameOver);        bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY,mWhiteArray);        bundle.putParcelableArrayList(INSTANCE_BLACK_ARRAY,mBlackArray);        return bundle;    }    @Override    protected void onRestoreInstanceState(Parcelable state) {        if(state instanceof Bundle){            Bundle bundle = (Bundle) state;            mIsGameOver = bundle.getBoolean(INSTANCE_GAME_OVER);            mWhiteArray = bundle.getParcelableArrayList(INSTANCE_WHITE_ARRAY);            mBlackArray = bundle.getParcelableArrayList(INSTANCE_BLACK_ARRAY);            super.onRestoreInstanceState(bundle.getParcelable(INSTANCE));            return ;        }        super.onRestoreInstanceState(state);    }}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@drawable/bg"    tools:context="com.xbmu.wuziqi.MainActivity">    <com.xbmu.wuziqi.WuziqiPanel        android:id="@+id/id_wuziqi"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_centerInParent="true" /></RelativeLayout>
运行效果:

再来一局&我要悔棋

Wuziqi.java
package com.xbmu.wuziqi;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Point;import android.os.Bundle;import android.os.Parcelable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.widget.Toast;import java.util.ArrayList;import java.util.List;/** * 五子棋面板 * Created by Administrator on 2016/5/2 0002. */public class WuziqiPanel extends View {    private int mPanelWidth;//棋盘宽度    private float mLineHeight;//棋盘每行行高    private int MAX_LINE = 10;//棋盘最大行数    //创建绘画对象    private Paint mPaint = new Paint();    private Bitmap mWhitePiece;//白色棋子    private Bitmap mBlackPiece;//黑色棋子    //比例:棋子的大小是行高的3/4;    private float ratioPieceOfLineHeight = 3*1.0f / 4;    //白棋先手,当前轮到白棋。    private boolean mIsWhite = true;    private ArrayList<Point> mWhiteArray = new ArrayList<>();    private ArrayList<Point> mBlackArray = new ArrayList<>();    private boolean mIsGameOver;    private boolean mIsWhiteWinner;    private int MAX_COUNT_IN_LINE = 5;    public WuziqiPanel(Context context, AttributeSet attrs) {        super(context, attrs);        setBackgroundColor(0x44ff0000);        init();    }    /**初始化画笔属性*/    private void init() {        mPaint.setColor(0x88000000);//设置颜色为灰色效果        mPaint.setAntiAlias(true);        mPaint.setDither(true);        mPaint.setStyle(Paint.Style.STROKE);        mWhitePiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_w2);        mBlackPiece = BitmapFactory.decodeResource(getResources(),R.drawable.stone_b1);    }    /**测量一个view的大小*/    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int widthSize = MeasureSpec.getSize(widthMeasureSpec);        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightSize = MeasureSpec.getSize(heightMeasureSpec);        int heightMode = MeasureSpec.getMode(widthMeasureSpec);        int width = Math.min(widthSize,heightSize);        if(widthMode == MeasureSpec.UNSPECIFIED){            width = heightSize;        }else if(heightMode == MeasureSpec.UNSPECIFIED){            width = widthSize;        }        //设置自身大小        setMeasuredDimension(width,width);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        mPanelWidth = w;        mLineHeight = mPanelWidth*1.0f / MAX_LINE;        int pieceWidth = (int) (mLineHeight * ratioPieceOfLineHeight);//棋子宽度        mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece,pieceWidth,pieceWidth,false);        mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece,pieceWidth,pieceWidth,false);    }    @Override    public boolean onTouchEvent(MotionEvent event) {        int action = event.getAction();        if(action == MotionEvent.ACTION_DOWN){            int x = (int) event.getX();            int y = (int) event.getY();            Point p = getValidPoint(x,y);            if(mWhiteArray.contains(p) || mBlackArray.contains(p)){                return false;            }            if(mIsWhite){                mWhiteArray.add(p);            }else{                mBlackArray.add(p);            }            invalidate();//请求重绘            mIsWhite = !mIsWhite;            return true;        }        return super.onTouchEvent(event);    }    private Point getValidPoint(int x, int y) {        return new Point((int)(x/mLineHeight) ,(int)(y/mLineHeight));    }    private Canvas canvas;    /**Draw画出View的显示内容*/    @Override    protected void onDraw(Canvas canvas) {        this.canvas = canvas;        super.onDraw(canvas);        //绘制棋盘        drawBoard(canvas);        //绘制棋子        drawPieces(canvas);        //检查游戏结束        checkGameOver();    }    private void checkGameOver() {        boolean whiteWin = checkFiveInLine(mWhiteArray);        boolean blackWin = checkFiveInLine(mBlackArray);        if(whiteWin || blackWin){            mIsGameOver = true;            mIsWhiteWinner = whiteWin;            String text = mIsWhiteWinner ? "白棋胜利":"黑棋胜利";            Toast.makeText(getContext(),text,Toast.LENGTH_LONG).show();        }    }    private boolean checkFiveInLine(List<Point> points) {        for (Point p : points){            int x = p.x;            int y = p.y;            boolean win = checkHorizontal(x,y,points);            if(win) return true;            win = checkVertical(x,y,points);            if(win) return true;            win =checkLeftDiagonal(x,y,points);            if(win) return true;            win = checkRightDiagonal(x,y,points);            if(win) return true;        }        return false;    }    /**     * 判断x,y位置的棋子,是否横向有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkHorizontal(int x, int y, List<Point> points) {        int count = 1;        //左        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否纵向有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkVertical(int x, int y, List<Point> points) {        int count = 1;        //上        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x,y-i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x,y+i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否左斜有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkLeftDiagonal(int x, int y, List<Point> points) {        int count = 1;        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y+i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y-i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    /**     * 判断x,y位置的棋子,是否右斜有相邻的五个一致。     * @param x     * @param y     * @param points     * @return     */    private boolean checkRightDiagonal(int x, int y, List<Point> points) {        int count = 1;        for(int i=0;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x-i,y-i))){                count++;            }else{                break;            }        }        if(count ==MAX_COUNT_IN_LINE) return true;        for(int i=1;i<MAX_COUNT_IN_LINE;i++){            if(points.contains(new Point(x+i,y+i))){                count++;            }else{                break;            }        }        if(count==MAX_COUNT_IN_LINE) return true;        return  false;    }    private void drawPieces(Canvas canvas) {        for(int i=0,n = mWhiteArray.size(); i< n ;i++){            Point whitePoint = mWhiteArray.get(i);            canvas.drawBitmap(mWhitePiece,                    (whitePoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (whitePoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }        for(int i=0,n = mBlackArray.size(); i< n ;i++){            Point blackPoint = mBlackArray.get(i);            canvas.drawBitmap(mBlackPiece,                    (blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }    }    private void drawPieces(Canvas canvas,int whiteCount,int blackCount) {        for(int i=0,n =whiteCount; i< n ;i++){            Point whitePoint = mWhiteArray.get(i);            canvas.drawBitmap(mWhitePiece,                    (whitePoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (whitePoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }        for(int i=0,n = blackCount; i< n ;i++){            Point blackPoint = mBlackArray.get(i);            canvas.drawBitmap(mBlackPiece,                    (blackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,                    (blackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);        }    }    private void drawBoard(Canvas canvas) {        /**         * 分析:根据棋盘的效果,我们知道棋子是下在边界的交叉点上的。可得棋盘中间有9个完整的lineHeight,         * 上下两边有半个lineHeight,总共10个lineHeight。左右也是。         */        int w = mPanelWidth;        float lineHeight = mLineHeight;        for(int i=0;i<MAX_LINE;i++){            int startX = (int) (lineHeight / 2);//起点坐标            int endX = (int) (w - lineHeight / 2);//终点坐标            int y = (int) ((0.5+i)*lineHeight);            canvas.drawLine(startX,y,endX,y,mPaint);            canvas.drawLine(y,startX,y,endX,mPaint);        }    }    /**再来一局*/    public void reStart(){        mWhiteArray.clear();        mBlackArray.clear();        mIsGameOver = false;        mIsWhiteWinner = false;        invalidate();    }    //是否悔棋。true悔棋,false不悔棋    private boolean isBlack = true;    //悔棋    public void goRegret(){        //棋盘上无子        if(mWhiteArray.size() == 0 && mBlackArray.size() == 0){            return;        }        //棋盘上有子        if(mIsWhite){//下一步白棋先手            //上一步黑棋可以悔棋            mBlackArray.remove(mBlackArray.size()-1);        }else{//下一步黑棋先手手            //上一步白棋可以悔棋            mWhiteArray.remove(mWhiteArray.size()-1);        }        mIsWhite = !mIsWhite;        mIsGameOver = true;        mIsWhiteWinner = false;        invalidate();        isBlack = !isBlack;    }    private static final String INSTANCE = "instance";    private static final String INSTANCE_GAME_OVER = "instance_game_over";    private static final String INSTANCE_WHITE_ARRAY = "instance_white_array";    private static final String INSTANCE_BLACK_ARRAY = "instance_black_array";    @Override    protected Parcelable onSaveInstanceState() {        Bundle bundle = new Bundle();        bundle.putParcelable(INSTANCE,super.onSaveInstanceState());        bundle.putBoolean(INSTANCE_GAME_OVER,mIsGameOver);        bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY,mWhiteArray);        bundle.putParcelableArrayList(INSTANCE_BLACK_ARRAY,mBlackArray);        return bundle;    }    @Override    protected void onRestoreInstanceState(Parcelable state) {        if(state instanceof Bundle){            Bundle bundle = (Bundle) state;            mIsGameOver = bundle.getBoolean(INSTANCE_GAME_OVER);            mWhiteArray = bundle.getParcelableArrayList(INSTANCE_WHITE_ARRAY);            mBlackArray = bundle.getParcelableArrayList(INSTANCE_BLACK_ARRAY);            super.onRestoreInstanceState(bundle.getParcelable(INSTANCE));            return ;        }        super.onRestoreInstanceState(state);    }}
MainActivity.java
package com.xbmu.wuziqi;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Button;public class MainActivity extends Activity {    private WuziqiPanel wuziqiPanel;    private Button btnRestart;    private Button btnRegret;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        wuziqiPanel  = (WuziqiPanel) findViewById(R.id.id_wuziqi);        btnRestart  = (Button) findViewById(R.id.btn_restart);        btnRegret = (Button) findViewById(R.id.btn_regret);        //再来一局        btnRestart.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                wuziqiPanel.reStart();            }        });        //我要悔棋        btnRegret.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                wuziqiPanel.goRegret();            }        });    }}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="@drawable/bg"    tools:context="com.xbmu.wuziqi.MainActivity">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="horizontal"        android:id="@+id/ll_top"        android:gravity="center">        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="再来一局"            android:id="@+id/btn_restart"/>        <Button            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:id="@+id/btn_regret"            android:text="我要悔棋"/>    </LinearLayout>    <com.xbmu.wuziqi.WuziqiPanel        android:id="@+id/id_wuziqi"        android:layout_marginTop="10dp"        android:layout_below="@id/ll_top"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_centerHorizontal="true" /></RelativeLayout>
运行效果:

感谢慕课网提供的教学资料,源码下载:http://download.csdn.net/detail/btt2013/9508584

更多相关文章

  1. Android TextView 一些字体颜色、大小设置属性
  2. Android Studio设置界面风格和字体大小
  3. android命名大小写问题
  4. android根据字体大小设置控件高度
  5. android sqilte3数据库大小的测试
  6. android默认字体大小、高度、宽度
  7. 修改dialog的大小
  8. android获取屏幕分辨率大小(DisplayMetrics)
  9. Android图片的固定大小显示

随机推荐

  1. Android(安卓)判断手机的Rom类型
  2. Android(安卓)获取播放视频的相关 内容,
  3. 一些常用SD卡操作的方法,APk管理之类的方
  4. android音量控制以及硬件同步
  5. Android(安卓)Bad notification for star
  6. Android调用自定义Dialog中的控件
  7. Android(安卓)Support Multidex原理分析
  8. android 调用系统日历
  9. android 图片叠加效果实现
  10. Android(安卓)发送通知 notification