亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android實現俄羅斯方塊的方法

發布時間:2021-04-16 09:32:31 來源:億速云 閱讀:331 作者:小新 欄目:移動開發

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

具體內容如下

思路:

  • 首先要畫出游戲背景墻;

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

  • 方塊的不同形狀,顏色隨機產生;

  • 游戲的控制面板。

可能會出現的問題或者難點:

邊界問題:

①處于邊界的時候,方塊不可以再左右移動;
②下降的時候,到達邊界即底部,則不可繼續下落,此時應該產生一個新的方塊;

與其它方塊接觸問題:

①下落的時候,如果碰到其它的方塊則停止下落;
②左右移動的時候,移動的過程中,如果接觸到其他方快,則不可再繼續左右移動;

方塊的消除:

①調用方塊消除方法的時間:當方塊下落到底部的時候,判斷是否有需要消除的行;
②消除某一行之后,應該把這一行上面的全部方塊下移一行;

方塊的旋轉:

在當前項目中,我采用的是順時針旋轉。
①當旋轉的時候,如果出現方塊部分超出了邊界,應該對方塊進行平移,使其回到邊界以內。(曾在網上看到有人做過,判斷旋轉之后是否會超出邊界,如果會超出,則不進行旋轉,我覺得不好,方塊只要沒有下落到底部,我覺得都可以進行旋轉,除了沒有空間讓其旋轉外);
②如果空間不足以旋轉,也不可以旋轉。空間不足以旋轉的意思是:比如橫向方向只有兩個的空間,而方塊旋轉后會占用三個空間,此時也不可進行旋轉;
③當無法繼續下落或者下落到了底部也不可再進行旋轉

控制面板:

①游戲開始、暫停、繼續、結束,這些狀態應該怎么去控制,以及游戲與控制臺的事件關聯。

未發現的問題:

因為本人能力,只做到這么多,如果有人發現問題,可以留言交流,歡迎挑問題。

游戲的運行界面如下所示,基本的功能以及操作很簡單。

Android實現俄羅斯方塊的方法

下面直接看項目代碼
項目文件結構

Android實現俄羅斯方塊的方法

下面分別介紹每個類的功能

