成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Android實(shí)現(xiàn)俄羅斯方塊的方法

這篇文章主要介紹了Android實(shí)現(xiàn)俄羅斯方塊的方法,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)是一家專(zhuān)注于網(wǎng)站建設(shè)、做網(wǎng)站與策劃設(shè)計(jì),嘉魚(yú)網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專(zhuān)注于網(wǎng)站建設(shè)10多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專(zhuān)業(yè)建站公司;建站業(yè)務(wù)涵蓋:嘉魚(yú)等地區(qū)。嘉魚(yú)做網(wǎng)站價(jià)格咨詢:13518219792

具體內(nèi)容如下

思路:

  • 首先要畫(huà)出游戲背景墻;

  • 其次,要有方塊,以及方塊單元;

  • 方塊的不同形狀,顏色隨機(jī)產(chǎn)生;

  • 游戲的控制面板。

可能會(huì)出現(xiàn)的問(wèn)題或者難點(diǎn):

邊界問(wèn)題:

①處于邊界的時(shí)候,方塊不可以再左右移動(dòng);
②下降的時(shí)候,到達(dá)邊界即底部,則不可繼續(xù)下落,此時(shí)應(yīng)該產(chǎn)生一個(gè)新的方塊;

與其它方塊接觸問(wèn)題:

①下落的時(shí)候,如果碰到其它的方塊則停止下落;
②左右移動(dòng)的時(shí)候,移動(dòng)的過(guò)程中,如果接觸到其他方快,則不可再繼續(xù)左右移動(dòng);

方塊的消除:

①調(diào)用方塊消除方法的時(shí)間:當(dāng)方塊下落到底部的時(shí)候,判斷是否有需要消除的行;
②消除某一行之后,應(yīng)該把這一行上面的全部方塊下移一行;

方塊的旋轉(zhuǎn):

在當(dāng)前項(xiàng)目中,我采用的是順時(shí)針旋轉(zhuǎn)。
①當(dāng)旋轉(zhuǎn)的時(shí)候,如果出現(xiàn)方塊部分超出了邊界,應(yīng)該對(duì)方塊進(jìn)行平移,使其回到邊界以內(nèi)。(曾在網(wǎng)上看到有人做過(guò),判斷旋轉(zhuǎn)之后是否會(huì)超出邊界,如果會(huì)超出,則不進(jìn)行旋轉(zhuǎn),我覺(jué)得不好,方塊只要沒(méi)有下落到底部,我覺(jué)得都可以進(jìn)行旋轉(zhuǎn),除了沒(méi)有空間讓其旋轉(zhuǎn)外);
②如果空間不足以旋轉(zhuǎn),也不可以旋轉(zhuǎn)??臻g不足以旋轉(zhuǎn)的意思是:比如橫向方向只有兩個(gè)的空間,而方塊旋轉(zhuǎn)后會(huì)占用三個(gè)空間,此時(shí)也不可進(jìn)行旋轉(zhuǎn);
③當(dāng)無(wú)法繼續(xù)下落或者下落到了底部也不可再進(jìn)行旋轉(zhuǎn)

控制面板:

①游戲開(kāi)始、暫停、繼續(xù)、結(jié)束,這些狀態(tài)應(yīng)該怎么去控制,以及游戲與控制臺(tái)的事件關(guān)聯(lián)。

未發(fā)現(xiàn)的問(wèn)題:

因?yàn)楸救四芰?,只做到這么多,如果有人發(fā)現(xiàn)問(wèn)題,可以留言交流,歡迎挑問(wèn)題。

游戲的運(yùn)行界面如下所示,基本的功能以及操作很簡(jiǎn)單。

Android實(shí)現(xiàn)俄羅斯方塊的方法

下面直接看項(xiàng)目代碼
項(xiàng)目文件結(jié)構(gòu)

Android實(shí)現(xiàn)俄羅斯方塊的方法

下面分別介紹每個(gè)類(lèi)的功能

TetrisViewAW.java游戲的主界面,背景墻以及方塊都在此TetrisViewAW.Java里面,就是一個(gè)自定義的View ,(默認(rèn)大家對(duì)于自定義View是熟悉的),在改類(lèi)里面,有一個(gè)游戲主線程,用于控制游戲的開(kāi)始,暫停,繼續(xù),停止,以及方塊下落的速率。代碼我加了很多注釋?zhuān)床欢目梢粤粞?。還有一點(diǎn)需要注意,當(dāng)停止游戲時(shí),要釋放線程,養(yǎng)成好習(xí)慣

/**
 * 俄羅斯方塊Game主界面
 * 
 * @sign Created by wang.ao on 2017年1月12日
 */
