自定义view二五子棋分析.docx

上传人:b****1 文档编号:14283012 上传时间:2023-06-22 格式:DOCX 页数:18 大小:141.69KB
下载 相关 举报
自定义view二五子棋分析.docx_第1页
第1页 / 共18页
自定义view二五子棋分析.docx_第2页
第2页 / 共18页
自定义view二五子棋分析.docx_第3页
第3页 / 共18页
自定义view二五子棋分析.docx_第4页
第4页 / 共18页
自定义view二五子棋分析.docx_第5页
第5页 / 共18页
自定义view二五子棋分析.docx_第6页
第6页 / 共18页
自定义view二五子棋分析.docx_第7页
第7页 / 共18页
自定义view二五子棋分析.docx_第8页
第8页 / 共18页
自定义view二五子棋分析.docx_第9页
第9页 / 共18页
自定义view二五子棋分析.docx_第10页
第10页 / 共18页
自定义view二五子棋分析.docx_第11页
第11页 / 共18页
自定义view二五子棋分析.docx_第12页
第12页 / 共18页
自定义view二五子棋分析.docx_第13页
第13页 / 共18页
自定义view二五子棋分析.docx_第14页
第14页 / 共18页
自定义view二五子棋分析.docx_第15页
第15页 / 共18页
自定义view二五子棋分析.docx_第16页
第16页 / 共18页
自定义view二五子棋分析.docx_第17页
第17页 / 共18页
自定义view二五子棋分析.docx_第18页
第18页 / 共18页
亲,该文档总共18页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

自定义view二五子棋分析.docx

《自定义view二五子棋分析.docx》由会员分享,可在线阅读,更多相关《自定义view二五子棋分析.docx(18页珍藏版)》请在冰点文库上搜索。

自定义view二五子棋分析.docx

自定义view二五子棋分析

自定义view

(二)五子棋

画棋盘

首先自定义view的四部曲

1,在attrs中申明自定义的属性

2,在View的构造方法中获得我们自定义的属性

3,重写onMeasure方法

4,重写ondraw方法

五子棋的自定义属性我都写死了,也可以不写死,写在attrs中动态的改变,这样都可以

生成构造方法

publicWuZiQiView(Contextcontext,AttributeSetattrs){

super(context,attrs);

//设置一个背景颜色用来区分我们自定义的view的大小最后的时候去掉

setBackgroundColor(0x44ff0000);

init();

}

//棋盘的线条数

privateintmaxline=10;

//棋盘的宽度

privateintmpanelWidth;

//每一行的高度

privatefloatmLineHeight;

//新建一只画棋盘的画笔

privatePaintmPaint=newPaint();

重写onmeasure方法

@Override

protectedvoidonMeasure(intwidthMeasureSpec,intheightMeasureSpec){

intheightSize=MeasureSpec.getSize(heightMeasureSpec);

intheightMode=MeasureSpec.getMode(heightMeasureSpec);

intwidthSize=MeasureSpec.getSize(widthMeasureSpec);

intwidthMode=MeasureSpec.getMode(widthMeasureSpec);

//取view的宽度

intwidth=Math.min(widthSize,heightSize);

if(heightMode==MeasureSpec.UNSPECIFIED){

//测量模式为不确定的时候也取view的宽度

width=widthSize;

}elseif(widthMode==MeasureSpec.UNSPECIFIED){

width=heightSize;

}

//设置自定义view的宽度和高度

setMeasuredDimension(width,width);

}

获取棋盘的高度

@Override

protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){

super.onSizeChanged(w,h,oldw,oldh);

//设置view的宽度为棋盘的宽度

mpanelWidth=w;

//获取每一行的宽度=棋盘的宽度/行数

mLineHeight=mpanelWidth*1.0f/maxline;

}

重写ondraw方法

@Override

protectedvoidonDraw(Canvascanvas){

super.onDraw(canvas);

//画棋盘

doawBoard(canvas);

}

//初始化画笔

privatevoidinit(){

//设置颜色

mPaint.setColor(0x88000000);

//抗锯齿

mPaint.setAntiAlias(true);

//防抖动

mPaint.setDither(true);

//Paint.Style.STROKE仅描边

mPaint.setStyle(Paint.Style.STROKE);

}

privatevoiddoawBoard(Canvascanvas){

intw=mpanelWidth;

intLineHeight=(int)mLineHeight;

for(inti=0;i

//不能从起点开始画,因为我们还需要放置旗子,所以这里取行宽的2分之1

intstartX=(int)(mLineHeight/2);

intendX=(int)(w-mLineHeight/2);

//Y坐标根据行数进行变化

inty=(int)((0.5+i)*LineHeight);

canvas.drawLine(startX,y,endX,y,mPaint);

canvas.drawLine(y,startX,y,endX,mPaint);

}

}

画棋子

首先在网上找俩张资源图,棋子的,放在drawble中