TetrisViewAW.java游戲的主界面,背景墻以及方塊都在此TetrisViewAW.Java里面,就是一個自定義的View ,(默認大家對于自定義View是熟悉的),在改類里面,有一個游戲主線程,用于控制游戲的開始,暫停,繼續,停止,以及方塊下落的速率。代碼我加了很多注釋,看不懂的可以留言。還有一點需要注意,當停止游戲時,要釋放線程,養成好習慣

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

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

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

 /**
 * 設置當前游戲頁面的父類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;
 // 繪制網格
 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++;
 }
 // 隨機產生一個俄羅斯方塊
 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;
 // 設置當前方塊的顏色
 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);
 }
 // 隨機產生一個俄羅斯方塊
 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);
 }
 }

 /**
 * 開始游戲
 */
 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;
 }

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

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

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

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

 /**
 * 按順時針旋轉
 */
 public void route() {
 if (blockType == 3) {// 如果當前正在下落的方塊為正方形,則不進行旋轉
 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, "不可旋轉", 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();
 }

 /**
 * 如果方塊處于邊緣,則翻轉過后,會出現方塊部分處于邊緣之外的情況, 因此,通過遞歸判斷是否有超出邊緣的部分,
 * 如果有,則進行左右平移,把處于邊緣外的方塊移動到邊緣內
 */
 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;
 }

 }

 /**
 * 獲取一個新的方塊
 */
 private void getNewBlock() {
 // 新的方塊的坐標,x坐標位于x軸的中間,y 位于起始位置
 this.xx = beginPoint + (num_x / 2) * BlockUnit.UNIT_SIZE;
 this.yy = beginPoint;
 if (blockUnitBufs.size() == 0) {
 // 當游戲第一次開始的時候,先初始化一個方塊
 blockUnitBufs = tetrisBlock.getUnits(xx, yy);
 }
 blockUnits = blockUnitBufs;
 blockType = tetrisBlock.blockType;
 blockUnitBufs = tetrisBlock.getUnits(xx, yy);
 if (father != null) {// 顯示出下一個要出現的方塊
 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)) {
 // 判斷是否可以繼續下落,如果可以下落,則下落
 BlockUnit.toDown(blockUnits, max_y, allBlockUnits);
 yy = yy + BlockUnit.UNIT_SIZE;
 } else {
 /**
 * 當不可以繼續下落的時候,把當前的方塊添加到allBlockUnits中,
 * 并且判斷是否有需要消除的方塊,然后再產生一個新的方塊
 */
 for (BlockUnit blockUnit : blockUnits) {
 blockUnit.y = blockUnit.y + BlockUnit.UNIT_SIZE;
 allBlockUnits.add(blockUnit);
 }
 for (BlockUnit u : blockUnits) {
 // 更新map,即更新每行網格中靜止俄羅斯方塊單元的個數
 int index = (int) ((u.y - beginPoint) / 50); // 計算所在行數
 map[index]++;
 }
 // 每行最大個數
 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++) {
 /***
 * 消除需要消除的方塊(觸發條件,某一行中被塞滿了方塊,沒有空白)
 * 注意順序,先消除某一行,再移動這一行上邊的方塊
 */
 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() {
 /**
  * 刷新分數
  */
 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方塊的單元塊,大家都玩過俄羅斯方塊,每一個方塊由四個單元塊組成。單元快應該有以下屬性:①大小:單元塊的大小決定了主界面的容量(容納單元塊的數量);②顏色:每個單元塊都有一個顏色,美化游戲界面(可無);③坐標:包括X軸坐標、Y軸坐標,在繪制方塊的時候,以單元塊的坐標為起點繪制,即:單元塊的坐標值應該為單元塊在界面上的左上角的坐標。

此類的主要功能有:方塊的下落,左右移動,判斷是否可以旋轉等功能都在此類中,算是核心類。

/**
 * 俄羅斯方塊的單元快
 * 
 * @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;
 // 單元塊 的坐標
 public int x, y;

 public BlockUnit() {
 }

 public BlockUnit(int x, int y, int color) {
 /*
 * @param 單元塊橫縱坐標 構造函數
 */
 this.x = x;
 this.y = y;
 this.color = color;
 }

 /**
 * 判斷方塊是否可以向左移動,1是否在邊緣,2是否會與其他方塊重合
 * @param blockUnits 當前正在下落的方塊
 * @param max_x 游戲主界面X軸的最大值 ,下同
 * @param allBlockUnits 所有的方塊
 * @return 能移動true;不能移動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;
 }

 /**
 * 判斷方塊是否可以向右移動,1是否在邊緣,2是否會與其他方塊重合
 * @param blockUnits 當前正在下落的方塊
 * @param max_x 游戲主界面X軸的最大值 ,下同
 * @param allBlockUnits 所有的方塊
 * @return 能移動true;不能移動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;
 }
 /**
 * 判斷方塊是否可以向下移動,1是否在邊緣,2是否會與其他方塊重合
 * @param blockUnits 當前正在下落的方塊
 * @param max_x 游戲主界面X軸的最大值 ,下同
 * @param allBlockUnits 所有的方塊
 * @return 能移動true;不能移動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;
 }

 /**
 * 把當前方塊向左移動一格
 * @param blockUnits
 * @param max_x
 * @param allBlockUnits
 * @return 是否成功移動一格,是: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;
 }
 /**
 * 把當前方塊向右移動一格
 * @param blockUnits
 * @param max_x
 * @param allBlockUnits
 * @return 是否成功移動一格,是: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;
 }

 /**
 * 把當前方塊下落一格
 * @param blockUnits
 * @param allBlockUnits
 * @return 是否成功移動一格,是: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 需刪除行標
 */
 public static void remove(List<BlockUnit> allBlockUnits, int j) {
 for (int i = allBlockUnits.size() - 1; i >= 0; i--) {
 /*
 * ①逆向遍歷 ②根據y坐標計算單元所在行,若為j行則從units中刪除
 */
 if ((int) ((allBlockUnits.get(i).y - BEGIN) / 50) == j)
 allBlockUnits.remove(i);
 }
 }
}

