0

ゲームは 2D 配列を使用して作成され、12 枚の画像が読み込まれます。正確には6組。タイルをクリックすると、タイルに 1 が追加されて 2 になり、タイルが表示されます。2 つのタイルが表示され、3 番目のタイルがクリックされると、最初の 2 つは非表示になります。

質問: 公開された 2 つのタイルが同じ画像を表示しているかどうかを確認するにはどうすればよいですか? それらが同じ画像を表示している場合、3 番目のタイルがクリックされたときにそれらが表示されたままになり、非表示にならないようにするにはどうすればよいですか?

配列に対応するある種のカウンターを作成しようとしましたが、まったく機能しませんでした。ある配列が別の配列と等しいかどうかもチェックしませんでした。

どんな助けでも大歓迎です。本当にありがとう。

参照用の私のコードは次のとおりです。

    // Number of columns and rows in the grid
int cols;
int rows;
int counter = 0; //counts how many are shown
boolean[] tracker = new boolean[12];
PImage [][] img = new PImage[4][3]; // load images

int[][] grid;

void setup() {
  size(600, 600);
  cols = height/4; //I want 4
  rows = width/3; //I want 3
  for (int m =0; m<tracker.length;m++){
        tracker[m]=false; //To laod array as false. Will be used to track numbers given out to make sure each every image is only put out once (but in reality I have pairs)
  }
  for (int i =0; i<img.length; i++) {
    for (int j=0; j<img[i].length;j++) {
      //int k = (j * 4 + i)%6;//2D array to 1D
      int k = (int)random(0,12);
      while(tracker[k]) //While it's true, pick 0-11 corepsonding to an image
      {
        k = (int)random(0,12);
      }
      tracker[k]=true; //Make it true, therefore can't be picked again
      img[i][j] = loadImage("img" + k + ".jpeg"); //Load the images
    }
  }
  grid = new int[cols][rows]; //To make the 2D array of 30 and 30
  for (int i=0; i<cols; i++) {
    for (int j=0; j<rows; j++) {
      grid[i][j] = 1; //If mouse clicked, will by multiplied by -1 to change if black or white
    }
  }
}

void draw() {
  rects(); //Calls the function to display rectangles
}

void rects() {
  for (int i=0; i<cols; i++) {
    for (int j=0; j<rows; j++) {
      if (grid[i][j]== 1) { //if grid at i,j is 1, change white
        fill(255); //white
        rect(cols*i, rows*j, cols, rows);
      }
      if (grid[i][j]== 2) { //if grid at i,j is -1, change black
        image(img[i][j], cols*i, rows*j);
        //rect(cols*0, rows*0, cols, rows);
      }
    }
  }
}

void mouseClicked() {
  for (int i=0; i<cols; i++) {
    for (int j=0; j<rows; j++) {
      if (mouseX<(i*cols)+cols && mouseX >= i*cols && mouseY<((j)*rows+rows) && mouseY >= (j)*rows) { // find square that is clicked then change color
        counter++;
        if (counter == 3) {
          for (int k=0; k<cols; k++) {
            for (int l=0; l<rows; l++) {
              grid[k][l]=1; //Making it 1 again, thus white
            }
          }
          counter =1;
        }
        grid[i][j] +=1; //By adding one, we make it show the imahe
      }
    }
  }
}
4

1 に答える 1

2

PImage は遅く、常に正確であるとは限らないため、比較しようとはしません。

メモリを浪費するため、必要以上の画像を保存したくありません。一意の画像のみを保存します。

モデルをビューから分離したい。画像を操作する必要はありません。それらを表示する場所と、一致を検索する手順を知る必要があるだけです。画像を保存する方法は、そのロジックとは別にする必要があります。

6 つの一意の画像の「PImage」配列を作成することをお勧めします。次に、一意の画像の数の 2 倍のサイズの "int" 配列を作成します (ペアが必要なため)。最後に、「int」配列と同じ長さの「boolean」配列を作成します。