首先初始化它

privatevoidinit(){

mPaint.setColor(0x88000000);

mPaint.setAntiAlias(true);

mPaint.setDither(true);

mPaint.setStyle(Paint.Style.STROKE);

//根据资源文件获取白棋黑棋对应的bitmap

mWhitePiece=BitmapFactory.decodeResource(getResources(),R.drawable.stone_w2);

mBlancPiece=BitmapFactory.decodeResource(getResources(),R.drawable.stone_b1);

}

画棋子大概的思路如下

俩个list用来存取2种颜色的棋子的坐标,用一个常量区分当前是下白子还是黑子,重写ontouchevent方法,在手势抬起的时候绘制棋子,之所以不是手势按下就绘制就考虑到玩家按下后平移,但是发现棋子已经绘制好了,所以把棋子的绘制放在手势抬起的时候

//白棋

privateBitmapmWhitePiece;

//黑棋

privateBitmapmBlancPiece;

//百分比用来设置棋子的宽度

privatefloatratioPieceOfLineHeight=1.0f*3/4;

//常量用来区分当前的状态

privatebooleanmeisWhite=false;

//存放白棋坐标的list

privateArrayListmWhiteList=newArrayList<>();

//存放黑棋坐标的list

privateArrayListmBlackList=newArrayList<>();

//获取棋子的宽度

@Override

protectedvoidonSizeChanged(intw,inth,intoldw,intoldh){

super.onSizeChanged(w,h,oldw,oldh);

mpanelWidth=w;

mLineHeight=mpanelWidth*1.0f/maxline;

//棋子的宽度去行宽的3/4

intpipcewidth=(int)(mLineHeight*ratioPieceOfLineHeight);

//根据棋子的宽度重新定制棋子的大小和尺寸

mWhitePiece=Bitmap.createScaledBitmap(mWhitePiece,pipcewidth,pipcewidth,false);

mBlancPiece=Bitmap.createScaledBitmap(mBlancPiece,pipcewidth,pipcewidth,false);

}

@Override

publicbooleanonTouchEvent(MotionEventevent){

if(mIsGameOver){

returnfalse;

}

intaction=event.getAction();

if(action==MotionEvent.ACTION_UP){

//记录手势的坐标并且将坐标存在list中

intx=(int)event.getX();

inty=(int)event.getY();

//使用系统自带的point类,用来存放x,y

Pointp=getVaildPoint(x,y);

//避免重复绘制

if(mWhiteList.contains(p)||mBlackList.contains(p)){

returnfalse;

}

//用一个常量来区分当前下的棋子是白色还是黑色

if(meisWhite){

mWhiteList.add(p);

}else{

mBlackList.add(p);

}

//刷新界面

invalidate();

//每次都取反,这样白子和黑子一人一轮

meisWhite=!

meisWhite;

}

returntrue;

 

}

//获取棋子的坐标

privatePointgetVaildPoint(intx,inty){

returnnewPoint((int)(x/mLineHeight),(int)(y/mLineHeight));

}

 

@Override

protectedvoidonDraw(Canvascanvas){

super.onDraw(canvas);

doawBoard(canvas);

//画棋子

drawPiece(canvas);

}

 

