安卓开发之五子棋

昨天心血来潮做了一个手机移动小游戏–五子棋,现在过来做个技术总结。
开发工具 Android studio
首先在网络上下载一些自己喜欢的图片(后面会用到布局背景,棋子背景上面)
第一步,创建一个android项目,里面xml文件代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@drawable/bg"
    tools:context="com.dahuijii.liziguo.wuziqi.MainA_wuziqictivity">

    <com.dahuijii.liziguo.wuziqi.wuziqiPanel
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        />

</LinearLayout>

其中主程序wuziqi.Java文件不做任何修改
新创建的wuziqiPane.Java文件程序如下

package com.dahuijii.liziguo.wuziqi;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Size;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;
public class wuziqiPanel extends View {
    private int mPanelWidth;
    private float mLineHeight;
    private int MAX_LINE=10;
    private int MAX_COUNT_IN_LINE=5;
    private Paint mPaint=new Paint();
    private Bitmap mBlackPiece;
    private Bitmap mWhitePiece;
    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;

    public wuziqiPanel(Context context, @Nullable 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_b2);
    }
 @Override   //测量的方法
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        int widthSize=MeasureSpec.getSize(widthMeasureSpec);
        int widthMode=MeasureSpec.getMode(widthMeasureSpec);

        int heightSize=MeasureSpec.getSize(widthMeasureSpec);
        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);

    }

    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 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_SHORT).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=checkRightDiagnoal(x,y,points);
            if(win) return true;

        }
        return false;
    }

    private boolean checkRightDiagnoal(int x, int y, List<Point> points) {
        int count=1;
        //右上
        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;
        //左下
        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 boolean checkLeftDiagonal(int x, int y, List<Point> points) {
        int count=1;
        //左上
        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;
        //右下
        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 boolean checkVertical(int x, int y, List<Point> points) {
        int count=1;
        //上
        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;
        //下
        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;
    }
private boolean checkHorizontal(int x, int y, List<Point> points) {
        int count=1;
        //左
        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;
        //右
        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;
    }

    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,y,endx,y,mPaint);
            canvas.drawLine(y,startx,y,endx,mPaint);
        }
    }

}

测试中出现的问题:
真机运行老是出现闪退现象:后面发现这是因为图片资源放错位置导致,在drawable文件夹中放的文件有时候会默认存储为xx.png(v-24),这时候就要重新放置文件,确保不是放在隐藏文件夹drawable-v24下。
项目运行文件冲突问题:我一方面建了一个项目运行这个程序,另一方面我在module组件下也建立了这样一个程序。导致程序运行时会发生不必要的冲突。

最后我做的五子棋demo如下展示:

12

发布了45 篇原创文章 · 获赞 23 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览