したがって、セットアップ時に、画像配列 (「PImage」配列) に 6 つの画像を入力し、ラベル配列 (「int」配列) に画像配列のキー (0 ~ 5 の繰り返し、つまり {0,1) を入力します。 ,2,3,4,5,0,1,2,3,4,5)、ラベル配列をシャッフルし、表示配列 (「ブール」配列) に「false」値を入力します。

ユーザーがタイルをクリックすると、タイル番号 (0 ~ 11) が決定され、そのタイル番号の表示が true に設定され、タイル番号が最初にクリックされたものとして保存されます。ユーザーが別のタイルをクリックすると、最初にクリックしたタイル番号とは異なるタイル番号であることを確認してから、表示を true に設定し、タイル番号を 2 番目にクリックしたものとして保存します。2 つがクリックされたので、各タイル番号のラベル配列をチェックして、それらが等しいことを確認します。一致する場合は一致し、そうでない場合は一致せず、最初と 2 番目にクリックされたものがリセットされ、それらのタイル番号の表示が再び false に設定されます。

以下に作成した例では、2 つの pde ファイル、match と colors があります。match.pde ファイルには、ラベルの一致方法を理解するために必要なすべてが含まれています。colors.pde は、ランダムな色を生成する方法としてのみ含まれているため、心配する必要はありません。重要なのは、色を使用してロジックを示し、画像を使用して実装できるようにすることです。

match.pde

import java.util.Arrays; // used for shuffling
import java.util.Collections; // used for shuffling

int COLOR_COUNT = 6; //number of colors we will try to match

int WINDOW_X = 600;
int WINDOW_Y = 600;

//we will set these values during setup
int COLUMN_COUNT;
int ROW_COUNT;

color TILE_BACK_COLOR = color(255);
color TILE_EDGE_COLOR = color(0);

//we will set these values after we set the size of the window
int TILE_WIDTH;
int TILE_HEIGHT;

int ROUNDED_CORNER = 10;

//this is where we will store the colors
color[] COLORS = new color[COLOR_COUNT];

//the following must be Integer to allow for shuffle
//see http://stackoverflow.com/a/3981494/1736092
//this is where we will store the labels for the colors
Integer[] LABELS = new Integer[COLOR_COUNT*2]; 

//this is where we will store which tiles may be displayed
boolean[] DISPLAY = new boolean[COLOR_COUNT*2];

//this is where we will store the last 2 clicked tiles
int[] CLICKED = new int[2];

boolean MATCHED = false;
int MATCH_COUNT = 0;
int GUESS_COUNT = 0;

void setup() {
  /* calculate how many rows and columns we need based on number of tiles
   * since this is a matching game, number of tiles is twice the number of colors
   * we want a board that is as square as possible
   * take the square root of the number of tiles and round down (floor) and set that as rows
   * if rows divide evenly into the number of tiles, just divide tiles by rows to get columns
   * if not, keep subtracting a row until they divide evenly then get columns
   */
  println("Tiles: " + COLOR_COUNT*2);
  ROW_COUNT = floor(sqrt(COLOR_COUNT*2));
  println("Initial ROW_COUNT: " + ROW_COUNT);
  if((COLOR_COUNT*2) % ROW_COUNT == 0) {
    COLUMN_COUNT = (COLOR_COUNT*2) / ROW_COUNT;
    println("Keeping ROW_COUNT: " + ROW_COUNT + ", Setting COLUMN_COUNT: " + COLUMN_COUNT);
  } else {
    for(int i = ROW_COUNT - 1; i > 1; i--) {
      ROW_COUNT = i;
      if((COLOR_COUNT*2) % ROW_COUNT == 0) {
        COLUMN_COUNT = (COLOR_COUNT*2) / ROW_COUNT;
        println("Calculated ROW_COUNT: " + ROW_COUNT + ", Setting COLUMN_COUNT: " + COLUMN_COUNT);
      }
    }  
  }

  // make sure that the rows and columns are valid
  assert(COLUMN_COUNT * ROW_COUNT == COLOR_COUNT*2);

  size(WINDOW_X, WINDOW_Y);
  TILE_WIDTH = width/COLUMN_COUNT;
  TILE_HEIGHT = height/ROW_COUNT;

  populateColors(); // populate the colors
  newGrid(); // set up the initial grid

  background(0);
  drawGrid();
}

