2012年11月13日 星期二

Midterm


踩地雷
左半邊是地圖區,很簡單就是地雷可以踩或是右鍵Mark為地雷,
右邊介面區顯示當前這局總共有多少顆地雷,
可以使用下面的+或-來增加減少,然後按下PLAY開始新一局,
總地雷數就會是新設定的地雷數。

中間是經過時間,從第一顆地雷被踩下去才開始記數,
做為計算排行榜之用。

最下是高分表,顯示了目前資料中記錄的前三名,
會有一個HighSore.txt的純文字文件用於記錄當前排行榜,
如果不存在就會跳出例外,前三名的成績就為預設的255
只有玩地雷為25顆的正規局,名次才會被計算。

開始玩

如同大家所知的踩地雷一樣,
當踩到一格是周圍完全沒有地雷的空格,
就會自動把周圍全部點開,所以如果運氣好,
點兩三下就可以開出一大片安全區。

踩爆
如果不幸踩到地雷,畫面上就會秀出失敗的訊息,
這個時候時間不再繼續記數,也不能夠再踩,
只能夠按下PLAY開始新的一局,當然也可以設定地雷數後再開始。

勝利(這裡為了節省時間把地雷數改為5顆,排行榜也會計算)
當地圖上應該要被踩下的位置都被踩下後
(剩下未踩,或被Mark都是地雷)
判定勝利,秀出勝利訊息。
如果很確定是地雷的位置,那不必標記也沒關係,不影響判定。

可以看到上一局的11秒刷新了新的紀錄,
所以被記錄在第一名的位置了。


我的專案資料夾結構
HighScore是個很單純的純文字文件,
所以任何有心人士(?)都可以輕易的竄改上面的排行榜...



Code

字很多,先直接說我的做法好了QQ
程式從按下PLAY開始,
首先生成n(地雷數)個隨機不重複0~143的亂數,設定為地雷,
建構一個boolean陣列,存放144格是否地雷的地圖;
然後再做一個int二維陣列(boolean陣列為配合亂數,是一維陣列)
根據boolean陣列的資料判定當前這格周圍有多少顆地雷(或根本就是雷)
這個int map做好以後,地雷的資料就算完成了。

當使用者開始踩地雷區,因為每一格是50像素,
所以直接把使用者的mouseX.Y除50就可以對應到int map上,
判定起來很方便;
我的圖片在遊戲一開始後就載入到一個Image陣列之中,
當Click事件發生,直接讓int map中的資料去當作Image陣列的Index,
然後貼圖就是對應的數字,省去很多不必要的記憶體浪費。

大致上就是這樣,其他的小功能基本上都是小函式,
copy來研究一下就貼上了沒什麼特別的QQ

以下為程式碼:
請搭配http://ppt.cc/z6ee
完整專案檔服用,不然圖都貼不出來(doh)
int intMap[][] = new int[12][12];
boolean check[][] = new boolean[12][12];
boolean mark[][] = new boolean[12][12];
PImage pic[] = new PImage[10];
int mines = 25;
int oldTime;
int time = 0;
boolean pause;
boolean begin;
int[] highScore = {255,255,255};
int winCount;