@SuppressLint("DrawAllocation")
public class TetrisViewAW extends View {
 /** 網(wǎng)格開(kāi)始坐標(biāo)值,橫縱坐標(biāo)的開(kāi)始值都是此值 */
 public static final int beginPoint = 10;
 /** 俄羅斯方塊的最大坐標(biāo) */
 private static int max_x, max_y;
 /** 行數(shù)和列數(shù) */
 private static int num_x = 0, num_y = 0;
 /** 背景墻畫(huà)筆 */
 private static Paint paintWall = null;
 /** 俄羅斯方塊的單元塊畫(huà)筆 */
 private static Paint paintBlock = null;
 private static final int BOUND_WIDTH_OF_WALL = 2;
 /** 當(dāng)前正在下落的方塊 */
 private List<BlockUnit> blockUnits = new ArrayList<BlockUnit>();
 /** 下一個(gè)要顯示的方塊 */
 private List<BlockUnit> blockUnitBufs = new ArrayList<BlockUnit>();
 /** 下一個(gè)要顯示的方塊 */
 private List<BlockUnit> routeBlockUnitBufs = new ArrayList<BlockUnit>();
 /** 全部的方塊allBlockUnits */
 private List<BlockUnit> allBlockUnits = new ArrayList<BlockUnit>();
 /** 調(diào)用此對(duì)象的Activity對(duì)象 */
 private TetrisActivityAW father = null;
 private int[] map = new int[100]; // 保存每行網(wǎng)格中包含俄羅斯方塊單元的個(gè)數(shù)
 /** 游戲的主線程 */
 private Thread mainThread = null;
 // 游戲的幾種狀態(tài)
 /** 標(biāo)識(shí)游戲是開(kāi)始還是停止 */
 private boolean gameStatus = false;
 /** 標(biāo)識(shí)游戲是暫停還是運(yùn)行 */
 private boolean runningStatus = false;
 /** 俄羅斯方塊顏色數(shù)組 */
 private static final int color[] = { Color.parseColor("#FF6600"), Color.BLUE, Color.RED, Color.GREEN, Color.GRAY };
 /** 方塊的中心方塊單元的坐標(biāo), */
 private int xx, yy;
 /** 方塊,用戶隨機(jī)獲取各種形狀的方塊 */
 private TetrisBlock tetrisBlock;
 /** 分?jǐn)?shù) */
 private int score = 0;
 /** 當(dāng)前方塊的類(lèi)型 */
 private int blockType = 0;

 public TetrisViewAW(Context context) {
 this(context, null);
 }

 public TetrisViewAW(Context context, AttributeSet attrs) {
 super(context, attrs);
 if (paintWall == null) {// 初始化化背景墻畫(huà)筆
 paintWall = new Paint();
 paintWall.setColor(Color.LTGRAY);
 paintWall.setStyle(Paint.Style.STROKE);
 paintWall.setStrokeWidth(BOUND_WIDTH_OF_WALL + 1);
 }
 if (paintBlock == null) {// 初始化化背景墻畫(huà)筆
 paintBlock = new Paint();
 paintBlock.setColor(Color.parseColor("#FF6600"));
 }
 tetrisBlock = new TetrisBlock();
 routeBlockUnitBufs = tetrisBlock.getUnits(beginPoint, beginPoint);
 Arrays.fill(map, 0); // 每行網(wǎng)格中包含俄羅斯方塊單元的個(gè)數(shù)全部初始化為0
 // 繪制方塊
 }

