admin 管理员组

文章数量: 1087678

安卓开发之五子棋

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android=""xmlns:app=""xmlns: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.wuziqiPanelandroid: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);//确保图形为正方形}@Overrideprotected 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如下展示:

本文标签: 安卓开发之五子棋