void setup()
{
  size(800,600);
  try
  {
    String lines[] = loadStrings("HighScore.txt");
    for (int i = 0; i < 3; i++)
      highScore[i] = Integer.parseInt(lines[i]);
  }
  catch(Exception ex)
  {
    println("There is no High Score Data!\nThe High Score are all 255");
  }
  
  pic[0] = loadImage("white.jpg");
  pic[1] = loadImage("one.jpg");
  pic[2] = loadImage("two.jpg");
  pic[3] = loadImage("three.jpg");
  pic[4] = loadImage("four.jpg");
  pic[5] = loadImage("five.jpg");
  pic[6] = loadImage("six.jpg");
  pic[7] = loadImage("seven.jpg");
  pic[8] = loadImage("eight.jpg");
  pic[9] = loadImage("red.jpg");
  
  
  background(255,255,255);
  //frameRate(24);
  
  gameZoom();
  IFset();
  Start();
  
}
void gameZoom()
{
  stroke(5);
  fill(200,200,200);
  rect(0,0,600,600);
  strokeWeight(5);
  line(0,0,600,0);
  line(0,50,600,50);
  line(0,100,600,100);
  line(0,150,600,150);
  line(0,200,600,200);
  line(0,250,600,250);
  line(0,300,600,300);
  line(0,350,600,350);
  line(0,400,600,400);
  line(0,450,600,450);
  line(0,500,600,500);
  line(0,550,600,550);
  line(0,600,600,600);
  
  line(0,0,0,600);
  line(50,0,50,600);
  line(100,0,100,600);
  line(150,0,150,600);
  line(200,0,200,600);
  line(250,0,250,600);
  line(300,0,300,600);
  line(350,0,350,600);
  line(400,0,400,600);
  line(450,0,450,600);
  line(500,0,500,600);
  line(550,0,550,600);
  line(600,0,600,600);
  strokeWeight(1);
}
void IFset()
{
  fill(0,0,0);
  PFont myFont;
  myFont = createFont("FFScala", 32);
  textFont(myFont);
  text(str(mines),630,10,100,100);
  
  text("經過時間",620, 350,170,100);
  text("High Score",620, 450,170,100);
  
  myFont = createFont("FFScala", 20);
  textFont(myFont);
  text("顆地雷",690,20,200,100);
  text("1.\n2.\n3.",630,490,50,100);
  noStroke();
  fill(255,255,255);
  rect(700,490,50,100);
  fill(0,0,0);
  text(str(highScore[0])+"\n"+str(highScore[1])+"\n"+str(highScore[2]),700,490,50,100);
  stroke(1);
  
  fill(0,255,0);
  rect(630,60,40,40);
  fill(0,0,255);
  rect(700,60,40,40);
  fill(255,0,0);
  rect(635,78,30,4);
  rect(648,65,4,30);
  rect(705,78,30,4);
  
  rect(625,160,150,150);
  fill(0,0,0);
  myFont = createFont("FFScala", 50);
  textFont(myFont);
  text("PLAY",635,200,200,100);
  myFont = createFont("FFScala", 40);
  textFont(myFont);
}