 /**
 * 設(shè)置當(dāng)前游戲頁(yè)面的父類(lèi)activity
 * 
 * @param tetrisActivityAW
 */
 public void setFather(TetrisActivityAW tetrisActivityAW) {
 father = tetrisActivityAW;
 }

 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 max_x = getWidth();
 max_y = getHeight();
 RectF rel;
 // 繪制網(wǎng)格
 num_x = 0;
 num_y = 0;
 for (int i = beginPoint; i < max_x - BlockUnit.UNIT_SIZE; i += BlockUnit.UNIT_SIZE) {
 for (int j = beginPoint; j < max_y - BlockUnit.UNIT_SIZE; j += BlockUnit.UNIT_SIZE) {
 rel = new RectF(i, j, i + BlockUnit.UNIT_SIZE, j + BlockUnit.UNIT_SIZE);
 canvas.drawRoundRect(rel, 8, 8, paintWall);
 num_y++;
 }
 num_x++;
 }
 // 隨機(jī)產(chǎn)生一個(gè)俄羅斯方塊
 int len = blockUnits.size();
 // 繪制方塊
 // Toast.makeText(context, "" + len, Toast.LENGTH_SHORT).show();
 for (int i = 0; i < len; i++) {
 int x = blockUnits.get(i).x;
 int y = blockUnits.get(i).y;
 // 設(shè)置當(dāng)前方塊的顏色
 paintBlock.setColor(color[blockUnits.get(i).color]);
 rel = new RectF(x + BOUND_WIDTH_OF_WALL, y + BOUND_WIDTH_OF_WALL,
 x + BlockUnit.UNIT_SIZE - BOUND_WIDTH_OF_WALL, y + BlockUnit.UNIT_SIZE - BOUND_WIDTH_OF_WALL);
 canvas.drawRoundRect(rel, 8, 8, paintBlock);
 }
 // 隨機(jī)產(chǎn)生一個(gè)俄羅斯方塊
 len = allBlockUnits.size();
 // 繪制方塊
 // Toast.makeText(context, "" + len, Toast.LENGTH_SHORT).show();
 for (int i = 0; i < len; i++) {
 int x = allBlockUnits.get(i).x;
 int y = allBlockUnits.get(i).y;
 paintBlock.setColor(color[allBlockUnits.get(i).color]);
 rel = new RectF(x + BOUND_WIDTH_OF_WALL, y + BOUND_WIDTH_OF_WALL,
 x + BlockUnit.UNIT_SIZE - BOUND_WIDTH_OF_WALL, y + BlockUnit.UNIT_SIZE - BOUND_WIDTH_OF_WALL);
 canvas.drawRoundRect(rel, 8, 8, paintBlock);
 }
 }

 /**
 * 開(kāi)始游戲
 */
 public void startGame() {
 gameStatus = true;
 runningStatus = true;
 if (mainThread == null || !mainThread.isAlive()) {
 getNewBlock();
 mainThread = new Thread(new MainThread());
 mainThread.start();
 }

 }

 /**
 * 暫停游戲
 */
 public void pauseGame() {
 runningStatus = false;
 }

 /**
 * 繼續(xù)游戲
 */
 public void continueGame() {
 runningStatus = true;
 }

 /**
 * 停止游戲
 */
 public void stopGame() {
 // 停止游戲,釋放游戲主線程
 runningStatus = false;
 gameStatus = false;
 mainThread.interrupt();
 blockUnits.clear();
 allBlockUnits.clear();
 score = 0;
 invalidate();
 }

 /**
 * 向左滑動(dòng)
 */
 public void toLeft() {
 if (BlockUnit.toLeft(blockUnits, max_x, allBlockUnits)) {
 xx = xx - BlockUnit.UNIT_SIZE;
 }
 invalidate();
 }

 /**
 * 向右滑動(dòng)
 */
 public void toRight() {
 if (BlockUnit.toRight(blockUnits, max_x, allBlockUnits)) {
 xx = xx + BlockUnit.UNIT_SIZE;
 }
 invalidate();
 }

 /**
 * 按順時(shí)針旋轉(zhuǎn)
 */
 public void route() {
 if (blockType == 3) {// 如果當(dāng)前正在下落的方塊為正方形,則不進(jìn)行旋轉(zhuǎn)
 return;
 }
 if (routeBlockUnitBufs.size() != blockUnits.size()) {
 routeBlockUnitBufs = tetrisBlock.getUnits(xx, yy);
 }
 for (int i = 0; i < blockUnits.size(); i++) {
 routeBlockUnitBufs.get(i).x = blockUnits.get(i).x;
 routeBlockUnitBufs.get(i).y = blockUnits.get(i).y;
 }
 for (BlockUnit blockUnit : routeBlockUnitBufs) {
 int tx = blockUnit.x;
 int ty = blockUnit.y;
 blockUnit.x = -(ty - yy) + xx;
 blockUnit.y = tx - xx + yy;
 }
 routeTran(routeBlockUnitBufs);
 if (!BlockUnit.canRoute(routeBlockUnitBufs, allBlockUnits)) {
 // Toast.makeText(father, "不可旋轉(zhuǎn)", Toast.LENGTH_SHORT).show();
 return;
 }
 for (BlockUnit blockUnit : blockUnits) {
 int tx = blockUnit.x;
 int ty = blockUnit.y;
 blockUnit.x = -(ty - yy) + xx;
 blockUnit.y = tx - xx + yy;
 }
 routeTran(blockUnits);
 invalidate();
 }

 /**
 * 如果方塊處于邊緣,則翻轉(zhuǎn)過(guò)后,會(huì)出現(xiàn)方塊部分處于邊緣之外的情況, 因此,通過(guò)遞歸判斷是否有超出邊緣的部分,
 * 如果有,則進(jìn)行左右平移,把處于邊緣外的方塊移動(dòng)到邊緣內(nèi)
 */
 public void routeTran(List<BlockUnit> blockUnitsBuf) {
 boolean needLeftTran = false;
 boolean needRightTran = false;
 for (BlockUnit u : blockUnitsBuf) {
 if (u.x < beginPoint) {
 needLeftTran = true;
 }
 if (u.x > max_x - BlockUnit.UNIT_SIZE) {
 needRightTran = true;
 }
 }
 if (needLeftTran || needRightTran) {
 for (BlockUnit u : blockUnitsBuf) {
 if (needLeftTran) {
 u.x = u.x + BlockUnit.UNIT_SIZE;
 } else if (needRightTran) {
 u.x = u.x - BlockUnit.UNIT_SIZE;
 }
 }
 routeTran(blockUnitsBuf);
 } else {
 return;
 }

 }

 /**
 * 獲取一個(gè)新的方塊
 */
 private void getNewBlock() {
 // 新的方塊的坐標(biāo),x坐標(biāo)位于x軸的中間,y 位于起始位置
 this.xx = beginPoint + (num_x / 2) * BlockUnit.UNIT_SIZE;
 this.yy = beginPoint;
 if (blockUnitBufs.size() == 0) {
 // 當(dāng)游戲第一次開(kāi)始的時(shí)候,先初始化一個(gè)方塊
 blockUnitBufs = tetrisBlock.getUnits(xx, yy);
 }
 blockUnits = blockUnitBufs;
 blockType = tetrisBlock.blockType;
 blockUnitBufs = tetrisBlock.getUnits(xx, yy);
 if (father != null) {// 顯示出下一個(gè)要出現(xiàn)的方塊
 father.setNextBlockView(blockUnitBufs, (num_x / 2) * BlockUnit.UNIT_SIZE);
 }
 }

 /**
 * 游戲的主線程
 * 
 * @sign Created by wang.ao on 2017年1月16日
 */
 private class MainThread implements Runnable {

 @Override
 public void run() {
 while (gameStatus) {
 while (runningStatus) {
 if (BlockUnit.canMoveToDown(blockUnits, max_y, allBlockUnits)) {
 // 判斷是否可以繼續(xù)下落,如果可以下落,則下落
 BlockUnit.toDown(blockUnits, max_y, allBlockUnits);
 yy = yy + BlockUnit.UNIT_SIZE;
 } else {
 /**
 * 當(dāng)不可以繼續(xù)下落的時(shí)候,把當(dāng)前的方塊添加到allBlockUnits中,
 * 并且判斷是否有需要消除的方塊,然后再產(chǎn)生一個(gè)新的方塊
 */
 for (BlockUnit blockUnit : blockUnits) {
 blockUnit.y = blockUnit.y + BlockUnit.UNIT_SIZE;
 allBlockUnits.add(blockUnit);
 }
 for (BlockUnit u : blockUnits) {
 // 更新map,即更新每行網(wǎng)格中靜止俄羅斯方塊單元的個(gè)數(shù)
 int index = (int) ((u.y - beginPoint) / 50); // 計(jì)算所在行數(shù)
 map[index]++;
 }
 // 每行最大個(gè)數(shù)
 int end = (int) ((max_y - 50 - beginPoint) / BlockUnit.UNIT_SIZE);
 int full = (int) ((max_x - 50 - beginPoint) / BlockUnit.UNIT_SIZE) + 1;
 try {
 Thread.sleep(GameConfig.SPEED);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 for (int i = 0; i <= end; i++) {
 /***
 * 消除需要消除的方塊(觸發(fā)條件,某一行中被塞滿了方塊,沒(méi)有空白)
 * 注意順序,先消除某一行,再移動(dòng)這一行上邊的方塊
 */
 if (map[i] >= full) {
 BlockUnit.remove(allBlockUnits, i);
 score += 100;
 map[i] = 0;
 for (int j = i; j > 0; j--)
  map[j] = map[j - 1];
 map[0] = 0;
 for (BlockUnit blockUnit : allBlockUnits) {
  if (blockUnit.y < (i * BlockUnit.UNIT_SIZE + beginPoint)) {
  blockUnit.y = blockUnit.y + BlockUnit.UNIT_SIZE;
  }
 }
 }
 }
 father.runOnUiThread(new Runnable() {
 @Override
 public void run() {
 /**
  * 刷新分?jǐn)?shù)
  */
 father.score.setText("" + score);
 invalidate();
 }
 });
 try {
 Thread.sleep(GameConfig.SPEED * 3);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }
 father.runOnUiThread(new Runnable() {
 @Override
 public void run() {
 getNewBlock();
 score += 10;
 father.score.setText("" + score);
 }
 });
 }
 father.runOnUiThread(new Runnable() {
 @Override
 public void run() {
 invalidate();
 }
 });
 try {
 Thread.sleep(GameConfig.SPEED);
 } catch (InterruptedException e) {
 e.printStackTrace();
 }

 }
 }

 }

 }

}

