/** 产生一个数字 */ public void generateNum() { if (checkOver()) { Log.e("TAG", "GAME OVER"); if (mGame2048Listener != null) { mGame2048Listener.onGameOver(); } return; } if (!isFull()) { if (isMoveHappen || isMergeHappen) { Random random = new Random(); int next = random.nextInt(16); Game2048Item item = mGame2048Items[next]; while (item.getmNumber() != 0) { next = random.nextInt(16); item = mGame2048Items[next]; } item.setmNumber(Math.random() > 0.75 ? 4 : 2); isMergeHappen = isMoveHappen = false; } } }
/** 重新开始游戏 */ public void restart() { for (Game2048Item item : mGame2048Items) { item.setmNumber(0); } mScore = 0; if (mGame2048Listener != null) { mGame2048Listener.onScoreChange(mScore); } isMoveHappen = isMergeHappen = true; generateNum(); }
/** * 合并相同的Item * * @param row */ private void mergeItem(List<Game2048Item> row) { if (row.size() < 2) return; for (int j = 0; j < row.size() - 1; j++) { Game2048Item item1 = row.get(j); Game2048Item item2 = row.get(j + 1); if (item1.getmNumber() == item2.getmNumber()) { isMergeHappen = true; int val = item1.getmNumber() + item2.getmNumber(); item1.setmNumber(val); // 加分 mScore += val; if (mGame2048Listener != null) { mGame2048Listener.onScoreChange(mScore); } // 向前移动 for (int k = j + 1; k < row.size() - 1; k++) { row.get(k).setmNumber(row.get(k + 1).getmNumber()); } row.get(row.size() - 1).setmNumber(0); return; } } }
/** 测量Layout的宽和高,以及设置Item的宽和高,这里忽略wrap_content 以宽、高之中的最小值绘制正方形 */ @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); // 获得正方形的边长 int length = Math.min(getMeasuredHeight(), getMeasuredWidth()); // 获得Item的宽度 int childWidth = (length - mPadding * 2 - mMargin * (mColumn - 1)) / mColumn; if (!once) { if (mGame2048Items == null) { mGame2048Items = new Game2048Item[mColumn * mColumn]; } // 放置Item for (int i = 0; i < mGame2048Items.length; i++) { Game2048Item item = new Game2048Item(getContext()); mGame2048Items[i] = item; item.setId(i + 1); RelativeLayout.LayoutParams lp = new LayoutParams(childWidth, childWidth); // 设置横向边距,不是最后一列 if ((i + 1) % mColumn != 0) { lp.rightMargin = mMargin; } // 如果不是第一列 if (i % mColumn != 0) { lp.addRule( RelativeLayout.RIGHT_OF, // mGame2048Items[i - 1].getId()); } // 如果不是第一行,//设置纵向边距,非最后一行 if ((i + 1) > mColumn) { lp.topMargin = mMargin; lp.addRule( RelativeLayout.BELOW, // mGame2048Items[i - mColumn].getId()); } addView(item, lp); } generateNum(); } once = true; setMeasuredDimension(length, length); }
/** 根据用户运动,整体进行移动合并值等 */ private void action(ACTION action) { // 行|列 for (int i = 0; i < mColumn; i++) { List<Game2048Item> row = new ArrayList<Game2048Item>(); // 行|列 // 记录不为0的数字 for (int j = 0; j < mColumn; j++) { // 得到下标 int index = getIndexByAction(action, i, j); Game2048Item item = mGame2048Items[index]; // 记录不为0的数字 if (item.getmNumber() != 0) { row.add(item); } } // 判断是否发生移动 for (int j = 0; j < mColumn && j < row.size(); j++) { int index = getIndexByAction(action, i, j); Game2048Item item = mGame2048Items[index]; if (item.getmNumber() != row.get(j).getmNumber()) { isMoveHappen = true; } } // 合并相同的 mergeItem(row); // 设置合并后的值 for (int j = 0; j < mColumn; j++) { int index = getIndexByAction(action, i, j); if (row.size() > j) { mGame2048Items[index].setmNumber(row.get(j).getmNumber()); } else { mGame2048Items[index].setmNumber(0); } } } // 生成数字 generateNum(); }
/** * 检测当前所有的位置都有数字,且相邻的没有相同的数字 * * @return */ private boolean checkOver() { // 检测是否所有位置都有数字 if (!isFull()) { return false; } for (int i = 0; i < mColumn; i++) { for (int j = 0; j < mColumn; j++) { int index = i * mColumn + j; // 当前的Item Game2048Item item = mGame2048Items[index]; // 右边 if ((index + 1) % mColumn != 0) { Log.e("TAG", "RIGHT"); // 右边的Item Game2048Item itemRight = mGame2048Items[index + 1]; if (item.getmNumber() == itemRight.getmNumber()) return false; } // 下边 if ((index + mColumn) < mColumn * mColumn) { Log.e("TAG", "DOWN"); Game2048Item itemBottom = mGame2048Items[index + mColumn]; if (item.getmNumber() == itemBottom.getmNumber()) return false; } // 左边 if (index % mColumn != 0) { Log.e("TAG", "LEFT"); Game2048Item itemLeft = mGame2048Items[index - 1]; if (itemLeft.getmNumber() == item.getmNumber()) return false; } // 上边 if (index + 1 > mColumn) { Log.e("TAG", "UP"); Game2048Item itemTop = mGame2048Items[index - mColumn]; if (item.getmNumber() == itemTop.getmNumber()) return false; } } } return true; }