2012年11月12日 星期一

Midtern


我們的期中小遊戲是踩地雷,也就是大家熟悉的踩地雷遊戲。
接著下面會有我們的程式碼、遊戲顯示視窗以及玩法介紹與demo影片。

 1.由於踩地雷週圍有幾個地雷的顯示數字,對於我們來說有困難點須突破,最後終於突破了。整體踩地雷配合已撰寫計時功能與預設炸彈數、restart功能鍵與良好的操作介面、悅耳的背景音樂,以完成我們的期中小遊戲踩地雷。

程式碼 :

import ddf.minim.*;
  Minim minim;
  AudioPlayer player;
public void setup() {
  size(400, 400);
  loop();
  stroke(0);
  fill(0);
  textSize(50);
  minim = new Minim(this);
  player =minim.loadFile("two.mp3");
  player.play();
  dx = width/col;
  dy = (height - GUIOffset)/row;
  mines = new Field[col][row];
  minesLeft = amountOfMines;
  fieldsRevealed = 0;
  timeCounter = -1;
  timeHelp = 0;
  populate();

}
public void draw() {
  background(167,250,250);
  drawGUI();
  drawField();
}
class Field {
  private int mineCount;
  private boolean mine;
  private boolean hidden;
  private boolean marked;
  public Field() {
    mineCount = 0;
    mine = false;
    hidden = true;
    marked = false;
  }
  int getMineCount() {
    return mineCount;
  }
  void raiseMineCount() {
    mineCount++;
  }
  boolean isMine() {
    return mine;
  }
  void setMine() {
    mine = true;
  }
  boolean isHidden() {
    return hidden;
  }
  void reveal() {
    hidden = false;
    marked = false;
  }
  boolean isMarked() {
    return marked;
  }
  void toggleMark() {
    marked = !marked;
  }
}
final int col =6;
final int row =6;
final int amountOfMines = 5;
final int GUIOffset = 100;
int minesLeft;
int fieldsRevealed;
float dx;
float dy;
Field[][] mines;
  for (int i = 0; i < a; i++) {
    int v = minePositions[i];
    int c = v%col;
    int r = v/row;
    if (c > 0 && r > 0) mines[c - 1][r - 1].raiseMineCount();
    if (r > 0) mines[c][r - 1].raiseMineCount();
    if (c < col - 1 && r > 0) mines[c + 1][r - 1].raiseMineCount()
    if (c > 0) mines[c - 1][r].raiseMineCount();
    mines[c][r].setMine();
    if (c < col - 1) mines[c + 1][r].raiseMineCount();
    if (c > 0 && r < row - 1) mines[c - 1][r + 1].raiseMineCount();
    if (r < row - 1) mines[c][r + 1].raiseMineCount();
    if (c < col - 1 && r < row - 1) mines[c + 1][r + 1].raiseMineCount();
  }
}
int timeCounter;//時間
int timeHelp;
void drawGUI() {
  fill(0);
  for (int i = 0; i < width; i += dx) {
    line(i, GUIOffset, i, height);
  }
  for (int i = GUIOffset; i < height; i += dy) {
    line(0, i, width, i);
  }
  int s = second();
  if (s != timeHelp) {
    timeCounter++;
    timeHelp = s;
  }
  String seconds = Integer.toString(timeCounter);
  if (seconds.length() == 1) {
    seconds = "00" + seconds;
  }
  else if (seconds.length() == 2) {
    seconds = "0" + seconds;
  }
  else if (seconds.length() < 3) {
    seconds = "999";
  }
  textSize(50);
  text(seconds, 10, 50);             //計時位置
  text(minesLeft, width - 50, 50);   //炸彈個數位置
  fill(255);
  noStroke();
  ellipse(width/2+5, 33, 70, 70);//r的格子
  fill(0);
  text("R", width/2 - 10, 50);
}
void highlight(float x, float y) {
  fill(255, 0, 0);
  y -= GUIOffset;
  if (x/dx >= col || y/dy >= row || y < 0) {
    return;
  }
  Float iF = x/dx;
  Float jF = y/dy;
  int i = iF.intValue();
int j = jF.intValue();
  rect(i * dx, j * dy + GUIOffset, dx, dy);
}
void reveal(float x, float y) {
  float yRel = y - GUIOffset;
  Float iF = x/dx;
  Float jF = yRel/dy;
  int i = iF.intValue();
  int j = jF.intValue();
  if (i < 0 || yRel < 0 || i >= col || j >= row ) {
   return;
  }
  if (!mines[j][i].isHidden()) {
    return;
  }
  if (mines[j][i].isMarked()) {
    minesLeft++;
  }
  mines[j][i].reveal();
  fieldsRevealed++;
  if (fieldsRevealed == col*row - amountOfMines) {        
    win();
  }
  if (mines[j][i].isMine()) {
    gameOver();
void toggleMark(float x, float y) {
  float yRel = y - GUIOffset;
  Float iF = x/dx;
  Float jF = yRel/dy;
  int i = iF.intValue();
  int j = jF.intValue();
if (i < 0 || yRel < 0 || i >= col || j >= row) {
    return;
  }
  if (mines[j][i].isHidden()) {
    if (mines[j][i].isMarked()) {
      mines[j][i].toggleMark();
      minesLeft++;
    }
    else {
      mines[j][i].toggleMark();
      minesLeft--;
} }}
void gameOver() {
  noLoop();
  draw();
  textSize(50);
  fill(55, 200, 30);
  text("ARE YUU OKAY!",20, 180);
}
void win() {
  for (int i = 0; i < col; i++) {
    for (int j = 0; j < row; j++) {
      if (mines[i][j].isHidden() && !mines[i][j].isMarked()) {
        mines[i][j].toggleMark();
      }}}
  minesLeft = 0;
  noLoop();
  draw();
  textSize(50);
  fill(255,135, 80);
  text("CHAMPION!", 20, 200);
}
void reset() {
  setup();
}
public void mousePressed() {
  if (mouseButton == LEFT) {
    reveal(mouseX, mouseY);
  if (mouseX > width/2 - 25 && mouseX < width/2 + 25 && mouseY > 10 && mouseY < 60) {
      reset();
    }}
else if (mouseButton == RIGHT) {
toggleMark(mouseX, mouseY);
  }
}


2.遊戲顯示

此畫面為一開始的遊戲顯示視窗。
一啟動遊戲,即有悅耳的背景音樂相襯。
畫面方塊為6*6的選擇方塊,可供玩家選擇。
1.畫面左上方,為時間計時功能,採累加的方式計時。
2.畫面右上方,為預設炸彈數,顯示6*6方塊中共有5個預設炸彈。
3.畫面中間上方的R鍵,玩家可以依喜好重新啟動遊戲,開啟新局。
此時,時間會重新計時,而炸彈個數不變,背景音樂也持續播放。


 遊戲失敗顯示
1.圖中的紅色同心圓圖形,即為我們所設的預設炸彈。
當按到時,即表示遊戲失敗。
2.失敗時,左上方計時器將停止,秒數為按到炸彈時間。
3.畫面中央會顯示粗體綠字的ARE YOU OKAY! 的字樣。
遊戲過關顯示
1.圖中 "- ",表是炸彈位置。
2.過關時,左上方計時器將停止,秒數為過關時間。
3.右上方炸彈個數會顯示為0個。
4.遊戲過關,會在中央顯示粗體橘字CHAMPION!的字樣。

希望大家玩得愉快
以下是我們完整DEMO影片




沒有留言:

張貼留言