BlockUnit.java方塊的單元塊,大家都玩過(guò)俄羅斯方塊,每一個(gè)方塊由四個(gè)單元塊組成。單元快應(yīng)該有以下屬性:①大?。?jiǎn)卧獕K的大小決定了主界面的容量(容納單元塊的數(shù)量);②顏色:每個(gè)單元塊都有一個(gè)顏色,美化游戲界面(可無(wú));③坐標(biāo):包括X軸坐標(biāo)、Y軸坐標(biāo),在繪制方塊的時(shí)候,以單元塊的坐標(biāo)為起點(diǎn)繪制,即:?jiǎn)卧獕K的坐標(biāo)值應(yīng)該為單元塊在界面上的左上角的坐標(biāo)。

此類(lèi)的主要功能有:方塊的下落,左右移動(dòng),判斷是否可以旋轉(zhuǎn)等功能都在此類(lèi)中,算是核心類(lèi)。

/**
 * 俄羅斯方塊的單元快
 * 
 * @sign Created by wang.ao on 2017年1月13日
 */
public class BlockUnit {
 public static final int UNIT_SIZE = 50;
 public static final int BEGIN = 10;
 public int color;
 // 單元塊 的坐標(biāo)
 public int x, y;

 public BlockUnit() {
 }

 public BlockUnit(int x, int y, int color) {
 /*
 * @param 單元塊橫縱坐標(biāo) 構(gòu)造函數(shù)
 */
 this.x = x;
 this.y = y;
 this.color = color;
 }