privatevoiddrawPiece(Canvascanvas){

//根据存放的list的大小绘制棋子

for(inti=0;i

PointwhitePoint=mWhiteList.get(i);

//画棋子,棋子的坐标加上行宽的1/8,保持绘制的棋子处于线条交叉正中心的位置

canvas.drawBitmap(mWhitePiece,(whitePoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,(whitePoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,ull);

}

for(inti=0;i

PointmBlackPoint=mBlackList.get(i);

canvas.drawBitmap(mBlancPiece,(mBlackPoint.x+(1-ratioPieceOfLineHeight)/2)*mLineHeight,(mBlackPoint.y+(1-ratioPieceOfLineHeight)/2)*mLineHeight,null);

}

}

检查游戏是否结束

最后检查游戏的结束状态

//是否是白棋胜利

privatebooleanmisWhiteWinner;

//游戏是否结束

privatebooleanmIsGameOver;

//同色的相邻棋子最大数

privateintMaxCountLine=5;

@Override

protectedvoidonDraw(Canvascanvas){

super.onDraw(canvas);

doawBoard(canvas);

drawPiece(canvas);

/检查游戏是否结束

checkGameOver();

}

privatevoidcheckGameOver(){

//检查的逻辑算法

booleanwhiteWin=checkFiveInLine(mWhiteList);

booleanblackWin=checkFiveInLine(mBlackList);

if(whiteWin||blackWin){

mIsGameOver=true;

misWhiteWinner=whiteWin;

//弹出toast

Stringtext=misWhiteWinner?

"白棋胜利":

"黑期胜利";

Toast.makeText(getContext(),text,Toast.LENGTH_SHORT).show();

//游戏结束后弹出对话框,

AlertDialog.BuilderalertDialog=newAlertDialog.Builder(getContext());

alertDialog.setTitle("游戏结束").setMessage("在来一局吗").setPositiveButton("确定",newDialogInterface.OnClickListener(){

@Override

publicvoidonClick(DialogInterfacedialog,intwhich){

//重置游戏

reStart();

}

}).setNegativeButton("取消",newDialogInterface.OnClickListener(){

@Oride

publicvoidonClick(DialogInterfacedialog,intwhich){

}

}).show();

}

}

检查的逻辑算法:

再用户当前放置棋子的坐标开始判断,横,竖,左斜,右斜,进行5次循环判断,判断list中是否存在有相邻的棋子,如果有则用index++,当index达到5的时候代表游戏结束

privatebooleancheckFiveInLine(Listpoints){

for(Pointpoint:

points){

intx=point.x;

inty=point.y;

booleanhorizontalwin=checkHorizontal(x,y,points);

booleanverticalwin=checkvertical(x,y,points);

booleanleftwin=checkleftDiagonal(x,y,points);

booleanrightwin=checkRightDigonal(x,y,points);

if(horizontalwin||verticalwin||leftwin||rightwin){

returntrue;

}

}

returnfalse;

}

privatebooleancheckvertical(intx,inty,Listpoints){

intcount=1;

for(inti=1;i

if(points.contains(newPoint(x,y+i))){

count++;

}else{

break;

}

}

if(count==MaxCountLine){

returntrue;

}

for(inti=1;i

if(points.contains(newPoint(x,y-i))){

count++;

}else{

break;

}

}

if(count==MaxCountLine){

returntrue;

}

returnfalse;

}

privatebooleancheckleftDiagonal(intx,inty,Listpoints){

intcount=1;

for(inti=1;i

if(points.contains(newPoint(x-i,y+i))){

count++;

}else{

break;

}

}

if(count==MaxCountLine){

returntrue;

}

for(inti=1;i

if(points.contains(newPoint(x+i,y-i))){

count++;

}else{

break;

}

}

if(count==MaxCountLine){

returntrue;

}

returnfalse;

}

privatebooleancheckRightDigonal(intx,inty,Listpoints){

intcount=1;

for(inti=1;i

if(points.contains(newPoint(x+i,y+i))){

count++;

}else{

break;

}

}

if(count==MaxCountLine){

returntrue;

}

for(inti=1;i

if(points.contains(newPoint(x-i,y-i))){

count++;

}else{

break;

}

}

if(count==MaxCountLine){

returntrue;

}

returnfalse;

}

/**

*检查横向的是否胜利

*

*@paramx

*@paramy

*@parampoints

*/

privatebooleancheckHorizontal(intx,inty,Listpoints){

intcount=1;

//左边

for(inti=1;i

if(points.contains(newPoint(x-i,y))){

count++;

}else{

break;

}

}

if(count==MaxCountLine){

returntrue;

}

for(inti=1;i

if(points.contains(newPoint(x+i,y))){

count++;

}else{

break;

}

}

if(count==MaxCountLine){

returntrue;

}

returnfalse;

}

重置的代码

publicvoidreStart(){

//清楚所有的list

mWhiteList.clear();

mBlackList.clear();

//标识位恢复

mIsGameOver=false;

misWhiteWinner=false;

invalidate();

}

屏幕状态改变后,保存当前的棋盘信息

privatestaticfinalStringINSTANCE="instance";//主标识,用来存放super

//存放游戏是否结束

privatestaticfinalStringINSTANCE_GAME_OVER="instance_game_over";

//存放当前轮到什么颜色的棋子下

privatestaticfinalStringINSTANCE_ME_ISWHITE="instance_me_iswhite";

//存放白棋的list

privatestaticfinalStringINSTANCE_WHITE_ARRAY="instance_white_array";

privatestaticfinalStringINSTANCE_BLACK_ARRAY="instance_black_array";

//重写,存储

@Override

protectedParcelableonSaveInstanceState(){

Bundlebundle=ewBundle();

bundle.putParcelable(INSTANCE,super.onSaveInstanceState());

bundle.putBoolean(INSTANCE_GAME_OVER,mIsGameOver);

bundle.putBoolean(INSTANCE_ME_ISWHITE,meisWhite);

bundle.putParcelableArrayList(INSTANCE_WHITE_ARRAY,mWhiteList);

bundle.putParcelableArrayList(INSTANCE_BLACK_ARRAY,mBlackList);

returnbundle;

}

//恢复

@Override

protectedvoidonRestoreInstanceState(Parcelablestate){

if(stateinstanceofBundle){

Bundlebundle=(Bundle)state;

mIsGameOver=bundle.getBoolean(INSTANCE_GAME_OVER);

mBlackList=bundle.getParcelableArrayList(INSTANCE_BLACK_ARRAY);

mWhiteList=bundle.getParcel

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2