TetrisBlock.java用于產生不同形狀的方塊,共有其中類型。

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

 private int color; // 方塊顏色

 private int x, y; // 方塊坐標

 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();
 }

 /**
 * 隨機產生一種方塊
 * @return
 */
 public List<BlockUnit> returnUnit() {
 List<BlockUnit> units = new ArrayList<BlockUnit>(); // 方塊組成部分
 blockType = (int) (Math.random() * TYPE_SUM) + 1; // 隨機生成一個種類
 blockDirection = 1; // 默認初始方向
 color = (int) (Math.random() * 4) + 1; // 隨機生成一個顏色
 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其實就是游戲主界面的一個縮減版,用于顯示下一個要出現的方塊的,玩家可以明確的知道下一個方塊的形狀和顏色。

/**
 * 下一個要展示的方塊
 * 
 * @sign Created by wang.ao on 2017年1月13日
 */
@SuppressLint("DrawAllocation")
public class NextBlockView extends View {
 /** 網格開始坐標值,橫縱坐標的開始值都是此值 */
 public static final int beginPoint = 10;
 /** 俄羅斯方塊的最大坐標 */
 private static int max_x, max_y;
 private List<BlockUnit> blockUnits = new ArrayList<BlockUnit>();
 /** 背景墻畫筆 */
 private static Paint paintWall = null;
 private static final int BOUND_WIDTH_OF_WALL = 2;
 private static Paint paintBlock = null;
 private int div_x = 0;
 // 俄羅斯方塊顏色數組
 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) {// 初始化化背景墻畫筆
 paintWall = new Paint();
 paintWall.setColor(Color.LTGRAY);
 paintWall.setStyle(Paint.Style.STROKE);
 paintWall.setStrokeWidth(BOUND_WIDTH_OF_WALL + 1);
 }
 if (paintBlock == null) {// 初始化化背景墻畫筆
 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;
 // 繪制網格
 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主界面,包括游戲主界面和控制臺,很簡單,直接貼代碼。

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);
 }

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

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

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

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

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

 /**
 * 向右滑動
 */
 public void toRight(View view) {
 tetrisViewAW.toRight();
 }
 /**
 * 向右滑動
 */
 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="分數" />

 <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="等級" />

 <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="開始" />

 <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="繼續" />

 <Button
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:onClick="stopGame"
 android:text="結束" />
 </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="點擊開始運行游戲"
 android:textSize="20sp" />
 <Button
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:layout_centerInParent="true"
 android:onClick="toRoute"
 android:text="旋轉" />
 <Button
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:layout_alignParentRight="true"
 android:onClick="toRight"
 android:text="右" />
 </RelativeLayout>

</RelativeLayout>

整個項目就是這些,代碼已經全部貼出來了。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Android實現俄羅斯方塊的方法”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

石景山区| 双江| 资讯| 邯郸市| 淮阳县| 天柱县| 遂平县| 浦城县| 海兴县| 谷城县| 鹿泉市| 石城县| 靖边县| 嘉荫县| 宜阳县| 巴塘县| 邯郸县| 淮安市| 镇平县| 屯昌县| 珲春市| 延津县| 马尔康县| 清原| 化隆| 新邵县| 沾益县| 清水县| 凤翔县| 鲜城| 新疆| 乌拉特后旗| 迭部县| 来宾市| 富裕县| 高邑县| 璧山县| 文安县| 汉源县| 翁牛特旗| 苗栗县|