 /**
 * 判斷方塊是否可以向左移動(dòng),1是否在邊緣,2是否會(huì)與其他方塊重合
 * @param blockUnits 當(dāng)前正在下落的方塊
 * @param max_x 游戲主界面X軸的最大值 ,下同
 * @param allBlockUnits 所有的方塊
 * @return 能移動(dòng)true;不能移動(dòng)false
 */
 public static boolean canMoveToLeft(List<BlockUnit> blockUnits, int max_x, List<BlockUnit> allBlockUnits) {
 for (BlockUnit blockUnit : blockUnits) {
 int x = blockUnit.x;
 if (x - UNIT_SIZE < BEGIN) {
 return false;
 }
 int y = blockUnit.y;
 if (isSameUnit(x - UNIT_SIZE, y, allBlockUnits)) {
 return false;
 }
 }
 return true;
 }

 /**
 * 判斷方塊是否可以向右移動(dòng),1是否在邊緣,2是否會(huì)與其他方塊重合
 * @param blockUnits 當(dāng)前正在下落的方塊
 * @param max_x 游戲主界面X軸的最大值 ,下同
 * @param allBlockUnits 所有的方塊
 * @return 能移動(dòng)true;不能移動(dòng)false
 */
 public static boolean canMoveToRight(List<BlockUnit> blockUnits, int max_x, List<BlockUnit> allBlockUnits) {
 for (BlockUnit blockUnit : blockUnits) {
 int x = blockUnit.x;
 if (x + UNIT_SIZE > max_x - UNIT_SIZE) {
 return false;
 }
 int y = blockUnit.y;
 if (isSameUnit(x + UNIT_SIZE, y, allBlockUnits)) {
 return false;
 }
 }
 return true;
 }
 /**
 * 判斷方塊是否可以向下移動(dòng),1是否在邊緣,2是否會(huì)與其他方塊重合
 * @param blockUnits 當(dāng)前正在下落的方塊
 * @param max_x 游戲主界面X軸的最大值 ,下同
 * @param allBlockUnits 所有的方塊
 * @return 能移動(dòng)true;不能移動(dòng)false
 */
 public static boolean canMoveToDown(List<BlockUnit> blockUnits, int max_y, List<BlockUnit> allBlockUnits) {
 for (BlockUnit blockUnit : blockUnits) {
 int x = blockUnit.x;
 int y = blockUnit.y + UNIT_SIZE * 2;
 if (y > max_y - UNIT_SIZE) {
 return false;
 }
 if (isSameUnit(x, y, allBlockUnits)) {
 return false;
 }
 }
 return true;
 }
 public static boolean canRoute(List<BlockUnit> blockUnits, List<BlockUnit> allBlockUnits){
 for (BlockUnit blockUnit: blockUnits) {
 if(isSameUnit(blockUnit.x, blockUnit.y, allBlockUnits)){
 return false;
 }
 }
 return true;
 }

 /**
 * 把當(dāng)前方塊向左移動(dòng)一格
 * @param blockUnits
 * @param max_x
 * @param allBlockUnits
 * @return 是否成功移動(dòng)一格,是:true,否:false
 */
 public static boolean toLeft(List<BlockUnit> blockUnits, int max_x, List<BlockUnit> allBlockUnits) {
 if (canMoveToLeft(blockUnits, max_x, allBlockUnits)) {
 for (BlockUnit blockUnit : blockUnits) {
 blockUnit.x = blockUnit.x - UNIT_SIZE;
 }
 return true;
 }
 return false;
 }
 /**
 * 把當(dāng)前方塊向右移動(dòng)一格
 * @param blockUnits
 * @param max_x
 * @param allBlockUnits
 * @return 是否成功移動(dòng)一格,是:true,否:false
 */
 public static boolean toRight(List<BlockUnit> blockUnits, int max_x, List<BlockUnit> allBlockUnits) {
 if (canMoveToRight(blockUnits, max_x, allBlockUnits)) {
 for (BlockUnit blockUnit : blockUnits) {
 blockUnit.x = blockUnit.x + UNIT_SIZE;
 }
 return true;
 }
 return false;
 }