void draw() {
// //With no animations, this game is visually static
// //No need for a draw loop
}

void populateColors() {
  //for this game, we'll just generate random colors
  //however, you could change this function to set specific colors
  for(int i = 0; i < COLORS.length; i++) {
    COLORS[i] = getRandomColor();
  }  
}

//this function will create a new grid
//labels will be populated and shuffled
//clicks will be initialized to -1, which we will use to mean no click
void newGrid() {
  print("Initial LABELS[" + LABELS.length + "]:\t");

  for(int i = 0; i < LABELS.length; i++) {
    if(i < LABELS.length/2) LABELS[i] = i;
    else LABELS[i] = i-COLOR_COUNT;

    DISPLAY[i] = false;

    print(LABELS[i] + " ");
  }

  CLICKED[0] = -1;
  CLICKED[1] = -1;

  // shuffles the labels array
  Collections.shuffle(Arrays.asList(LABELS));

  print("\nShuffled LABELS[" + LABELS.length + "]:\t");
  for(int i = 0; i < LABELS.length; i++) print(LABELS[i] + " ");
  println();
}

//this just iterates through the grid and displays tiles as necessary
void drawGrid() {
  stroke(TILE_EDGE_COLOR); //set outline color
  for(int row = 0; row < ROW_COUNT; row++) {
    for(int col = 0; col < COLUMN_COUNT; col++) {
      int tile_number = col + row*(COLUMN_COUNT);
      if(DISPLAY[tile_number]) {
        fill(COLORS[LABELS[tile_number]]); //set fill color to that of tile front
      } else {
        fill(TILE_BACK_COLOR); //set fill color to that of tile back
      }
      //rect(top left x, top left y, width, height)
      rect(col*TILE_WIDTH, row*TILE_HEIGHT, TILE_WIDTH, TILE_HEIGHT, ROUNDED_CORNER);
    }
  }
}

//this is called when two tiles have been clicked
//it checks the labels of the colors of the given tiles, not the actual colors 
void checkMatch() {
  //we want to make sure that both of the clicked tiles have been properly logged
  if(CLICKED[0] != -1 || CLICKED[1] != -1) {
    println("Comparing LABELS of COLORS[" + LABELS[CLICKED[0]] + "] and COLORS[" + LABELS[CLICKED[1]] + "]");
    if(LABELS[CLICKED[0]] == LABELS[CLICKED[1]]) {
      println("Colors match! MATCHED set to true and MATCH_COUNT++");
      MATCHED = true;
      MATCH_COUNT++;
      println("MATCH_COUNT now " + MATCH_COUNT);
      if(MATCH_COUNT == COLOR_COUNT) {
        println("MATCH_COUNT now equals COLOR_COUNT, board must be complete, executing win()"); 
        win();
      }
    } else {
      println("Colors do not match");
    }
  }  
}

//this funciton is called when a win condition has been met
void win() { 
  println("You Win! You made " + GUESS_COUNT + " tile flips, best possible is " + COLOR_COUNT*2);
  if(GUESS_COUNT == COLOR_COUNT*2) println("PERFECT GAME!");
  println("Press SPACE to generate a new board."); 
}

//this function is called when the user wants to reset the board
void reset() {
  println("Resetting the board");

  COLORS = new color[COLOR_COUNT];
  LABELS = new Integer[COLOR_COUNT*2]; 
  DISPLAY = new boolean[COLOR_COUNT*2];

  CLICKED = new int[2];
  MATCHED = false;
  MATCH_COUNT = 0;
  GUESS_COUNT = 0;

  populateColors();
  newGrid();
}

