手把手教你寫Android 貪吃蛇 遊戲

原文www.zhangman523.cn/18.htmlhtml

先看看效果圖git

貪吃蛇設計思路

貪吃蛇分爲3個對象:github

  • canvas

  • 食物數組

  • 舞臺dom

舞臺咱們能夠看做爲一個二維數組 蛇和食物 都是數組中的元素ide

蛇是一串數組中的連續的元素 分爲蛇的頭元素和蛇身長度this

食物能夠看做是數組中的一個元素spa

蛇的移動

蛇能夠向上,向下,向左,向右移動設計

蛇移動 頭元素+1 尾元素-1

碰撞檢測

當蛇的頭部元素碰撞到食物 則吃掉食物 蛇長度+1。 若是碰撞到蛇身 遊戲結束,到舞臺邊界 直接穿過去

隨機生成食物

使用Random 生成食物座標 x,和y 生成後判斷是否是在蛇身座標上,若是是從新生成。

代碼實現

首先咱們使用自定義View 來實現

public class SnakePanelView extends View {
  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //繪製界面...
  }
}複製代碼

而後咱們定義格子元素

public class GridSquare {
  private int mType;//元素類型

  public GridSquare(int type) {
    mType = type;
  }

  public int getColor() {
    switch (mType) {
      case GameType.GRID://空格子
        return Color.WHITE;
      case GameType.FOOD://食物
        return Color.BLUE;
      case GameType.SNAKE://蛇
        return Color.parseColor("#FF4081");
    }
    return Color.WHITE;
  }

  public void setType(int type) {
    mType = type;
  }
}
複製代碼

這個就是格子對象

而後咱們定義出的二維數組舞臺定義以下:

private List> mGridSquare = new ArrayList<>();
複製代碼

定義出了舞臺數組 咱們須要定義食物的位置和蛇的位置。因此咱們須要定義一個對象 這個對象須要兩個成員變量 xy 來標示在舞臺中的位置

public class GridPosition {
  private int x;
  private int y;

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

  public int getX() {
    return x;
  }

  public void setX(int x) {
    this.x = x;
  }

  public int getY() {
    return y;
  }

  public void setY(int y) {
    this.y = y;
  }
}
複製代碼

而後咱們須要定義蛇頭位置、蛇身List 和食物的位置

private List mSnakePositions = new ArrayList<>();
  private GridPosition mSnakeHeader;//蛇頭部位置
  private GridPosition mFoodPosition;//食物的位置
複製代碼

而後咱們須要定義蛇的一系列屬性:速度、蛇身長度和運動方向。

private int mSnakeLength = 3;//蛇身長度
 private long mSpeed = 8;//運行速度 值越大 速度越快
 private int mSnakeDirection = GameType.RIGHT;//運行方向 
複製代碼

讓蛇運動起來咱們須要一個遊戲主循環 咱們能夠簡單定義一個循環

private class GameMainThread extends Thread {

    @Override
    public void run() {
      while (true) {
        //todo...
      }
    }
}
複製代碼

咱們在循環裏處理蛇移動、碰撞檢測和食物生產等操做。

處理蛇的移動方法:

private void moveSnake(int snakeDirection) {
    switch (snakeDirection) {
      case GameType.LEFT:
        if (mSnakeHeader.getX() - 1 < 0) {//邊界判斷:若是到了最左邊 讓他穿過屏幕到最右邊 mGridSize 爲舞臺大小
          mSnakeHeader.setX(mGridSize - 1);
        } else {
          mSnakeHeader.setX(mSnakeHeader.getX() - 1);
        }
        mSnakePositions.add(new GridPosition(mSnakeHeader.getX(), mSnakeHeader.getY()));
        break;
      case GameType.TOP:
        if (mSnakeHeader.getY() - 1 < 0) {
          mSnakeHeader.setY(mGridSize - 1);
        } else {
          mSnakeHeader.setY(mSnakeHeader.getY() - 1);
        }
        mSnakePositions.add(new GridPosition(mSnakeHeader.getX(), mSnakeHeader.getY()));
        break;
      case GameType.RIGHT:
        if (mSnakeHeader.getX() + 1 >= mGridSize) {
          mSnakeHeader.setX(0);
        } else {
          mSnakeHeader.setX(mSnakeHeader.getX() + 1);
        }
        mSnakePositions.add(new GridPosition(mSnakeHeader.getX(), mSnakeHeader.getY()));
        break;
      case GameType.BOTTOM:
        if (mSnakeHeader.getY() + 1 >= mGridSize) {
          mSnakeHeader.setY(0);
        } else {
          mSnakeHeader.setY(mSnakeHeader.getY() + 1);
        }
        mSnakePositions.add(new GridPosition(mSnakeHeader.getX(), mSnakeHeader.getY()));
        break;
    }
}
複製代碼

處理碰撞:

//檢測碰撞
private void checkCollision() {
//檢測是否咬到本身
GridPosition headerPosition = mSnakePositions.get(mSnakePositions.size() - 1);
for (int i = 0; i < mSnakePositions.size() - 2; i++) {
GridPosition position = mSnakePositions.get(i);
if (headerPosition.getX() == position.getX() && headerPosition.getY() == position.getY()) {
//咬到本身 中止遊戲
mIsEndGame = true;
showMessageDialog();
return;
}
}
//判斷是否吃到食物
if (headerPosition.getX() == mFoodPosition.getX()
&& headerPosition.getY() == mFoodPosition.getY()) {
mSnakeLength++;
generateFood();
}
}
複製代碼

隨機生成食物:

private void generateFood() {
Random random = new Random();
int foodX = random.nextInt(mGridSize - 1);
int foodY = random.nextInt(mGridSize - 1);
for (int i = 0; i < mSnakePositions.size() - 1; i++) {
if (foodX == mSnakePositions.get(i).getX() && foodY == mSnakePositions.get(i).getY()) {
//不能生成在蛇身上
foodX = random.nextInt(mGridSize - 1);
foodY = random.nextInt(mGridSize - 1);
//從新循環
i = 0;
}
}
mFoodPosition.setX(foodX);
mFoodPosition.setY(foodY);
refreshFood(mFoodPosition);
}
複製代碼

基本的遊戲邏輯已經完成。

工程已經放在GITHUb

相關文章
相關標籤/搜索