 /**
 * 把當(dāng)前方塊下落一格
 * @param blockUnits
 * @param allBlockUnits
 * @return 是否成功移動(dòng)一格,是:true,否:false
 */
 public static void toDown(List<BlockUnit> blockUnits, int max_Y, List<BlockUnit> allBlockUnits) {
 for (BlockUnit blockUnit : blockUnits) {
 blockUnit.y = blockUnit.y + BlockUnit.UNIT_SIZE;
 }
 }

 /**
 * 判斷 方塊單元是否和所有方塊有重合
 * @param x
 * @param y
 * @param allBlockUnits
 * @return
 */
 public static boolean isSameUnit(int x, int y, List<BlockUnit> allBlockUnits) {
 for (BlockUnit blockUnit : allBlockUnits) {
 if (Math.abs(x - blockUnit.x) < UNIT_SIZE && Math.abs(y - blockUnit.y) < UNIT_SIZE) {
 return true;
 }
 }
 return false;
 }

 /**
 * 刪除在第j行上的方塊單元
 * @param allBlockUnits
 * @param j 需刪除行標(biāo)
 */
 public static void remove(List<BlockUnit> allBlockUnits, int j) {
 for (int i = allBlockUnits.size() - 1; i >= 0; i--) {
 /*
 * ①逆向遍歷 ②根據(jù)y坐標(biāo)計(jì)算單元所在行,若為j行則從units中刪除
 */
 if ((int) ((allBlockUnits.get(i).y - BEGIN) / 50) == j)
 allBlockUnits.remove(i);
 }
 }
}

TetrisBlock.java用于產(chǎn)生不同形狀的方塊,共有其中類(lèi)型。

/**
 * 方塊
 * 
 * @sign Created by wang.ao on 2017年1月13日
 */
public class TetrisBlock {
 private static final int TYPE_SUM = 7;
 public int blockType, blockDirection; // 方塊種類(lèi),方塊朝向

 private int color; // 方塊顏色

 private int x, y; // 方塊坐標(biāo)

 public TetrisBlock() {

 }

 public TetrisBlock(int x, int y) {
 this.x = x;
 this.y = y;
 }

 public List<BlockUnit> getUnits(int x, int y) {
 this.x = x;
 this.y = y;
 return returnUnit();
 }

 /**
 * 隨機(jī)產(chǎn)生一種方塊
 * @return
 */
 public List<BlockUnit> returnUnit() {
 List<BlockUnit> units = new ArrayList<BlockUnit>(); // 方塊組成部分
 blockType = (int) (Math.random() * TYPE_SUM) + 1; // 隨機(jī)生成一個(gè)種類(lèi)
 blockDirection = 1; // 默認(rèn)初始方向
 color = (int) (Math.random() * 4) + 1; // 隨機(jī)生成一個(gè)顏色
 units.clear();
 switch (blockType) {
 case 1:// 橫線
 for (int i = 0; i < 4; i++) {
 units.add(new BlockUnit(x + (-2 + i) * BlockUnit.UNIT_SIZE, y, color));
 }
 break;
 case 2:
 units.add(new BlockUnit(x + (-1 + 1) * BlockUnit.UNIT_SIZE, y - BlockUnit.UNIT_SIZE, color));
 for (int i = 0; i < 3; i++) {
 units.add(new BlockUnit(x + (-1 + i) * BlockUnit.UNIT_SIZE, y, color));
 }
 break;
 case 3:
 for (int i = 0; i < 2; i++) {
 units.add(new BlockUnit(x + (i - 1) * BlockUnit.UNIT_SIZE, y - BlockUnit.UNIT_SIZE, color));
 units.add(new BlockUnit(x + (i - 1) * BlockUnit.UNIT_SIZE, y, color));
 }
 break;
 case 4:
 units.add(new BlockUnit(x + (-1 + 0) * BlockUnit.UNIT_SIZE, y - BlockUnit.UNIT_SIZE, color));
 for (int i = 0; i < 3; i++) {
 units.add(new BlockUnit(x + (-1 + i) * BlockUnit.UNIT_SIZE, y, color));
 }
 break;
 case 5:
 units.add(new BlockUnit(x + (-1 + 2) * BlockUnit.UNIT_SIZE, y - BlockUnit.UNIT_SIZE, color));
 for (int i = 0; i < 3; i++) {
 units.add(new BlockUnit(x + (-1 + i) * BlockUnit.UNIT_SIZE, y, color));
 }
 break;
 case 6:
 for (int i = 0; i < 2; i++) {
 units.add(new BlockUnit(x + (-1 + i) * BlockUnit.UNIT_SIZE, y - BlockUnit.UNIT_SIZE, color));
 units.add(new BlockUnit(x + i * BlockUnit.UNIT_SIZE, y, color));
 }
 break;
 case 7:
 for (int i = 0; i < 2; i++) {
 units.add(new BlockUnit(x + i * BlockUnit.UNIT_SIZE, y - BlockUnit.UNIT_SIZE, color));
 units.add(new BlockUnit(x + (-1 + i) * BlockUnit.UNIT_SIZE, y, color));
 }
 break;
 }
 return units;
 }

NextBlockView.java其實(shí)就是游戲主界面的一個(gè)縮減版,用于顯示下一個(gè)要出現(xiàn)的方塊的,玩家可以明確的知道下一個(gè)方塊的形狀和顏色。

/**
 * 下一個(gè)要展示的方塊
 * 
 * @sign Created by wang.ao on 2017年1月13日
 */
@SuppressLint("DrawAllocation")
public class NextBlockView extends View {
 /** 網(wǎng)格開(kāi)始坐標(biāo)值,橫縱坐標(biāo)的開(kāi)始值都是此值 */
 public static final int beginPoint = 10;
 /** 俄羅斯方塊的最大坐標(biāo) */
 private static int max_x, max_y;
 private List<BlockUnit> blockUnits = new ArrayList<BlockUnit>();
 /** 背景墻畫(huà)筆 */
 private static Paint paintWall = null;
 private static final int BOUND_WIDTH_OF_WALL = 2;
 private static Paint paintBlock = null;
 private int div_x = 0;
 // 俄羅斯方塊顏色數(shù)組
 private static final int color[] ={ Color.parseColor("#FF6600"), Color.BLUE, Color.RED, Color.GREEN, Color.GRAY };

