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