2023年12月14日 星期四

WEEK14 期末作品進度

 期末作品進度: 做出遊戲開始畫面 包含level1 level2 level3 三個按鈕 分別進入3個關卡

程式碼: 

PImage bombImage;  // 儲存炸彈的圖片
boolean gameover = false;
int gameoverTime, cellSize;
int[][] mine ; 
boolean[][] open ;
int selectedLevel = 0;//0表示未選擇級別 1表示第一關 2.... 3...
int gameState = 0;  // 0表示起始畫面,1表示遊戲中
int rows, cols, totalMines;

void openAll(int i, int j) {
  if (i < 0 || j < 0 || i >= 10 || j >= 10 || gameover) return;
  if (open[i][j] == true) return;

  open[i][j] = true;
  //如果是炸彈,顯示所有炸彈
  if (mine[i][j] == 9) {
    revealAllBombs();
    gameover = true;
    gameoverTime = millis();//紀錄遊戲結束時間
  }
  //如果是0,則遞迴打開相鄰格子
  if (mine[i][j] == 0) {
    openAll(i - 1, j);
    openAll(i, j - 1);
    openAll(i, j + 1);
    openAll(i + 1, j);
  }
}

void addOne(int i, int j) {
  if (i < 0 || j < 0 || i >= 10 || j >= 10) return;//範圍外,不處理
  if (mine[i][j] == 9) return;//地雷本身不用再+1
  mine[i][j]++;//如果不是就+1
}

void revealAllBombs() {
  //將所有炸彈顯示為已開啟,以顯示所有炸彈
  for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      if (mine[i][j] == 9) {
        open[i][j] = true;
      }
    }
  }
}

void setup() {
  size(500, 500);
  cellSize = width / 10;//根據視窗大小和格子數量計算格子大小
  int mineCount = 0;
  //載入炸彈圖片
  bombImage = loadImage("bomb.png");
}

void draw()
{
  background(255);

  if (gameState == 0) 
  {
    // 起始畫面 level1 按鈕
    fill(100, 100, 200);
    rect(width / 4, height / 2 - 25, width / 2, 50);
    
    fill(255);
    textSize(20);
    textAlign(CENTER, CENTER);
    text("LEVEL1", width / 2, height / 2 - 5);
   
    
    //level2 按鈕
    fill(100, 100, 200);
    rect(width / 4, height / 2 + 25, width / 2, 50);
    fill(255);
    textSize(20);
    textAlign(CENTER, CENTER);
    text("LEVEL2", width / 2, height / 2 + 45);
    
  
    
    //level3 按鈕
    fill(100, 100, 200);
    rect(width / 4, height / 2 + 75, width / 2, 50);
    fill(255);
    textSize(20);
    textAlign(CENTER, CENTER);
    text("LEVEL3", width / 2, height / 2 + 95);
  } 
  else if (gameState == 1) 
  {
    // 踩地雷遊戲
    for (int i = 0; i < 10; i++) 
    {
      for (int j = 0; j < 10; j++) 
      {
        if (open[i][j]) 
        {
          if (mine[i][j] == 0) 
          {
            fill(150);
          } 
          else 
          {
            fill(200);
          }
          rect(j * 50, i * 50, 50, 50);
          
          if (mine[i][j] == 0) continue;

          if (mine[i][j] == 1) 
          {
            textSize(20);
            fill(0, 0, 255);
            textAlign(CENTER, CENTER);
            text("" + mine[i][j], j * 50 + 50 / 2, i * 50 + 50 / 2);
          } 
          else if (mine[i][j] == 2) 
          {
            textSize(20);
            fill(24, 123, 29);
            textAlign(CENTER, CENTER);
            text("" + mine[i][j], j * 50 + 50 / 2, i * 50 + 50 / 2);
          } 
          else if (mine[i][j] == 3) 
          {
            textSize(20);
            fill(255, 0, 0);
            textAlign(CENTER, CENTER);
            text("" + mine[i][j], j * 50 + 50 / 2, i * 50 + 50 / 2);
          } 
          else if (mine[i][j] == 9) 
          {
            image(bombImage, j * 50, i * 50, 50, 50);
          }
        } 
        else 
        {
          fill(200);
          rect(j * 50, i * 50, 50, 50);
        }
      }
    }
  }

  if (gameover && millis() - gameoverTime > 2000) 
  {
    background(0);//背景黑色
    textSize(50);
    fill(255, 0, 0);
    textAlign(CENTER, CENTER);
    text("Game Over", width / 2, height / 2);
    
    
    fill ( 100,100,200 );//restart的按鈕
    rect( width/4 , height /2 +50 ,width / 2 , 50);
    fill( 255 );
    textSize(20);
    textAlign(CENTER,CENTER);
    text("RESTART", width / 2 , height / 2 +75);
  }
}

void mousePressed()
{
  if (gameState == 0) 
  {//level1 按鈕
    if (mouseX > width / 4 && mouseX < width / 4 + width / 2 && mouseY > height / 2 - 25 && mouseY < height / 2 + 25) 
    {
      selectedLevel = 1;
      gameState = 1;
      initializeGame();
    }
    else if ( mouseX > width / 4 && mouseX < width / 4 + width / 2 && mouseY > height / 2 + 25 && mouseY < height / 2 + 75 )
    {
      selectedLevel = 2;
      gameState = 1;
      initializeGame();
      
    }
    else if (  mouseX > width / 4 && mouseX < width / 4 + width / 2 && mouseY > height / 2 + 75 && mouseY < height / 2 + 125 )
    {
      selectedLevel = 3;
      gameState = 1;
      initializeGame();
    }
  } 
  else if (gameState == 1) 
  {
    int i = mouseY / 50;
    int j = mouseX / 50;
    
    if (!open[i][j]) 
    {
      openAll(i, j);
    }
    
    if (gameover && millis() - gameoverTime > 5000) 
    {
      if (mouseX > width / 4 && mouseX < width / 4 + width / 2 && mouseY > height / 2 + 50 && mouseY < height / 2 + 100) 
      {
        restartGame();
      }
    }
  }
}

void initializeGame() {
  int mineCount = 0;

  if ( selectedLevel == 1 )
  {
    rows = 10;
    cols = 10;
    totalMines = 9;
  }
  else if ( selectedLevel ==2 )
  {
    rows = 16;
    cols = 16;
    totalMines = 30;
  }
  else if ( selectedLevel == 3 )
  {
    rows = 30;
    cols = 16;
    totalMines = 60;
  }
  
  mine = new int [rows][cols];
  open = new boolean [rows][cols];
  
  while (mineCount < totalMines) {
    int i = int(random(rows)), j = int(random(cols));
    if (mine[i][j] != 9) {
      mine[i][j] = 9;
      mineCount++;
    }
  }

  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      if (mine[i][j] == 9) {
        addOne(i - 1, j - 1);//炸彈左上方格子+1
        addOne(i - 1, j);//炸彈正上方格子+1
        addOne(i - 1, j + 1);//炸彈右上方格子+1
        addOne(i, j - 1);//炸彈左邊的格子+1
        addOne(i, j + 1);//炸彈右邊的格子+1
        addOne(i + 1, j - 1);//炸彈左下方格子+1
        addOne(i + 1, j);//炸彈正下方的格子+1
        addOne(i + 1, j + 1);//炸彈右下方的格子+1
      }
    }
  }
}

void restartGame() {
  gameState = 0;
  gameover = false;
  gameoverTime = 0;
  
  for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      open[i][j] = false;
      mine[i][j] = 0;
    }
  }
}





沒有留言:

張貼留言