 public NextBlockView(Context context) {
 this(context, null);
 }

 public NextBlockView(Context context, AttributeSet attrs) {
 super(context, attrs);
 if (paintWall == null) {// 初始化化背景墻畫(huà)筆
 paintWall = new Paint();
 paintWall.setColor(Color.LTGRAY);
 paintWall.setStyle(Paint.Style.STROKE);
 paintWall.setStrokeWidth(BOUND_WIDTH_OF_WALL + 1);
 }
 if (paintBlock == null) {// 初始化化背景墻畫(huà)筆
 paintBlock = new Paint();
 paintBlock.setColor(Color.parseColor("#FF6600"));
 }
 }

 public void setBlockUnits(List<BlockUnit> blockUnits, int div_x) {
 this.blockUnits = blockUnits;
 this.div_x = div_x;
 invalidate();
 }

 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 max_x = getWidth();
 max_y = getHeight();
 RectF rel;
 // 繪制網(wǎng)格
 int len = blockUnits.size();
 // 繪制方塊
 // Toast.makeText(context, "" + len, Toast.LENGTH_SHORT).show();
 for (int i = 0; i < len; i++) {
 paintBlock.setColor(color[blockUnits.get(i).color]);
 int x = blockUnits.get(i).x - div_x + BlockUnit.UNIT_SIZE * 2;
 int y = blockUnits.get(i).y + BlockUnit.UNIT_SIZE * 2;
 rel = new RectF(x + BOUND_WIDTH_OF_WALL, y + BOUND_WIDTH_OF_WALL,
 x + BlockUnit.UNIT_SIZE - BOUND_WIDTH_OF_WALL, y + BlockUnit.UNIT_SIZE - BOUND_WIDTH_OF_WALL);
 canvas.drawRoundRect(rel, 8, 8, paintBlock);
 rel = new RectF(x, y, x + BlockUnit.UNIT_SIZE, y + BlockUnit.UNIT_SIZE);
 canvas.drawRoundRect(rel, 8, 8, paintWall);
 }
 }

}

GameConfig.java用于配置方塊的下落速度

public class GameConfig {
 /**方塊下落的速度*/
 public static final int SPEED = 300;
}

TetrisActivityAW.java主界面,包括游戲主界面和控制臺(tái),很簡(jiǎn)單,直接貼代碼。

