??在這里說一下啊,我的所有文章都是根據(jù)看慕課上的視頻寫出來的眼滤,所以都不是原創(chuàng)的巴席,因為能力不夠。诅需。漾唉。。
??今天我在這里記一下诱担,五子棋的編寫方法毡证,歸根結底還是要到自定義View里面去。
??上面是一張我完成過后的截圖蔫仙,要完成這個功能料睛,必不可少的就是自定義控件。在此過程摇邦,我最主要的是要學習自定義控件的方法恤煞。
1.布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
tools:context="com.example.android_wuziqi.MainActivity">
<com.example.android_wuziqi.WuziqiView
android:id="@+id/id_wuziqiView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#44ff"
/>
</LinearLayout>
2.在自定義View當中,測量棋盤的大小
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
if (widthMode == MeasureSpec.UNSPECIFIED) {
widthSize = heightSize;
} else if (heightMeasureSpec == MeasureSpec.UNSPECIFIED) {
heightSize = widthSize;
}
int width = Math.min(widthSize, heightSize);
setMeasuredDimension(width, width);
}
??上面的代碼要注意的是:當我們父布局使用ScrollView時施籍,會發(fā)現(xiàn)有時候子空間取不到寬或者是高居扒,那是因為子控件的測量模式是UNSPECIFIED,因此在測量的時候丑慎,我們要考慮到這個問題喜喂。
3.在onSizechanged方法里面取得棋盤上每兩條邊之間的距離
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mLineHeight = (int) (w * 1.0f / MAX_LINE_COUNT);
int scaleWidth = (int) (mLineHeight * mRadioPieceOfLineHeight);
mBlackPiece = Bitmap.createScaledBitmap(mBlackPiece, scaleWidth, scaleWidth, false);
mWhitePiece = Bitmap.createScaledBitmap(mWhitePiece, scaleWidth, scaleWidth, false);
}
??Bitmap.createScaledBitmap主要是用來縮放bitmap的,因為棋子的大小由棋盤的邊之間的距離來決定竿裂。
4.繪制棋盤
private void drawBorad(Canvas canvas) {
int width = getMeasuredWidth();
for (int i = 0; i < MAX_LINE_COUNT; i++) {
float startX = (mLineHeight * 1.0f / 2);
float startY = (mLineHeight * 1.0f / 2) + mLineHeight * i;
float endX = (width - mLineHeight * 1.0f / 2);
float endY = mLineHeight / 2 + mLineHeight * i;
canvas.drawLine(startX, startY, endX, endY, mPaintLine);
canvas.drawLine(startY, startX, endY, endX, mPaintLine);
}
}
5.設置onTouchEvent事件
??在設置之前玉吁,先考慮一下,下棋的事件是定在DOWN還是UP里面腻异,具體原因我也不想去解釋进副,我在這里設置UP里面,因為教學視頻里面也是這樣的悔常,而我覺得挺不錯的影斑。
public boolean onTouchEvent(MotionEvent event) {
if(mIsGameOver)
{
return false;
}
switch (event.getAction()) {
case MotionEvent.ACTION_UP: {
int x = (int) event.getX();
int y = (int) event.getY();
Point point = getLeglaPoint(x, y);
if (mBlackArray.contains(point) || mWhiteArray.contains(point)) {
return false;
}
if (mIsWhite) {
mWhiteArray.add(point);
} else {
mBlackArray.add(point);
}
invalidate();
mIsWhite = !mIsWhite;
return true;
}
}
return true;
}
private Point getLeglaPoint(int x, int y) {
return new Point(x / mLineHeight, y / mLineHeight);
}
??這里注意一點的就是:當我們在某一個地方已經(jīng)下了棋子了给赞,如果再次點擊一次的話,不能將前面的棋子覆蓋了矫户。因此我們在這里必須有一個判斷片迅,那就是我們點擊的地方的是否有棋子。這里不是直接通過x和y來判斷的皆辽,因為每次點擊同一個地方障涯,x和y有一定的偏差。我們這里使用有x和y來整除邊之間的距離膳汪,這樣即使有偏差唯蝶,也是被忽略的。
6.畫棋子
private void drawPiece(Canvas canvas) {
for (int i = 0; i < mBlackArray.size(); i++) {
Point point = mBlackArray.get(i);
canvas.drawBitmap(mBlackPiece, (point.x + (1 - mRadioPieceOfLineHeight) / 2) * mLineHeight, (point.y + (1 - mRadioPieceOfLineHeight) / 2) * mLineHeight, mPaintBitmap);
}
for (int i = 0; i < mWhiteArray.size(); i++) {
Point point = mWhiteArray.get(i);
canvas.drawBitmap(mWhitePiece, (point.x + (1 - mRadioPieceOfLineHeight) / 2) * mLineHeight, (point.y + (1 - mRadioPieceOfLineHeight) / 2) * mLineHeight, mPaintBitmap);
}
}