Android實(shí)現(xiàn)連連看游戲
本文實(shí)例為大家分享了Android實(shí)現(xiàn)連連看游戲的具體代碼,供大家參考,具體內(nèi)容如下
本人用 android studio 實(shí)現(xiàn)的
源碼
主活動(dòng) 類:
package packageName; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.LinearLayout; import MaView; public class MainActivity extends AppCompatActivity { ? ? @Override ? ? protected void onCreate(Bundle savedInstanceState) { ? ? ? ? super.onCreate(savedInstanceState); ? ? ? ? setContentView(R.layout.activity_main); ? ? ? ? ViewGroup.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); ? ? ? ? final MaView mainView = new MaView(this); ? ? ? ? addContentView(mainView, params); ? ? ? ? // 添加三個(gè)按鈕執(zhí)行相應(yīng)的方法 ? ? ? ? Button btn = new Button(this); ? ? ? ? btn.setText("新游戲"); ? ? ? ? btn.setTextSize(20); ? ? ? ? btn.setX(40); ? ? ? ? btn.setY(40); ? ? ? ? btn.setOnClickListener(new View.OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? mainView.newGame(); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? addContentView(btn, params); ? ? ? ? Button tipBtn = new Button(this); ? ? ? ? tipBtn.setText("提示"); ? ? ? ? tipBtn.setTextSize(20); ? ? ? ? tipBtn.setX(380); ? ? ? ? tipBtn.setY(40); ? ? ? ? tipBtn.setOnClickListener(new View.OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? mainView.getTip(); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? addContentView(tipBtn, params); ? ? ? ? Button resetBtn = new Button(this); ? ? ? ? resetBtn.setText("重置"); ? ? ? ? resetBtn.setTextSize(20); ? ? ? ? resetBtn.setX(720); ? ? ? ? resetBtn.setY(40); ? ? ? ? resetBtn.setOnClickListener(new View.OnClickListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public void onClick(View v) { ? ? ? ? ? ? ? ? mainView.reset(); ? ? ? ? ? ? } ? ? ? ? }); ? ? ? ? addContentView(resetBtn, params); ? ? } }
MaView 類
package packageName; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Picture; import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.PictureDrawable; import android.os.Build; import android.support.annotation.RequiresApi; import android.transition.Explode; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.Toast; import java.util.Random; import java.util.Timer; import java.util.TimerTask; public class MaView extends View { ? ? // 連連看規(guī)則: 在一個(gè)方形有若干個(gè)格子,當(dāng)選擇其中的兩個(gè)格子時(shí),存在以下幾種連線關(guān)系時(shí)就會(huì)被消滅 ? ? // 連線只有水平和垂直方向 ? ? // 1, 其水平或垂直方向相同,并且兩個(gè)格子之間無其它非空格子的直線關(guān)系 ? ? // 2, 有一個(gè)折點(diǎn)的 一折點(diǎn)關(guān)系 ? ? // 3, 有兩個(gè)折點(diǎn)的 二折點(diǎn)關(guān)系 ? ? // 左邊距 ? ? public static final int MARGINLEFT = 40; ? ? // 上邊距 ? ? public static final int MARGINTOP = 400; ? ? // 格子的行列數(shù) ? ? public static final int ROW = 10; ? ? // 格子的寬高 ? ? public static final int W = 100; ? ? // 圖片的寬高 ? ? public static final int IMGW = 90; ? ? // 格子為空 ? ? public static final int NULL = -1; ? ? // 連接狀態(tài)為 直線 ? ? public static final int STRAIGHT = 1; ? ? // 連接狀態(tài)為 一折點(diǎn) ? ? public static final int ONELINK = 2; ? ? // 連接狀態(tài)為 二折點(diǎn) ? ? public static final int TWOLINK = 3; ? ? // 格子的種類數(shù) ? ? public static final int L = 25; ? ? // 存放格子信息的地圖 ? ? private int[] map = new int[ROW * ROW]; ? ? // 存放格子的圖片 ? ? private Bitmap[] imgs = new Bitmap[L]; ? ? // 判斷觸屏事件是否為點(diǎn)擊 ? ? private boolean isMove; ? ? // 是否為第一次選擇格子 ? ? private boolean isFirstSelect; ? ? // 是否可以畫連接線和格子的選中邊框 ? ? private boolean canDrawLine, canDrawRect; ? ? // 是否有提示,沒有的話要重置當(dāng)前格子位置 ? ? private boolean canTip; ? ? // 是否可以選擇格子 ? ? private boolean canPlay; ? ? // 是否已經(jīng)點(diǎn)擊了提示 ? ? private boolean firstTip; ? ? // 存儲(chǔ)第一次和第二次選中方塊的位置 ? ? private int x1 = NULL, y1 = NULL, x2 = NULL, y2 = NULL; ? ? // 第一個(gè)折點(diǎn)和第二個(gè)折點(diǎn)的位置 ? ? private int px1, py1, px2, py2; ? ? // 連接線的類別 ? ? private int linkState; ? ? // 計(jì)數(shù)器,用于解決異步問題 ? ? private int count = 0; ? ? public MaView(Context context) { ? ? ? ? super(context); ? ? ? ? // 初始化圖片 ? ? ? ? initImg(); ? ? ? ? // 初始化游戲 ? ? ? ? newGame(); ? ? ? ? // 設(shè)置觸屏事件 ? ? ? ? setOnTouchListener(new OnTouchListener() { ? ? ? ? ? ? @Override ? ? ? ? ? ? public boolean onTouch(View v, MotionEvent event) { ? ? ? ? ? ? ? ? // 當(dāng)前狀態(tài)不可以點(diǎn)擊,如畫連接線時(shí)會(huì)有 0.5 秒的等待時(shí)間 ? ? ? ? ? ? ? ? if (!canPlay) { ? ? ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? switch (event.getAction()) { ? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_DOWN: ? ? ? ? ? ? ? ? ? ? ? ? isMove = false; ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_MOVE: ? ? ? ? ? ? ? ? ? ? ? ? isMove = true; ? ? ? ? ? ? ? ? ? ? case MotionEvent.ACTION_UP: ? ? ? ? ? ? ? ? ? ? ? ? // 若為移動(dòng)事件則不執(zhí)行 ? ? ? ? ? ? ? ? ? ? ? ? if (!isMove) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 獲取當(dāng)前點(diǎn)擊的位置在網(wǎng)格中的位置 ? ? ? ? ? ? ? ? ? ? ? ? ? ? int x = (int) event.getX() - MARGINLEFT; ? ? ? ? ? ? ? ? ? ? ? ? ? ? int y = (int) event.getY() - MARGINTOP; ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 是否超出邊界 ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (x < 0 || x > W * ROW || y < 0 || y > W * ROW) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 轉(zhuǎn)化為格子的坐標(biāo) ? ? ? ? ? ? ? ? ? ? ? ? ? ? // x 為列, y 為行 ? ? ? ? ? ? ? ? ? ? ? ? ? ? x = x / W % ROW; ? ? ? ? ? ? ? ? ? ? ? ? ? ? y = y / W; ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 是否為第一次選擇 ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (isFirstSelect) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 點(diǎn)擊的位置是否為空格子 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (map[y * ROW + x] == NULL) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 存儲(chǔ)第一個(gè)格子的位置 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? x1 = x; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? y1 = y; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 可以畫邊框 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canDrawRect = true; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? isFirstSelect = false; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // View 自帶的方法,會(huì)異步執(zhí)行 onDraw() 方法,起到更新視圖的作用 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (map[y * ROW + x] == NULL) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 點(diǎn)擊的格子是是同一個(gè)則重置選擇 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (x1 == x && y1 == y) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? noDraw(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 更新視圖 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 存儲(chǔ)第二個(gè)格子的位置 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? x2 = x; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? y2 = y; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 判斷兩個(gè)格子是否相同 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (map[y1 * ROW + x1] == map[y2 * ROW + x2]) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 是否可以連接 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (isCanLink(x1, y1, x2, y2)) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? canDrawLine = true; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 更新視圖 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 計(jì)數(shù)器,防止視圖效果不同步 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? waitLose(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? noDraw(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? noDraw(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? }); ? ? } ? ?? ?? ?// 判斷是否贏了 ? ? private boolean isWin() { ? ? ? ? for (int i = 0; i < ROW * ROW; i++) { ? ? ? ? ? ? if (map[i] != NULL) { ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return true; ? ? } ? ?? ?? ?// 判斷是否可以將消除的格子 ? ? private void waitLose() { ? ? ? ? if (count == 2) { ? ? ? ? ? ? map[y2 * ROW + x2] = NULL; ? ? ? ? ? ? map[y1 * ROW + x1] = NULL; ? ? ? ? ? ? count = 0; ? ? ? ? } ? ? } ? ? // 開始新游戲 ? ? public void newGame() { ? ? ? ? randomMap(); ? ? ? ? noDraw(); ? ? ? ? firstTip = true; ? ? ? ? canPlay = true; ? ? ? ? invalidate(); ? ? } ? ? private boolean isCanLink(int x1, int y1, int x2, int y2) { ? ? ? ? // 要經(jīng)過直線連接,一折點(diǎn)連接,二折點(diǎn)連接三個(gè)判斷 ? ? ? ? // 垂直直線連接, 其列坐標(biāo)相同 ? ? ? ? if (x1 == x2 && isVLink(x1, y1, y2)) { ? ? ? ? ? ? linkState = STRAIGHT; ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? // 水平直線連接,其行坐標(biāo)相同 ? ? ? ? if (y1 == y2 && isHLink(y1, x1, x2)) { ? ? ? ? ? ? linkState = STRAIGHT; ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? // 判斷一個(gè)折點(diǎn)的連接 ? ? ? ? if (isOneLink(x1, y1, x2, y2)) { ? ? ? ? ? ? linkState = ONELINK; ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? // 判斷兩個(gè)折點(diǎn)的連接 ? ? ? ? if (isTwoLink(x1, y1, x2, y2)) { ? ? ? ? ? ? linkState = TWOLINK; ? ? ? ? ? ? return true; ? ? ? ? } ? ? ? ? return false; ? ? } ? ? // 垂直直線判斷 ? ? private boolean isVLink(int x1, int y1, int y2) { ? ? ? ? // 保證 y1 永遠(yuǎn)不大于 y2 ? ? ? ? if (y1 > y2) { ? ? ? ? ? ? int t = y1; ? ? ? ? ? ? y1 = y2; ? ? ? ? ? ? y2 = t; ? ? ? ? } ? ? ? ? // 遍歷 x, y1 到 y2 的格子 ? ? ? ? for (int i = y1 + 1; i < y2; i++) { ? ? ? ? ? ? // 有一個(gè)不為空則不能連接 ? ? ? ? ? ? if (map[i * ROW + x1] != NULL) { ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return true; ? ? } ? ? // 水平直線判斷 ? ? private boolean isHLink(int y1, int x1, int x2) { ? ? ? ? // 保證 x1 永遠(yuǎn)不大于 x2 ? ? ? ? if (x1 > x2) { ? ? ? ? ? ? int t = x1; ? ? ? ? ? ? x1 = x2; ? ? ? ? ? ? x2 = t; ? ? ? ? } ? ? ? ? // 遍歷 x1 到 x2, y 的格子 ? ? ? ? for (int i = x1 + 1; i < x2; i++) { ? ? ? ? ? ? // 有一個(gè)不為空則不能連接 ? ? ? ? ? ? if (map[y1 * ROW + i] != NULL) { ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return true; ? ? } ? ? // 兩個(gè)折點(diǎn)判斷 ? ? private boolean isTwoLink(int x1, int y1, int x2, int y2) { ? ? ? ? // 保證第一個(gè)坐標(biāo)在左邊,便于遍歷 ? ? ? ? if (x1 > x2) { ? ? ? ? ? ? int t = x1; ? ? ? ? ? ? x1 = x2; ? ? ? ? ? ? x2 = t; ? ? ? ? ? ? t = y1; ? ? ? ? ? ? y1 = y2; ? ? ? ? ? ? y2 = t; ? ? ? ? } ? ? ? ? // 有四個(gè)方向判斷 ? ? ? ? // top ? ? ? ? // 先將第一個(gè)折點(diǎn)上移,然后將第一個(gè)折點(diǎn)與第二個(gè)坐標(biāo)用 矩形連接法 進(jìn)行判斷 ? ? ? ? for (int i = y1 - 1; i >= -1; i--) { ? ? ? ? ? ? // 若到達(dá)了邊界,則判斷第二個(gè)坐標(biāo)在這個(gè)方向是否也能到達(dá)邊界,若能則可以連接 ? ? ? ? ? ? if (i == -1) { ? ? ? ? ? ? ? ? // 第二個(gè)坐標(biāo)是否能到達(dá)上邊界 ? ? ? ? ? ? ? ? if (isCanTop(x2, y2)) { ? ? ? ? ? ? ? ? ? ? // 存儲(chǔ)第一個(gè)和第二個(gè)折點(diǎn) ? ? ? ? ? ? ? ? ? ? px1 = x2; ? ? ? ? ? ? ? ? ? ? py1 = i; ? ? ? ? ? ? ? ? ? ? px2 = x1; ? ? ? ? ? ? ? ? ? ? py2 = i; ? ? ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? if (map[x1 + i * ROW] != NULL) { ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? if (isOneLink(x1, i, x2, y2)) { ? ? ? ? ? ? ? ? // 存儲(chǔ)第二個(gè)折點(diǎn),第一個(gè)折點(diǎn)在 一折點(diǎn)連接 中存了 ? ? ? ? ? ? ? ? px2 = x1; ? ? ? ? ? ? ? ? py2 = i; ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? // down ? ? ? ? for (int i = y1 + 1; i <= ROW; i++) { ? ? ? ? ? ? if (i == ROW) { ? ? ? ? ? ? ? ? if (isCanDown(x2, y2)) { ? ? ? ? ? ? ? ? ? ? px1 = x2; ? ? ? ? ? ? ? ? ? ? py1 = i; ? ? ? ? ? ? ? ? ? ? px2 = x1; ? ? ? ? ? ? ? ? ? ? py2 = i; ? ? ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? if (map[x1 + i * ROW] != NULL) { ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? if (isOneLink(x1, i, x2, y2)) { ? ? ? ? ? ? ? ? px2 = x1; ? ? ? ? ? ? ? ? py2 = i; ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? // left ? ? ? ? for (int i = x1 - 1; i >= -1; i--) { ? ? ? ? ? ? if (i == -1) { ? ? ? ? ? ? ? ? if (isCanLeft(x2, y2)) { ? ? ? ? ? ? ? ? ? ? px2 = i; ? ? ? ? ? ? ? ? ? ? py2 = y1; ? ? ? ? ? ? ? ? ? ? px1 = i; ? ? ? ? ? ? ? ? ? ? py1 = y2; ? ? ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? if (map[i + y1 * ROW] != NULL) { ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? if (isOneLink(i, y1, x2, y2)) { ? ? ? ? ? ? ? ? px2 = i; ? ? ? ? ? ? ? ? py2 = y1; ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? // right ? ? ? ? for (int i = x1 + 1; i <= ROW; i++) { ? ? ? ? ? ? if (i == ROW) { ? ? ? ? ? ? ? ? if (isCanRight(x2, y2)) { ? ? ? ? ? ? ? ? ? ? px2 = i; ? ? ? ? ? ? ? ? ? ? py2 = y1; ? ? ? ? ? ? ? ? ? ? px1 = i; ? ? ? ? ? ? ? ? ? ? py1 = y2; ? ? ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? if (map[i + y1 * ROW] != NULL) { ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? if (isOneLink(i, y1, x2, y2)) { ? ? ? ? ? ? ? ? px2 = i; ? ? ? ? ? ? ? ? py2 = y1; ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return false; ? ? } ? ?? ? ? private boolean isCanTop(int x2, int y2) { ? ? ? ? // 遍歷坐標(biāo)與上邊界之間的格子,若又不為空的則不能 ? ? ? ? for (int i = y2 - 1; i >= -1; i--) { ? ? ? ? ? ? if (i == -1) { ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? if (map[i * ROW + x2] != NULL) { ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return true; ? ? } ? ? private boolean isCanLeft(int x2, int y2) { ? ? ? ? for (int i = x2 - 1; i >= -1; i--) { ? ? ? ? ? ? if (i == -1) { ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? if (map[y2 * ROW + i] != NULL) { ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return true; ? ? } ? ? private boolean isCanRight(int x2, int y2) { ? ? ? ? for (int i = x2 + 1; i <= ROW; i++) { ? ? ? ? ? ? if (i == ROW) { ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? if (map[y2 * ROW + i] != NULL) { ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return true; ? ? } ? ? private boolean isCanDown(int x2, int y2) { ? ? ? ? for (int i = y2 + 1; i <= ROW; i++) { ? ? ? ? ? ? if (i == ROW) { ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? ? ? if (map[i * ROW + x2] != NULL) { ? ? ? ? ? ? ? ? return false; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return true; ? ? } ? ? // 一個(gè)折點(diǎn)判斷 ? ? private boolean isOneLink(int x1, int y1, int x2, int y2) { ? ? ? ? // 保證第一個(gè)坐標(biāo)在左邊,便于遍歷 ? ? ? ? if (x1 > x2) { ? ? ? ? ? ? int t = x1; ? ? ? ? ? ? x1 = x2; ? ? ? ? ? ? x2 = t; ? ? ? ? ? ? t = y1; ? ? ? ? ? ? y1 = y2; ? ? ? ? ? ? y2 = t; ? ? ? ? } ? ? ? ? // 一個(gè)折點(diǎn)的用 矩形判斷法, 兩個(gè)坐標(biāo)在對(duì)角處,折點(diǎn)在另外的對(duì)角處 ? ? ? ? // 先判斷這個(gè)折點(diǎn)是否為空,不為空就不能連接 ? ? ? ? // 為空就將兩個(gè)坐標(biāo)點(diǎn)與這個(gè)折點(diǎn)用直線連接判斷,若可以,則可以連接 ? ? ? ? if (map[y1 * ROW + x2] == NULL) { ? ? ? ? ? ? if (isHLink(y1, x1, x2) && isVLink(x2, y1, y2)) { ? ? ? ? ? ? ? ? // 存儲(chǔ)第一個(gè)折點(diǎn)的位置,便于畫線 ? ? ? ? ? ? ? ? px1 = x2; ? ? ? ? ? ? ? ? py1 = y1; ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? // 另外一個(gè)折點(diǎn) ? ? ? ? if (map[x1 + y2 * ROW] == NULL) { ? ? ? ? ? ? // 注意 x, y 的變換位置 ? ? ? ? ? ? if (isHLink(y2, x1, x2) && isVLink(x1, y1, y2)) { ? ? ? ? ? ? ? ? // 存儲(chǔ)第一個(gè)折點(diǎn)的位置,便于畫線 ? ? ? ? ? ? ? ? px1 = x1; ? ? ? ? ? ? ? ? py1 = y2; ? ? ? ? ? ? ? ? return true; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return false; ? ? } ? ? private void initImg() { ? ? ? ? int id; ? ? ? ? for (int i = 0; i < imgs.length; i++) { ? ? ? ? ? ? id = getResources().getIdentifier("a" + (i + 1), "drawable", getContext().getPackageName()); ? ? ? ? ? ? // 顯示圖片原尺寸 // ? ? ? ? ? ?BitmapFactory.Options options = new BitmapFactory.Options(); // ? ? ? ? ? ?options.inScaled = false; ? ? ? ? ? ? imgs[i] = BitmapFactory.decodeResource(getResources(), id); ? ? ? ? ? ? int w = imgs[i].getWidth(); ? ? ? ? ? ? int h = imgs[i].getHeight(); ? ? ? ? ? ? Matrix matrix = new Matrix(); ? ? ? ? ? ? matrix.postScale(IMGW * 1.0f / w, IMGW * 1.0f / h); ? ? ? ? ? ? imgs[i] = Bitmap.createBitmap(imgs[i], 0, 0, w, h, matrix, true); ? ? ? ? } ? ? } ? ? private Bitmap getMyImg(Bitmap rootImg, int goalW, int goalH) { ? ? ? ? int rootW = rootImg.getWidth(); ? ? ? ? int rootH = rootImg.getHeight(); ? ? ? ? // graphics 包下的 ? ? ? ? Matrix matrix = new Matrix(); ? ? ? ? matrix.postScale(goalW * 1.0f / rootW, goalH * 1.0f / rootH); ? ? ? ? return Bitmap.createBitmap(rootImg, 0, 0, rootW, rootH, matrix, true); ? ? } ? ? private void randomMap() { ? ? ? ? // 初始化地圖并將位置打亂 ? ? ? ? int c = 0; ? ? ? ? // 每種格子有四個(gè) ? ? ? ? for (int i = 0; i < L; i++) { ? ? ? ? ? ? for (int j = 0; j < 4; j++) { ? ? ? ? ? ? ? ? map[c] = i; ? ? ? ? ? ? ? ? c++; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? // 循環(huán) 500 次打亂位置 ? ? ? ? int a, b, t; ? ? ? ? Random random = new Random(); ? ? ? ? for (int i = 0; i < 500; i++) { ? ? ? ? ? ? a = random.nextInt(ROW * ROW); ? ? ? ? ? ? b = random.nextInt(ROW * ROW); ? ? ? ? ? ? if (map[a] == NULL || map[b] == NULL) { ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? } ? ? ? ? ? ? t = map[a]; ? ? ? ? ? ? map[a] = map[b]; ? ? ? ? ? ? map[b] = t; ? ? ? ? } ? ? } // ? ?private void showMap() { // ? ? ? ?String s = ""; // ? ? ? ?int c = 0; // ? ? ? ?for (int i = 0; i < ROW; i++) { // ? ? ? ? ? ?for (int j = 0; j < ROW; j++) { // ? ? ? ? ? ? ? ?s += map[c] + " "; // ? ? ? ? ? ? ? ?c++; // ? ? ? ? ? ?} // ? ? ? ? ? ?s = ""; // ? ? ? ?} // ? ?} ? ? @Override ? ? protected void onDraw(Canvas canvas) { ? ? ? ? int x, y; ? ? ? ? int c = 0; ? ? ? ? // 畫格子 ? ? ? ? for (int i = 0; i < ROW; i++) { ? ? ? ? ? ? for (int j = 0; j < ROW; j++) { ? ? ? ? ? ? ? ? x = MARGINLEFT + j * W; ? ? ? ? ? ? ? ? y = MARGINTOP + i * W; ? ? ? ? ? ? ? ? if (map[c] != NULL) { ? ? ? ? ? ? ? ? ? ? canvas.drawBitmap(imgs[map[c]], x, y, new Paint()); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? c++; ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? // 畫提示的格子邊框 ? ? ? ? if (canTip) { ? ? ? ? ? ? // 設(shè)置線條的樣式 ? ? ? ? ? ? Paint paint = new Paint(); ? ? ? ? ? ? paint.setStrokeWidth(8); ? ? ? ? ? ? paint.setColor(Color.parseColor("#08ffc8")); ? ? ? ? ? ? paint.setStyle(Paint.Style.STROKE); ? ? ? ? ? ? x = x1 * W + MARGINLEFT; ? ? ? ? ? ? y = y1 * W + MARGINTOP; ? ? ? ? ? ? canvas.drawRect(x, y, x + W - 3, y + W - 3, paint); ? ? ? ? ? ? x = x2 * W + MARGINLEFT; ? ? ? ? ? ? y = y2 * W + MARGINTOP; ? ? ? ? ? ? canvas.drawRect(x, y, x + W - 3, y + W - 3, paint); ? ? ? ? ? ? canTip = false; ? ? ? ? ? ? noDraw(); ? ? ? ? } ? ? ? ? // 畫已選格子的邊框 ? ? ? ? if (canDrawRect) { ? ? ? ? ? ? Paint paint = new Paint(); ? ? ? ? ? ? paint.setStrokeWidth(8); ? ? ? ? ? ? paint.setColor(Color.RED); ? ? ? ? ? ? paint.setStyle(Paint.Style.STROKE); ? ? ? ? ? ? // 第一個(gè)格子 ? ? ? ? ? ? if (x1 != NULL) { ? ? ? ? ? ? ? ? x = x1 * W + MARGINLEFT; ? ? ? ? ? ? ? ? y = y1 * W + MARGINTOP; ? ? ? ? ? ? ? ? canvas.drawRect(x, y, x + W - 3, y + W - 3, paint); ? ? ? ? ? ? ? ? firstTip = true; ? ? ? ? ? ? } ? ? ? ? ? ? // 第二個(gè)格子 ? ? ? ? ? ? if (x2 != NULL) { ? ? ? ? ? ? ? ? x = x2 * W + MARGINLEFT; ? ? ? ? ? ? ? ? y = y2 * W + MARGINTOP; ? ? ? ? ? ? ? ? canvas.drawRect(x, y, x + W - 3, y + W - 3, paint); ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? waitLose(); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? // 畫連接線 ? ? ? ? if (canDrawLine) { ? ? ? ? ? ? Paint paint = new Paint(); ? ? ? ? ? ? paint.setStrokeWidth(8); ? ? ? ? ? ? paint.setColor(Color.RED); ? ? ? ? ? ? paint.setStyle(Paint.Style.FILL); ? ? ? ? ? ? int sx1, sy1, sx2, sy2, zx1, zy1, zx2, zy2; ? ? ? ? ? ? // 第一個(gè)坐標(biāo) ? ? ? ? ? ? sx1 = x1 * W + W + MARGINLEFT - W / 2; ? ? ? ? ? ? sy1 = y1 * W + W + MARGINTOP - W / 2; ? ? ? ? ? ? // 第二個(gè)坐標(biāo) ? ? ? ? ? ? sx2 = x2 * W + W + MARGINLEFT - W / 2; ? ? ? ? ? ? sy2 = y2 * W + W + MARGINTOP - W / 2; ? ? ? ? ? ? switch (linkState) { ? ? ? ? ? ? ? ? case STRAIGHT: ? ? ? ? ? ? ? ? ? ? // 畫直線 ? ? ? ? ? ? ? ? ? ? canvas.drawLine(sx1, sy1, sx2, sy2, paint); ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? case ONELINK: ? ? ? ? ? ? ? ? ? ? // 畫一折點(diǎn)線 ? ? ? ? ? ? ? ? ? ? zx1 = px1 * W + MARGINLEFT + W / 2; ? ? ? ? ? ? ? ? ? ? zy1 = py1 * W + MARGINTOP + W / 2; ? ? ? ? ? ? ? ? ? ? canvas.drawLine(sx1, sy1, zx1, zy1, paint); ? ? ? ? ? ? ? ? ? ? canvas.drawLine(zx1, zy1, sx2, sy2, paint); ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? case TWOLINK: ? ? ? ? ? ? ? ? ? ? // 畫二折點(diǎn)線 ? ? ? ? ? ? ? ? ? ? // 第二個(gè)折點(diǎn) ? ? ? ? ? ? ? ? ? ? zx1 = px1 * W + MARGINLEFT + W / 2; ? ? ? ? ? ? ? ? ? ? zy1 = py1 * W + MARGINTOP + W / 2; ? ? ? ? ? ? ? ? ? ? // 第一個(gè)折點(diǎn) ? ? ? ? ? ? ? ? ? ? zx2 = px2 * W + MARGINLEFT + W / 2; ? ? ? ? ? ? ? ? ? ? zy2 = py2 * W + MARGINTOP + W / 2; ? ? ? ? ? ? ? ? ? ? // 到邊界了改變一下線條的位置 ? ? ? ? ? ? ? ? ? ? if (px1 == -1) { ? ? ? ? ? ? ? ? ? ? ? ? zx1 += 30; ? ? ? ? ? ? ? ? ? ? ? ? zx2 += 30; ? ? ? ? ? ? ? ? ? ? } else if (px1 == ROW) { ? ? ? ? ? ? ? ? ? ? ? ? zx1 -= 30; ? ? ? ? ? ? ? ? ? ? ? ? zx2 -= 30; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? // 有左右兩種情況,上下兩種情況,但第一個(gè)折點(diǎn)一定與第一個(gè)坐標(biāo)的 x 或 y 相同 ? ? ? ? ? ? ? ? ? ? if (px1 == x1 || py1 == y1) { ? ? ? ? ? ? ? ? ? ? ? ? int t = zx1; ? ? ? ? ? ? ? ? ? ? ? ? zx1 = zx2; ? ? ? ? ? ? ? ? ? ? ? ? zx2 = t; ? ? ? ? ? ? ? ? ? ? ? ? t = zy1; ? ? ? ? ? ? ? ? ? ? ? ? zy1 = zy2; ? ? ? ? ? ? ? ? ? ? ? ? zy2 = t; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? canvas.drawLine(sx1, sy1, zx2, zy2, paint); ? ? ? ? ? ? ? ? ? ? canvas.drawLine(zx2, zy2, zx1, zy1, paint); ? ? ? ? ? ? ? ? ? ? canvas.drawLine(zx1, zy1, sx2, sy2, paint); ? ? ? ? ? ? } ? ? ? ? ? ? noDraw(); ? ? ? ? ? ? // 畫線過程不能點(diǎn)擊 ? ? ? ? ? ? canPlay = false; ? ? ? ? ? ? // 開一個(gè)線程做連接效果 ? ? ? ? ? ? new Timer().schedule(new TimerTask() { ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? ? ? // 這個(gè)方法用于轉(zhuǎn)到主線程中執(zhí)行,更新視圖操作必須放到主線程中執(zhí)行 其 invalidate() 跟新了視圖 ? ? ? ? ? ? ? ? ? ? post(new Runnable() { ? ? ? ? ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? ? ? ? ? public void run() { ? ? ? ? ? ? ? ? ? ? ? ? ? ? invalidate(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 判斷是否贏了沒 ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (isWin()) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Toast.makeText(getContext(), "You Win! Please New Game", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? // 可以點(diǎn)擊了 ? ? ? ? ? ? ? ? ? ? ? ? ? ? canPlay = true; ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? }); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? }, 500); ? ? ? ? } ? ? } ? ? // 重置當(dāng)前圖片的位置 ? ? public void reset() { ? ? ? ? if (!canPlay) { ? ? ? ? ? ? return; ? ? ? ? } ? ? ? ? int a, b, t; ? ? ? ? Random random = new Random(); ? ? ? ? for (int i = 0; i < 500; i++) { ? ? ? ? ? ? a = random.nextInt(ROW * ROW); ? ? ? ? ? ? b = random.nextInt(ROW * ROW); ? ? ? ? ? ? if (map[a] == NULL || map[b] == NULL) { ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? } ? ? ? ? ? ? t = map[a]; ? ? ? ? ? ? map[a] = map[b]; ? ? ? ? ? ? map[b] = t; ? ? ? ? } ? ? ? ? invalidate(); ? ? } ? ? // 獲取提示 ? ? public void getTip() { ? ? ? ? if (!canPlay) { ? ? ? ? ? ? return; ? ? ? ? } ? ? ? ? // 不能連續(xù)點(diǎn)擊 ? ? ? ? if (!firstTip) { ? ? ? ? ? ? Toast.makeText(getContext(), "Alright Tip!", Toast.LENGTH_SHORT).show(); ? ? ? ? ? ? return; ? ? ? ? } ? ? ? ? firstTip = false; ? ? ? ? int count = 0; ? ? ? ? int x1, y1, x2, y2; ? ? ? ? Tag: ? ? ? ? for (int i = 0; i < ROW * ROW; i++) { ? ? ? ? ? ? if (map[i] == NULL) { ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? } ? ? ? ? ? ? for (int j = i + 1; j < ROW * ROW; j++) { ? ? ? ? ? ? ? ? if (map[j] == NULL) { ? ? ? ? ? ? ? ? ? ? continue; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? if (map[i] == map[j]) { ? ? ? ? ? ? ? ? ? ? x1 = i % ROW; ? ? ? ? ? ? ? ? ? ? y1 = i / ROW; ? ? ? ? ? ? ? ? ? ? x2 = j % ROW; ? ? ? ? ? ? ? ? ? ? y2 = j / ROW; ? ? ? ? ? ? ? ? ? ? if (isCanLink(x1, y1, x2, y2)) { ? ? ? ? ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? ? ? ? ? this.x1 = x1; ? ? ? ? ? ? ? ? ? ? ? ? this.y1 = y1; ? ? ? ? ? ? ? ? ? ? ? ? this.x2 = x2; ? ? ? ? ? ? ? ? ? ? ? ? this.y2 = y2; ? ? ? ? ? ? ? ? ? ? ? ? break Tag; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? // 不為空則有可連接的格子 ? ? ? ? if (count != 0) { ? ? ? ? ? ? canTip = true; ? ? ? ? ? ? invalidate(); ? ? ? ? } else { ? ? ? ? ? ? Toast.makeText(getContext(), "No One! Please Click New Game", Toast.LENGTH_SHORT).show(); ? ? ? ? } ? ? } ? ? // 重置選擇格子 ? ? private void noDraw() { ? ? ? ? canDrawRect = false; ? ? ? ? canDrawLine = false; ? ? ? ? isFirstSelect = true; ? ? ? ? x1 = NULL; ? ? ? ? x2 = NULL; ? ? ? ? y1 = NULL; ? ? ? ? y2 = NULL; ? ? } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android使用Circular Reveal動(dòng)畫讓頁(yè)面跳轉(zhuǎn)更炫酷
本篇文章主要介紹了Android使用Circular Reveal動(dòng)畫讓頁(yè)面跳轉(zhuǎn)更炫酷,具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08Android中Root權(quán)限獲取的簡(jiǎn)單代碼
那么我們?cè)贏ndroid開發(fā)中如何獲取Android的Root權(quán)限呢?下面是主要的簡(jiǎn)單代碼。2013-06-06Flutter中跨組件數(shù)據(jù)傳遞的方法總結(jié)
Flutter中的數(shù)據(jù)傳遞一般包括:父->子,子->父,父->父,也就是說嵌套時(shí)的傳遞以及跨頁(yè)面的傳遞,本文整理了三種我們通常使用的方法,需要的可以參考一下2023-06-06Android編程之截屏實(shí)現(xiàn)方法(包括scrollview與listview)
這篇文章主要介紹了Android編程之截屏實(shí)現(xiàn)方法,包括截取scrollview與listview屏幕的相關(guān)技巧,以及截屏圖片的生成與保存技巧,需要的朋友可以參考下2015-11-11Android中閃屏實(shí)現(xiàn)方法小結(jié)(普通閃屏、倒計(jì)時(shí)閃屏、倒計(jì)時(shí)+動(dòng)畫閃屏)
這篇文章主要介紹了Android中閃屏實(shí)現(xiàn)方法小結(jié)(普通閃屏、倒計(jì)時(shí)閃屏、倒計(jì)時(shí)+動(dòng)畫閃屏),非常不錯(cuò),代碼簡(jiǎn)單易懂,需要的朋友可以參考下2017-01-01Android實(shí)現(xiàn)購(gòu)物車添加商品動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)購(gòu)物車添加商品動(dòng)畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06Android實(shí)現(xiàn)伸縮彈力分布菜單效果的示例
本文介紹下在Android中實(shí)現(xiàn)伸縮彈力分布菜單效果。這種效果比較炫酷,有需要的朋友可以參考一下。2016-10-10