public class TetrisActivityAW extends Activity {
 private NextBlockView nextBlockView;
 private TetrisViewAW tetrisViewAW;
 private TextView gameStatusTip;
 public TextView score;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_tetris_activity_aw);
 nextBlockView = (NextBlockView) findViewById(R.id.nextBlockView1);
 tetrisViewAW = (TetrisViewAW) findViewById(R.id.tetrisViewAW1);
 tetrisViewAW.setFather(this);
 gameStatusTip = (TextView) findViewById(R.id.game_staus_tip);
 score = (TextView) findViewById(R.id.score);
 }

 public void setNextBlockView(List<BlockUnit> blockUnits, int div_x) {
 nextBlockView.setBlockUnits(blockUnits, div_x);
 }

 /**
 * 開(kāi)始游戲
 * 
 * @param view
 */
 public void startGame(View view) {
 tetrisViewAW.startGame();
 gameStatusTip.setText("游戲運(yùn)行中");
 }

 /**
 * 暫停游戲
 */
 public void pauseGame(View view) {
 tetrisViewAW.pauseGame();
 gameStatusTip.setText("游戲已暫停");
 }

 /**
 * 繼續(xù)游戲
 */
 public void continueGame(View view) {
 tetrisViewAW.continueGame();
 gameStatusTip.setText("游戲運(yùn)行中");
 }

 /**
 * 停止游戲
 */
 public void stopGame(View view) {
 tetrisViewAW.stopGame();
 score.setText(""+0);
 gameStatusTip.setText("游戲已停止");
 }

 /**
 * 向左滑動(dòng)
 */
 public void toLeft(View view) {
 tetrisViewAW.toLeft();
 }

 /**
 * 向右滑動(dòng)
 */
 public void toRight(View view) {
 tetrisViewAW.toRight();
 }
 /**
 * 向右滑動(dòng)
 */
 public void toRoute(View view) {
 tetrisViewAW.route();
 }
}

TetrisActivityAW activity的xml文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 tools:context="${relativePackage}.${activityClass}" >

 <com.awang.media.minetetris.TetrisViewAW
 android:id="@+id/tetrisViewAW1"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_marginBottom="200dp"
 android:layout_marginRight="120dp" />

 <com.awang.media.minetetris.NextBlockView
 android:id="@+id/nextBlockView1"
 android:layout_width="120dp"
 android:layout_height="120dp"
 android:layout_alignParentRight="true" />

 <LinearLayout
 android:layout_width="110dp"
 android:layout_height="wrap_content"
 android:layout_alignParentRight="true"
 android:layout_below="@+id/nextBlockView1"
 android:layout_marginTop="20dp"
 android:orientation="vertical" >

 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:orientation="horizontal" >

 <TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="分?jǐn)?shù)" />

 <TextView
 android:id="@+id/score"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginLeft="10dp"
 android:text="1" />
 </LinearLayout>

 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:layout_marginTop="20dp"
 android:orientation="horizontal" >

 <TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="等級(jí)" />

 <TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginLeft="10dp"
 android:text="1" />
 </LinearLayout>

 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:layout_marginTop="20dp"
 android:orientation="horizontal" >

 <TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="速度" />

 <TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginLeft="10dp"
 android:text="0" />
 </LinearLayout>

 <LinearLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:layout_marginTop="20dp"
 android:orientation="horizontal" >

 <TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="最高分" />

 <TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginLeft="10dp"
 android:text="0" />
 </LinearLayout>

 <Button
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginTop="10dp"
 android:onClick="startGame"
 android:text="開(kāi)始" />

 <Button
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:onClick="pauseGame"
 android:text="暫停" />

 <Button
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:onClick="continueGame"
 android:text="繼續(xù)" />

 <Button
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:onClick="stopGame"
 android:text="結(jié)束" />
 </LinearLayout>

 <RelativeLayout
 android:layout_width="match_parent"
 android:layout_height="200dp"
 android:layout_alignParentBottom="true" >

 <Button
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:onClick="toLeft"
 android:text="左" />

 <TextView
 android:id="@+id/game_staus_tip"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_centerHorizontal="true"
 android:layout_marginTop="5dp"
 android:text="點(diǎn)擊開(kāi)始運(yùn)行游戲"
 android:textSize="20sp" />
 <Button
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:layout_centerInParent="true"
 android:onClick="toRoute"
 android:text="旋轉(zhuǎn)" />
 <Button
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:layout_alignParentRight="true"
 android:onClick="toRight"
 android:text="右" />
 </RelativeLayout>

</RelativeLayout>

整個(gè)項(xiàng)目就是這些,代碼已經(jīng)全部貼出來(lái)了。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Android實(shí)現(xiàn)俄羅斯方塊的方法”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!

分享文章:Android實(shí)現(xiàn)俄羅斯方塊的方法
網(wǎng)頁(yè)路徑:http://jinyejixie.com/article14/ijggge.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)、、搜索引擎優(yōu)化、域名注冊(cè)、響應(yīng)式網(wǎng)站、品牌網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

小程序開(kāi)發(fā)
阿拉善盟| 天水市| 商都县| 图木舒克市| 大新县| 德钦县| 西畴县| 大新县| 通化市| 衡水市| 耿马| 博白县| 虞城县| 吉林市| 尼勒克县| 宣威市| 宁明县| 临城县| 永城市| 龙陵县| 鄂托克前旗| 阿巴嘎旗| 镇巴县| 乐平市| 郯城县| 萨迦县| 兴义市| 泸水县| 邵阳县| 新化县| 洛隆县| 潢川县| 宁阳县| 牙克石市| 临泉县| 土默特右旗| 桂东县| 芜湖县| 四平市| 雷州市| 鸡东县|