您不想尝试比较 PImage,因为它很慢且并不总是准确的。
您不想存储比您需要的更多的图像,因为这会浪费内存。仅存储唯一图像。
您想将模型与视图分开。你永远不需要操纵你的图像。您只需要知道它们应该显示在哪里以及搜索匹配项的过程。您存储图像的方式应该与该逻辑分开。
我建议您创建一个包含 6 个独特图像的“PImage”数组。然后,创建一个“int”数组,其大小是唯一图像数量的两倍(因为您想要成对)。最后,创建一个与“int”数组长度相同的“布尔”数组。
因此,在设置时,您将使用 6 个图像填充图像数组(“PImage”数组),使用图像数组的键(0 到 5 重复,即 {0,1)填充标签数组(“int”数组) ,2,3,4,5,0,1,2,3,4,5),打乱标签数组,并用“false”值填充显示数组(“布尔”数组)。
当用户单击一个磁贴时,您将确定磁贴编号(0 到 11),将该磁贴编号的显示设置为 true,并将该磁贴编号存储为第一次单击。当用户单击另一个磁贴时,首先检查它是否与第一次单击的磁贴编号不同,然后将显示设置为 true,并将磁贴编号存储为第二次单击。现在已经单击了两个,检查每个图块编号的标签数组,看看它们是否相等。如果是,则您有一个匹配项,如果没有,则没有匹配项,第一次和第二次单击将被重置,并且这些图块编号的显示再次设置为 false。
在下面我创建的示例中,有两个 pde 文件,match 和 colors。match.pde 文件包含了解标签匹配方法所需的所有内容。colors.pde 仅作为生成随机颜色的方法包含在内,您无需担心。重点是使用颜色向您展示逻辑,以便您可以使用图像来实现它。
匹配.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 库并只使用处理。一种流行的方法是 Fisher-Yates Shuffle。
http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle