本文实例为大家分享了AndroID五子棋游戏的具体代码,供大家参考,具体内容如下
1、效果图:
2、GobangPanel棋盘面板:
public class GobangPanel extends VIEw { private int mPanelWIDth;//棋盘的宽度 private float mlineHeight;//行,高要为float private int MAX_liNE = 15;//棋盘行数 private int MAX_COUNT_IN_liNE = 5;//设置赢棋子个数(6子棋设置为6) private Paint mPaint = new Paint();//画笔 private Bitmap mWhitePIEce;//白色棋子 private Bitmap mBlackPIEce;//黑色棋子 private float ratioPIEceOflineHeight = 3 * 1.0f / 4;//2个棋子间3/4距离 //白旗先手,当前轮到白棋了 private boolean mIsWhite = true; private ArrayList<Point> mWhiteArray = new ArrayList<>();//白棋数组 private List<Point> mBlackArray = new ArrayList<>();//黑骑数组 private boolean mIsGameOver;//游戏是否结束 private boolean mIsWhiteWinner;//白色棋子赢 true白子赢,false黑色赢 public GobangPanel(Context context,AttributeSet attrs) { super(context,attrs); init(); } /** * 初始化画笔参数 */ private voID init() { mPaint.setcolor(0x88000000);//Paint颜色 半透明灰色 mPaint.setAntiAlias(true);//抗锯齿(边界明显变模糊) mPaint.setDither(true);//设置防抖动(图片柔和) mPaint.setStyle(Paint.Style.stroke);//样式 //黑、白棋资源图片 mWhitePIEce = BitmapFactory.decodeResource(getResources(),R.mipmap.white_bg); mBlackPIEce = BitmapFactory.decodeResource(getResources(),R.mipmap.black_bg); } /** * 自定义view尺寸的规则 */ protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) { //宽和高 int wIDthSize = MeasureSpec.getSize(wIDthMeasureSpec); int wIDthMode = MeasureSpec.getMode(wIDthMeasureSpec); int heightSize = MeasureSpec.getSize(heightmeasureSpec); int heightmode = MeasureSpec.getMode(heightmeasureSpec); int wIDth = Math.max(wIDthSize,heightSize); //最大值 if (wIDthMode == MeasureSpec.UnspecIFIED) { wIDth = heightSize; } else if (heightmode == MeasureSpec.UnspecIFIED) { wIDth = wIDthSize; } setMeasuredDimension(wIDth,wIDth); } /** * 控件大小发生改变时调用 */ 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,false);//棋子跟随控件变化 mBlackPIEce = Bitmap.createScaledBitmap(mBlackPIEce,false); } //触摸焦点 public boolean ontouchEvent(MotionEvent event) { if (mIsGameOver) return false; int action = event.getAction(); if (action == MotionEvent.ACTION_UP) { 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;//感兴趣交给其处理 } private Point getValIDPoint(int x,int y) { return new Point((int) (x / mlineHeight),(int) (y / mlineHeight)); } protected voID onDraw(Canvas canvas) { super.onDraw(canvas); drawBoard(canvas); drawPIEces(canvas); checkGameOver(); } private static final String TAG = "GobangPanel"; /** * 游戏结束方法 */ public voID checkGameOver() { boolean whiteWin = checkFiveInline(mWhiteArray); boolean blackWin = checkFiveInline(mBlackArray); //黑棋或白棋赢游戏结束 if (whiteWin || blackWin) { mIsGameOver = true; mIsWhiteWinner = whiteWin; if (null != Listener) { Listener.onFinish(mIsWhiteWinner); Log.e(TAG,"checkGameOver: 111111" ); } Log.e(TAG,"checkGameOver: 222222" ); } } /** * 判断棋子是否5个相邻【5个相连只有4中情况分别是:水平、垂直、左斜和右斜】 */ private boolean checkFiveInline(List<Point> points) { for (Point p : points) { int x = p.x; int y = p.y; boolean win = checkLevel(x,y,points); if (win) return true; win = checkVetical(x,points); if (win) return true; win = checkleftWin(x,points); if (win) return true; win = checkRightWin(x,points); if (win) return true; } return false; } /** * 判断x,y位置的棋子是否【水平】有相邻的五个一致 */ private boolean checkLevel(int x,int y,List<Point> points) { int count = 1; //横向左边棋子个数 for (int i = 1; i < MAX_COUNT_IN_liNE; i++) { //如果有加1,没有重新计算是否有五个,否者中断 if (points.contains(new Point(x - i,y))) { count++; } else { break; } } //有5个时则赢 if (count == MAX_COUNT_IN_liNE) return true; //横向右边棋子个数 for (int i = 1; i < MAX_COUNT_IN_liNE; i++) { //如果有加1,否者中断 if (points.contains(new Point(x + i,y))) { count++; } else { break; } } //有5个时则赢 if (count == MAX_COUNT_IN_liNE) return true; return false; } /** * 判断x,y位置的棋子是否[垂直]有相邻的五个一致 */ private boolean checkVetical(int x,List<Point> points) { int count = 1; //上下棋子个数 for (int i = 1; i < MAX_COUNT_IN_liNE; i++) { //如果有加1,否者中断 if (points.contains(new Point(x,y - i))) { count++; } else { break; } } //有5个时则赢,return true; if (count == MAX_COUNT_IN_liNE) return true; for (int i = 1; i < MAX_COUNT_IN_liNE; i++) { //如果有加1,y + i))) { count++; } else { break; } } //有5个时则赢 if (count == MAX_COUNT_IN_liNE) return true; return false; } /** * 判断x,y位置的棋子是否【左斜和右斜】有相邻的五个一致 */ private boolean checkleftWin(int x,List<Point> points) { int count = 1; //横向上下棋子个数 for (int i = 1; i < MAX_COUNT_IN_liNE; i++) { //如果有加1,y + i))) { count++; } else { break; } } //有5个时则赢,y - i))) { count++; } else { break; } } //有5个时则赢 if (count == MAX_COUNT_IN_liNE) return true; return false; } /** * 判断x,y位置的棋子是否【右斜】有相邻的五个一致 */ private boolean checkRightWin(int x,List<Point> points) { int count = 1; //横向上下棋子个数 for (int i = 1; i < MAX_COUNT_IN_liNE; i++) { //如果有加1,y + i))) { count++; } else { break; } } //有5个时则赢 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) { 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,endX,mPaint); canvas.drawline(y,startx,mPaint); } } /** * 再来一局 */ public voID start() { if (null != mWhiteArray && null != mBlackArray) { mWhiteArray.clear();//清除数据 mBlackArray.clear(); } mIsGameOver = false; mIsWhiteWinner = false; invalIDate(); //再次调用 } /** * 后台运行时,调用此方法,防止数据丢失 */ 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"; /** * 保存数据 */ 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,mWhiteArray); return bundle; } /** * 恢复时调用 */ 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); } /** * 游戏结束回调 */ public OnFinishListener Listener; public voID setListener(OnFinishListener Listener) { this.Listener = Listener; } public interface OnFinishListener { voID onFinish(boolean mIsWhiteWinner); }}
3、使用MainActivity
public class MainActivity extends AppCompatActivity { private GobangPanel panel; protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_main); panel = this.findVIEwByID(R.ID.gobang_panel); panel.setListener(new GobangPanel.OnFinishListener() { @OverrIDe public voID onFinish(boolean mIsWhiteWinner) { initDialog(mIsWhiteWinner); } }); } /** * 初始化d框 */ private voID initDialog(boolean mIsWhiteWinner) { AlertDialog dialog = new AlertDialog.Builder(this) //.setTitle("这是标题") .setMessage(mIsWhiteWinner ? "白棋胜利,是否重新开始?" : "黑棋胜利,是否重新开始?") //.setIcon(R.mipmap.ic_launcher) .setPositivebutton("确定",new DialogInterface.OnClickListener() {//添加"Yes"按钮 @OverrIDe public voID onClick(DialogInterface dialogInterface,int i) { panel.start(); } })// .setNegativebutton("取消",new DialogInterface.OnClickListener() {//添加取消// @OverrIDe// public voID onClick(DialogInterface dialogInterface,int i) {// Toast.makeText(MainActivity.this,"这是取消按钮",Toast.LENGTH_SHORT).show();// }// }) //方法一:setCanceledOntouchOutsIDe(false);按对话框以外的地方不起作用。按返回键起作用 //方法二:setCanceleable(false);按对话框以外的地方不起作用。按返回键也不起作用 .setCancelable(false) .create(); dialog.show(); }}
对应布局文件:activity_main:
<horizontalscrollview 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="#fff" tools:context=".MainActivity"> <ScrollVIEw androID:layout_wIDth="match_parent" androID:layout_height="match_parent"> <com.helloworld.game.GobangPanel androID:ID="@+ID/gobang_panel" androID:layout_wIDth="1000dp" androID:layout_height="1000dp" androID:layout_centerInParent="true" /> </ScrollVIEw></horizontalscrollview>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
总结以上是内存溢出为你收集整理的Android自定义View实现五子棋游戏全部内容,希望文章能够帮你解决Android自定义View实现五子棋游戏所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)