主要实现简单的互动
主要代码:
package com.adolph.wuzhiqi;
import android.content.Context;
import android.content.pm.ProviderInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.text.style.TtsSpan;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2016/9/25.
*/
public class WuzhiqiPanel 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();//得到画笔
//BitMap代表一张位图
private Bitmap mWhitePiece;
private Bitmap mBlackPiece;
private float ratioPieceOfLineHeight = 3 * 1.0f /4;//设置棋子比例
//白棋先下
private boolean mIsWite = true;//标志那个棋子在下
private List<Point> mWiteArray = new ArrayList<>();
private List<Point> mBlackArray = new ArrayList<>();
private boolean mIsGameOver;
private boolean mIsWhiteWinner;
public WuzhiqiPanel(Context context, AttributeSet attrs){
super(context,attrs);
setBackgroundColor(0x44ff0000);
init();
}
//初始化画笔
private void init(){
//初始化棋盘
mPaint.setColor(0x8800000);//设置画笔颜色
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_b1);
}
//当控件的父元素正要放置该控件时调用,测量
/*支持match_parent*/
protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec)
{
//边界参数——widthMeasureSpec和heightMeasureSpec ,效率的原因以整数的方式传入。
//在它们使用之前,首先要做的是使用MeasureSpec类的静态方法getMode和getSize来译解
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int width = Math.min(widthSize,heightSize);//保证是正方形,取最小值作边
/*如果宽等于0就取高的值,如果高等于0就取宽的值*/
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);
}
//触发执行,绘制棋子
@Override
public boolean onTouchEvent(MotionEvent event) {
//游戏结束,表示不感兴趣
if (mIsGameOver) return false;
//得到这个事件
int action = event.getAction();
/*ACTION_UP,ACTION_DOWN,ACTION_CANCEL,ACTION_MOVE*/
if (action == MotionEvent.ACTION_UP){
//得到点击的坐标
int x = (int)event.getX();
int y = (int)event.getY();
//处理点击误差
Point p = getValidPoint(x,y);
//判断当前位置是否有棋子
if (mWiteArray.contains(p)||mBlackArray.contains(p)){
return false;
}
//Point p = new Point(x,y);
if (mIsWite){
mWiteArray.add(p);
}else {
mBlackArray.add(p);
}
//重绘
invalidate();
mIsWite = !mIsWite;
}
return true;//表明对事件感兴趣
}
private Point getValidPoint(int x, int y) {
return new Point((int)(x/mlineHeight),(int)(y/mlineHeight));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawBoard(canvas);
drawPieces(canvas);
CheckGameOvwe();
}
private void CheckGameOvwe() {
//判断白棋是否赢了
boolean whiteWin = checkFiveInLine(mWiteArray);
//判断黑棋是否赢了
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;
win = checkHorizontal(x,y,points);
if (win) return true;
win = checkLeftDiagonal(x,y,points);
if (win) return true;
win = checkRightDiagonal(x,y,points);
if (win) return true;
win = checkVertical(x,y,points);
if (win) 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;
else 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;
else 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;
else return false;
}
private boolean checkRightDiagonal(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;
else return false;
}
//绘制棋子
private void drawPieces(Canvas canvas) {
for (int i=0,n=mWiteArray.size(); i<n; i++){
//取出棋子
Point whitePoint = mWiteArray.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++){//绘制10行
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);
}
}
}