void Start()
{
  int mine[] = new int[mines];
  boolean boolMap[] = new boolean[144];
  check = new boolean[12][12];
  mark = new boolean[12][12];
  for (int i = 0; i < mines; i++)
  {
    boolean checker = true;
    while(checker)
    {
      mine[i] = int(random(144));
      for(int j = 0; j <= i; j++)
      {
        if (i == j)
        {
          checker = false;
          break;
        }
        else if (mine[i] == mine[j])
          break;
      }
    }
    boolMap[mine[i]] = true;
  }
  
  int count = 0;
  if (boolMap[0])
    count = 9;
  else
  {
    if(boolMap[1])
      count++;
    if(boolMap[12])
      count++;
    if(boolMap[13])
      count++;
  }
  intMap[0][0] = count;
  count = 0;
  
  if (boolMap[11])
    count = 9;
  else
  {
    if (boolMap[10])
      count++;
    if (boolMap[22])
      count++;
    if (boolMap[23])
      count++;
  }
  intMap[11][0] = count;
  count = 0;
  
  if (boolMap[132])
    count = 9;
  else
  {
    if (boolMap[120])
      count++;
    if (boolMap[121])
      count++;
    if (boolMap[133])
      count++;
  }
  intMap[0][11] = count;
  count = 0;
  
  if (boolMap[143])
    count = 9;
  else
  {
    if (boolMap[130])
      count++;
    if (boolMap[131])
      count++;
    if (boolMap[142])
      count++;
  }
  intMap[11][11] = count;
  count = 0;
  //上排
  for (int i = 1; i < 11; i++)
  {
    int couM = 0;
    if (boolMap[i])
      couM = 9;
    else
    {
      if (boolMap[i - 1])
        couM++;
      if (boolMap[i + 1])
        couM++;
      if (boolMap[i + 11])
        couM++;
      if (boolMap[i + 12])
        couM++;
      if (boolMap[i + 13])
        couM++;
    }
    intMap[i][0] = couM;
  }
  //左排
  for (int i = 1; i < 11; i++)
  {
    int couM = 0;
    if (boolMap[12 * i])
      couM = 9;
    else
    {
      if (boolMap[12 * (i - 1)])
        couM++;
      if (boolMap[12 * (i - 1) + 1])
        couM++;
      if (boolMap[12 * i + 1])
        couM++;
      if (boolMap[12 * (i + 1)])
        couM++;
      if (boolMap[12 * (i + 1) + 1])
        couM++;
    }
    intMap[0][i] = couM;
  }
  //右排
  for (int i = 1; i < 11; i++)
  {
    int couM = 0;
    if (boolMap[(i + 1) * 12 - 1])
      couM = 9;
    else
    {
      if (boolMap[i * 12 - 2])
        couM++;
      if (boolMap[i * 12 - 1])
        couM++;
      if (boolMap[(i + 1) * 12 - 2])
        couM++;
      if (boolMap[(i + 2) * 12 - 2])
        couM++;
      if (boolMap[(i + 2) * 12 - 1])
        couM++;
    }
    intMap[11][i] = couM;
  }
  //下排
  for (int i = 1; i < 11; i++)
  {
    int couM = 0;
    if (boolMap[132 + i])
      couM = 9;
    else
    {
      if (boolMap[120 + i - 1])
        couM++;
      if (boolMap[120 + i])
        couM++;
      if (boolMap[120 + i + 1])
        couM++;
      if (boolMap[132 + i - 1])
        couM++;
      if (boolMap[132 + i + 1])
        couM++;
    }
    intMap[i][11] = couM;
  }
  //中間
  for (int i = 1; i < 11; i++)
  {
    for (int j = 1; j < 11; j++)
    {
      int couM = 0;
      if (boolMap[i * 12 + j])
        couM = 9;
      else
      {
        if (boolMap[(i - 1) * 12 + j - 1])
          couM++;
        if (boolMap[(i - 1) * 12 + j])
          couM++;
        if (boolMap[(i - 1) * 12 + j + 1])
          couM++;
        if (boolMap[i * 12 + j - 1])
          couM++;
        if (boolMap[i * 12 + j + 1])
          couM++;
        if (boolMap[(i + 1) * 12 + j - 1])
          couM++;
        if (boolMap[(i + 1) * 12 + j])
          couM++;
        if (boolMap[(i + 1) * 12 + j + 1])
          couM++;
      }
      intMap[j][i] = couM;
    }
  }
}
void mousePressed()
{
  int a = mouseX / 50;
  int b = mouseY / 50;
  if (mouseButton == LEFT)
  {
    if(mouseX<600 && !pause)
    {
      image(pic[intMap[a][b]], a * 50 + 3, b * 50 + 3, 45, 45);
      check[a][b]=true;
      winCount++;
      if (intMap[a][b] == 9)
        endGame();
      else if (intMap[a][b] == 0)
        safe(a, b);
        
      if(!begin)
      {
        begin = true;
        oldTime = second();
      }
      
      if(winCount == 144 - mines)
        win();
    }
    else if(mouseY&rt;60 && mouseY<100)
    {
      PFont myFont;
      myFont = createFont("FFScala", 32);
      textFont(myFont);
      if(mouseX&rt;630 && mouseX<670)
      {
        mines++;
        fill(255,255,255);
        noStroke();
        rect(610,8,75,40);
        fill(0,0,0);
        text(str(mines),630,10,100,100);
      }
      else if(mouseX&rt;700 && mouseX<740)
      {
        mines--;
        fill(255,255,255);
        noStroke();
        rect(610,8,55,40);
        fill(0,0,0);
        text(str(mines),630,10,100,100);
      }
    }
    else if(mouseX&rt;625 && mouseX<775 && mouseY&rt;160 && mouseY<310)
    {
      gameZoom();
      Start();
      IFset();
      time = 0;
      begin = false;
      pause = false;
    }
  }
  else if (mouseButton == RIGHT)
  {
    if(!pause)
    {
      if (!check[a][b] && !mark[a][b])
      {
        mark[a][b] = true;
        PImage flag = loadImage("mark.jpg");
        image(flag, a * 50 + 3, b * 50 + 3, 45, 45);
      }
      else if (mark[a][b])
      {
        mark[a][b] = false;
        fill(200,200,200);
        rect(a * 50 + 2, b * 50 + 2,46,46);
      }
      
    }
  }
}

void endGame()
{
  PFont myFont;
  myFont = createFont("FFScala", 80);
  textFont(myFont);
  fill(255,0,0);
  text("爆了!GG!",100,200,500,200);
  myFont = createFont("FFScala", 40);
  textFont(myFont);
  pause = true;
  winCount = 0;
}