void mouseClicked() {
  println("Mouse Clicked");
  int clicked_column = mouseX/TILE_WIDTH;
  int clicked_row = mouseY/TILE_HEIGHT;
  int tile_number = clicked_column + clicked_row*(COLUMN_COUNT);
  println("Clicked: " + clicked_column + "," + clicked_row + " [" + tile_number + "]");

  //we don't want to allow clicking a tile that is already being displayed
  if(!DISPLAY[tile_number]) {
    GUESS_COUNT++;
    println("Guess count incremented to " + GUESS_COUNT);

    if(CLICKED[0] != -1 && CLICKED[1] != -1) {
      if(!MATCHED) {
        println("Set DISPLAY[" + CLICKED[0] + "] and DISPLAY[" + CLICKED[1] + "] to false");
        DISPLAY[CLICKED[0]] = false;
        DISPLAY[CLICKED[1]] = false;
      } else {
        println("Set MATCHED to false");
        MATCHED = false;  
      }
      CLICKED[0] = -1;
      CLICKED[1] = -1;
    }

    if(CLICKED[0] == -1 && CLICKED[1] == -1) {
      CLICKED[0] = tile_number;
      DISPLAY[tile_number] = true;
      println("Tile " + tile_number + " set as CLICKED[0], set DISPLAY[" + tile_number + "] to true");
    } else if(CLICKED[0] != -1 && CLICKED[1] == -1) {
      CLICKED[1] = tile_number; 
      DISPLAY[tile_number] = true;
      println("Tile " + tile_number + " set as CLICKED[1], set DISPLAY[" + tile_number + "] to true");
      checkMatch();
    } else {
      println("error in mouseClicked()");
    }
  }

  drawGrid();
  if(DISPLAY[tile_number]) {
    println("Tile " + tile_number + " is already being displayed");
    for(int i = 0; i < LABELS.length; i++) {
      print("-["+i+"]-");
      if(i != tile_number && LABELS[tile_number] == LABELS[i]) {

        break;  
      }
    }
  }

}

//allow user to reset the board by pressing SPACE
void keyPressed() {
  if(key == ' ') reset();
}

色.pde

final float PHI = (1 + sqrt(5))/2;
float rand = random(0,1);

color HSVtoRGB(float h, float s, float v) {
  float r, g, b;
  if (s == 0) {
    r = v * 255;
    g = v * 255;
    b = v * 255;
  } else {
    float var_h = h * 6;
    float var_i = floor(var_h);
    float var_1 = v * (1 - s);
    float var_2 = v * (1 - s * (var_h - var_i));
    float var_3 = v * (1 - s * (1 - (var_h - var_i)));

    float var_r, var_g, var_b;

    if (var_i == 0) {var_r = v; var_g = var_3; var_b = var_1;}
    else if (var_i == 1) {var_r = var_2; var_g = v; var_b = var_1;}
    else if (var_i == 2) {var_r = var_1; var_g = v; var_b = var_3;}
    else if (var_i == 3) {var_r = var_1; var_g = var_2; var_b = v;}
    else if (var_i == 4) {var_r = var_3; var_g = var_1; var_b = v;}
    else {var_r = v; var_g = var_1; var_b = var_2;}

    r = var_r * 255;
    g = var_g * 255;
    b = var_b * 255;
  }
  return color(r, g, b);
}

// returns a random color
color getRandomColor() {
  //0.25,0.8
  float sat = 0.65;
  float val = 0.6;
  rand += PHI - 1;
  rand %= 1;
  //this is a custom function to convert HSV to RGB
  return HSVtoRGB(rand, sat, val);
}

余談ですが、Java shuffle メソッドを使用する必要はありません。特に、Java ライブラリの使用を避けて、Processing のみに固執する場合はなおさらです。人気のあるメソッドの 1 つは、フィッシャー イェーツ シャッフルです。 http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

于 2012-11-27T22:38:21.927 に答える