ゲーム開発ラボ

視覚的に楽しいアプリやゲーム開発をしながら,Javaやjavascriptを楽しく学んでいきます

マインスイーパ ゲームを作成する-1

マインスイーパはパズルゲームの一種であり, 地雷を起動させないように地雷原に旗を立てることを目的としたものです
f:id:filopodia:20201122124159p:plain
以前はwindows OSにプレインストールされていましたが,残念ながら最近のwindowsには搭載されていないようです

今シリーズはこのマインスイーパを作成していきましょう
下図が今回作成するアプリの様子です
f:id:filopodia:20201122124238g:plain

キャンバス上に並んだセルをマウスクリックすると, セルが解放されるというアプリです
次回以降, セルの下に地雷や地雷数の情報が配置されることになりますが,今回は入れ物としてのセルが表示されるだけの,簡潔なアプリとなっています

コードは以下のようになっています

int col_num = 8; // 列数
int row_num = 8; // 行数
Cell[][] field = new Cell[col_num][row_num];
float c_x, c_y; // セルの幅
float margin = 4; // セル間の余白

void setup(){
  size(200, 200);
  background(255);
  c_x = (width-(col_num+1)*margin)/col_num;
  c_y = (height-(row_num+1)*margin)/row_num;  
  for(int i=0; i<col_num; i++){
    for(int j=0; j<col_num; j++){
      field[i][j] = new Cell(i, j);
    }
  }
}

void draw(){
  background(150);
  for(int i=0; i<col_num; i++){
    for(int j=0; j<col_num; j++){
      field[i][j].display();
    }
  }
}

void mouseClicked(){
  for(int i=0; i<col_num; i++){
    for(int j=0; j<col_num; j++){
      field[i][j].mouseClicked();
    }
  }  
}

class Cell{
  boolean isOpen;
  int x, y; // index
  
  // constructor
  Cell(int _x, int _y){
    x = _x;
    y = _y;
    isOpen = false;
  }
  
  // method
  void display(){
    stroke(50);
    if(isOpen){stroke(150); fill(150);}
    else if(isMouseHover()){fill(200);}
    else {fill(240);}
    rect(x*(c_x+margin)+margin, y*(c_y+margin)+margin, c_x, c_y);
  }
  
  void mouseClicked(){ // セル上でマウスクリックされたとき, isOpenにtrueを格納
    if(isMouseHover()){isOpen = true;}
  }
  
  boolean isMouseHover(){ // マウスがセル上にホバーしているときはtrue
    float cx_min = x*(c_x+margin)+margin; // セルの左端
    float cx_max = (x+1)*(c_x+margin); // セルの右端
    float cy_min = y*(c_y+margin)+margin; // セルの上端
    float cy_max = (y+1)*(c_y+margin); // セルの下端    
    if(cx_min<mouseX && mouseX<cx_max && cy_min<mouseY && mouseY<cy_max){
      return true;
    }
    else{return false;}
  }
}


コードを詳しくみてみましょう
キャンバス上にセルを描画するにあたり,セルクラスを定義しています

class Cell{
  boolean isOpen; // セルが開かれているかどうか

  // constructor
  Cell(int _x, int _y){
    isOpen = false;
  }
  
  // method
  void display(){
    if(isOpen){stroke(150); fill(150);}
    else {fill(240);}
    rect(x*(c_x+margin)+margin, y*(c_y+margin)+margin, c_x, c_y);
  }
  
  void mouseClicked(){ // セル上でマウスクリックされたとき, isOpenにtrueを格納
    if(isMouseHover()){isOpen = true;}
  }
  
  boolean isMouseHover(){ // マウスがセル上にホバーしているときはtrue
    float cx_min = x*(c_x+margin)+margin; // セルの左端
    float cx_max = (x+1)*(c_x+margin); // セルの右端
    float cy_min = y*(c_y+margin)+margin; // セルの上端
    float cy_max = (y+1)*(c_y+margin); // セルの下端    
    if(cx_min<mouseX && mouseX<cx_max && cy_min<mouseY && mouseY<cy_max){
      return true;
    }
    else{return false;}
  }
}

クラス変数としてセルが開かれているかという情報を格納する変数 isOpen を定義し,セルの開閉に応じてセルの色を変化させています
また,マウスがセル上をホバーしているときはセルの色を薄灰色に変化させています

次回は地雷や,地雷数を表す機能を実装してみたいと思います