安卓项目五子棋代码详解(一)

 

暑假一时心血来潮,就是做了一个五子棋的安卓开发项目,个人感觉从中学到了许多,也是把开发的经验写出来,方便以后自己复习,也方便他人学习~~
 

      废话不多说,先来张已经完成的图片——

 



我设计了一个更换背景的功能,以下是更换背景之后的图片——

 

好啦,那接下来就是进入正题——


界面的这些先放到一边,五子棋主要核心是实现能够下棋,能够判断输赢,我的这个项目还是简单的单人游戏,适合自己一个人玩耍五子棋安卓开发详细解析(一)五子棋安卓开发详细解析(一),我就先说明核心的部分,其他的功能之后一步步的讲解。

首先就是要实现一个自定义View,新建一个Pannel类,让其继承View,并一个生成带参数的构造方法


之后,在构造方法中调用一个init()方法

public Panel(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();//调用init()方法
    }

接下来我们定义一个init()方法,这个方法主要用来设置画笔的一些相关属性和初始化棋子图片资源并改其大小,init()方法定义如下

 

private void init() {
        paint.setColor(Color.BLACK);//设置画笔颜色为黑色
        paint.setAntiAlias(true);//开启抗锯齿功能
        paint.setDither(true);//使用图像抖动处理
        paint.setStyle(Paint.Style.STROKE);//只绘制图形轮廓(描边)
        
        Whitepiece = BitmapFactory.decodeResource(getResources(), R.drawable.stone_w2);//初始化白色棋子图片
        Blackpiece = BitmapFactory.decodeResource(getResources(), R.drawable.stone_b1);//初始化黑色棋子图片
    }

 

补充:

  paint.setStyle中可选择有三种选择:

  1. Paint.Style.STROKE 只绘制图形轮廓(描边)
  2. Paint.Style.FILL 只绘制图形内容
  3. Paint.Style.FILL_AND_STROKE 既绘制轮廓也绘制内容

  paint.setDither()方法的意义:

  设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰

  paint.setAntiAlias的意义:
  设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢
  

之后,重写ondraw方法,这个方法就是五子棋核心的方法,是用来画棋盘和棋子

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        drawBoard(canvas);//画棋盘
        drawPiece(canvas);//画棋子
        checkGameover();//检查游戏是否结束
        
    }

可以看到,我在onDraw()方法里面中调用了一个checkGameOver()方法,这个方法就是字面意思,用来检查游戏是否结束,结束了就可以停止onDraw方法,也就是用户触摸后,paint不会再绘制棋子来,游戏结束了还能绘制棋子,这个想想就有些不科学,是吧?这也就是这个checkGameOver()方法存在的意义

 

 

除此之外,还需要重写一个onTouchEvent()方法,这个方法用来判断当前用户手指触摸状态并实现下棋(也就是在棋盘中绘制棋子)的功能,有了这个办法,便能与onDraw()方法联系起来。

详细地解释为,判断用户的手指交互状态,并获取用户手指触摸处的坐标,将坐标放置到一个数组(也可以说是点集合)中,之后由onDraw()方法中的drawPiece()方法获取数组中的坐标,在坐标出将棋子绘制出来

onTouchEvent()方法代码如下:

@Override
    public boolean onTouchEvent(MotionEvent event) {
        if(IsGameOver){
            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(Whitearray.contains(p)|| Blackarray.contains(p)){
                return false;
            }
            if(IsWhite){
                Whitearray.add(p);
                
            }else{
                Blackarray.add(p);
            }
            invalidate(); //invalidate()是用来刷新View的,必须在UI线程中
            IsWhite = !IsWhite;
        }
        return true;
    }

 

MotionEvent后可以选择的状态有很多,有单点触摸向下(ACTION_DOWN),单点触摸向上(ACTION_UP)等等,这里选择了单点触摸向上的状态,原因为有着更高的交互性和逻辑性,我们可以做一个假设,如果用户下到的时候,忽然发觉自己下错地方了,但是他的手指还是在屏幕上的,如果我们选择了单点触摸向下的这个状态,用户的手指一触摸到屏幕,棋子就已经落下(绘制)了,这样子的话不就会让用户体验变差了吗?但是,如果我们选择了单点触摸向上,也就是在用户手指松开的时候才绘制棋子,那么上面的情景就是得以很好的解决,用户只需要在屏幕上移动手指,到了合适位置松开手指便是可以落子。
呃……是不是说太多口水话了??好吧,反正也就是我自己看,没事。
看了一下下面的代码,感觉没有什么好说的了,就这样了

 第一期我解释的主要是五子棋项目的主要方法,理清它们之间的关系,之后都是好理解了。
我自己感觉这样方法的话有助于加深理解,不然你直接去看一个项目,N多方法看了半天都是理不清其中的关系,看得心又累,眼又累……


这一期便是到这里了,下一期再继续详细解析,感谢观看!!(如果有人看的话……<( ̄ˇ ̄)/)

 

posted @ 2017-07-31 21:16  Stars-one  阅读(2873)  评论(0编辑  收藏  举报