void win()
{
  PFont myFont;
  myFont = createFont("FFScala", 80);
  textFont(myFont);
  fill(255,0,0);
  text("YOU WIN!!",100,200,500,200);
  myFont = createFont("FFScala", 40);
  textFont(myFont);
  pause = true;
  winCount = 0;
  if(mines == 25)        //如果是25顆地雷才會記錄!!!!
  {
    for(int i = 0; i < 3; i++)
      if(time < highScore[i])
      {
        for(int j = 2; j &rt; i; j--)
          highScore[j] = highScore[j - 1];
        highScore[i] = time;
        String saveHC = "";
        for(int j = 0; j < 3; j++)
          saveHC += str(highScore[j]) + " ";
        String[] list = split(saveHC, ' ');
        saveStrings("HighScore.txt", list);
        break;
      }
  }
}

void safe(int a,int b)
{
  if (a &rt; 0 && b &rt; 0)
  {
    if (!check[a-1][b-1])
    {
      image(pic[intMap[a-1][b-1]], (a-1) * 50 + 3, (b-1) * 50 + 3, 45, 45);
      check[a-1][b-1]=true;
      winCount++;
      if (intMap[a-1][b-1] == 0)
        safe(a-1, b-1);
    }
  }
  if (b &rt; 0)
  {
    if (!check[a][b-1])
    {
      image(pic[intMap[a][b-1]], (a) * 50 + 3, (b-1) * 50 + 3, 45, 45);
      check[a][b-1]=true;
      winCount++;
      if(intMap[a][b-1] == 0)
        safe(a, b-1);
    }
  }
  if (a < 11 && b &rt; 0)
  {
    if (!check[a+1][b-1])
    {
      image(pic[intMap[a+1][b-1]], (a+1) * 50 + 3, (b-1) * 50 + 3, 45, 45);
      check[a+1][b-1]=true;
      winCount++;
      if(intMap[a+1][b-1] == 0)
        safe(a+1, b-1);
    }
  }
  if (a &rt; 0 )
  {
    if (!check[a-1][b])
    {
      image(pic[intMap[a-1][b]], (a-1) * 50 + 3, (b) * 50 + 3, 45, 45);
      check[a-1][b]=true;
      winCount++;
      if(intMap[a-1][b] == 0)
        safe(a-1, b);
    }
  }
  if (a < 11)
  {
    if (!check[a+1][b])
    {
      image(pic[intMap[a+1][b]], (a+1) * 50 + 3, (b) * 50 + 3, 45, 45);
      check[a+1][b]=true;
      winCount++;
      if(intMap[a+1][b] == 0)
        safe(a+1,b);
    }
  }
  if (a &rt; 0 && b < 11)
  {
    if (!check[a-1][b+1])
    {
      image(pic[intMap[a-1][b+1]], (a-1) * 50 + 3, (b+1) * 50 + 3, 45, 45);
      check[a-1][b+1]=true;
      winCount++;
      if(intMap[a-1][b+1] == 0)
        safe(a-1,b+1);
    }
  }
  if (b < 11)
  {
    if (!check[a][b+1])
    {
      image(pic[intMap[a][b+1]], (a) * 50 + 3, (b+1) * 50 + 3, 45, 45);
      check[a][b+1]=true;
      winCount++;
      if(intMap[a][b+1] == 0)
        safe(a, b+1);
    }
  }
  if (a < 11 && b < 11)
  {
    if (!check[a+1][b+1])
    {
      image(pic[intMap[a+1][b+1]], (a+1) * 50 + 3, (b+1) * 50 + 3, 45, 45);
      check[a+1][b+1]=true;
      winCount++;
      if(intMap[a+1][b+1] == 0)
        safe(a+1,b+1);
    }
  }
}

void draw()
{
  if(begin)
  {
    if (oldTime != second())
      time++;
    oldTime = second();
  }
  noStroke();
  if(!pause)
  {  
    fill(255,255,255);
    rect(700,400,200,50);
    fill(0,0,0);
    text(str(time),700,400,200,50);
  }
}




//媽勒為什麼大家都是Midtern害我以為我拼錯

沒有留言:

張貼留言