我想在处理 3 时编写我自己的"生活游戏"版本,但我遇到了一个我似乎不理解的错误。每当代码运行时,屏幕都会变成黑白,有几个像素在变化,但它看起来不像是生活游戏。
有什么帮助吗?
int windowW, windowH, percentAlive, gen;
//windowW is the width of the window, windowH is the height
//percentVlive is the initial percent of alive pixel
//gen is the counter for the generation
color alive, dead;//alive is white and dead is black to represent their respective colors
boolean[][] cells0, cells1;//two arrays for the state of the cells, either alive or dead
boolean zeroOrOne = true;//this is to check which array should be iterated over
void setup() {
size(700, 700);
int width = 700;
int height = 700;
windowW = width;
windowH = height;
percentAlive = 15;
alive = color(255, 255, 255);
dead = color(0, 0, 0);
cells0 = new boolean[width][height];
cells1 = new boolean[width][height];
frameRate(2);
background(alive);
for (int x=0; x<width; x++) {//set the percent of live pixels according to the precentAlive varriable
for (int y=0; y<height; y++) {
int state = (int)random (100);
if (state > percentAlive)
cells0[x][y] = true;
else
cells0[x][y] = false;
}
}
}
void draw() {
gen += 1;//increases the generation every time it draws
drawLoop(zeroOrOne);
WriteGeneration(gen);
if(zeroOrOne){//changes the zeroOrOne value to change the array being iterated over
zeroOrOne = false;
}
else {
zeroOrOne = true;
}
}
void WriteGeneration(int number) {//changes the label on top
fill(0);
rect(0, 0, windowW, 100);
fill(255);
textFont(loadFont("BerlinSansFB-Reg-100.vlw"));
text("Generation " + number, 10, 90);
}
void drawLoop(boolean check) {
loadPixels();
if (check) {//checks which array to iterate thrgough
for (int x = 0; x < windowW; x++) {//iterates through the array
for (int y = 0; y < windowH; y++) {
if (cells0[x][y]) {//checks wether the pixel is alive or dead
pixels[x * 700 + y] = alive;//gets the current pixel
int lives = lives(x, y, check);//checks how many cells are alive around the current cell
if (lives<2) {//these are supposed to put in place the game of life rules
cells1[x][y] = false;
} else if (lives>4) {
cells1[x][y] = false;
} else {
cells1[x][y] = true;
}
} else {
pixels[x * 700 + y] = dead;//gets the current pixel
int lives = lives(x, y, check);//checks how many cells are alive around the current cell
if (lives == 3) {//turns the pixel alive if the condition is met
cells1[x][y] = true;
}
}
}
}
} else {//the same as the top but instead the arrays being updated and read are switched
for (int x = 0; x < windowW; x++) {
for (int y = 0; y < windowH; y++) {
if (cells1[x][y]) {
pixels[x * 700 + y] = alive;
int lives = lives(x, y, check);
if (lives<2) {
cells0[x][y] = false;
} else if (lives>4) {
cells0[x][y] = false;
} else {
cells0[x][y] = true;
}
} else {
pixels[x * 700 + y] = dead;
int lives = lives(x, y, check);
if (lives == 3) {
cells0[x][y] = true;
}
}
}
}
}
updatePixels();
}
int lives(int x, int y, boolean check) {//this just checks how many live pixels are around a given pixel
int lives = 0;
if (x > 1 && y >1 && x < 699 && y < 699) {
if (check) {
if (cells0[x-1][y-1])
lives++;
if (cells0[x][y-1])
lives++;
if (cells0[x+1][y-1])
lives++;
if (cells0[x-1][y])
lives++;
if (cells0[x+1][y])
lives++;
if (cells0[x-1][y+1])
lives++;
if (cells0[x][y+1])
lives++;
if (cells0[x+1][y+1])
lives++;
} else {
if (cells1[x-1][y-1])
lives++;
if (cells1[x][y-1])
lives++;
if (cells1[x+1][y-1])
lives++;
if (cells1[x-1][y])
lives++;
if (cells1[x+1][y])
lives++;
if (cells1[x-1][y+1])
lives++;
if (cells1[x][y+1])
lives++;
if (cells1[x+1][y+1])
lives++;
}
}
return lives;
}
请将您的代码发布为 MCVE。当我尝试运行您的代码时,我收到一个错误,因为我没有您尝试在第 59 行加载的字体文件。该字体与您的问题无关,因此您应该在发布问题之前真正摆脱它。
这段代码中有很多内容。我理解为什么你有两个数组,但将它们都放在草图级别只会让你的代码过于复杂。您不需要像这样不断地在数组之间切换。相反,我会像这样组织你的代码:
- 在草图级别只能有一个数组。您还可以删除
zeroOrOne
变量。 - 根据需要初始化该数组。
- 创建一个基于当前数组返回新数组的
nextGeneration()
。这可能会调用其他函数来计算邻居等等。但关键是每次都可以创建一个新数组,而不是在两个全局数组之间切换。 - 这将删除所有重复的逻辑。
一般说明:
- 有 8 个
if
语句来检查邻居有点矫枉过正。为什么不直接使用嵌套for
循环? - 您应该养成遵循正确命名约定的习惯。函数应该以小写字母开头,变量应该是描述性的 - 命名
check
的东西并不能真正告诉读者任何事情。
如果仍然无法使其工作,则必须进行一些调试。添加print()
语句,或使用处理编辑器的调试器单步执行代码。哪条行的行为与您的预期不同?然后,您可以发布该行的MCVE(以及显示行为所需的任何硬编码变量),我们将从那里开始。祝你好运。
您遇到的问题有两个:
-
当您只需要一个时,您拥有的两个单元格阵列会干扰并制作两个单独的游戏。
在检查哪些单元格需要 修改之前,您正在更新数组中的单元格。
同时解决这两个问题的方法是重新调整 cell1 数组的用途。不要每隔一段时间检查一次,而是将其设置为完全设置为 false 的数组。然后,每当要修改 cell0 中的正方形时,请将 cell1 中的该位置设置为 true,并在要更改的每个单元格创建标记后,在drawLoop()
方法末尾使用单独的 for 循环一次更改它们。这一举解决了这两个问题。
完成此操作后,您可以删除check
并zeroAndOne
变量,因为您将不再需要它们。这是我在进行建议的修改后获得的drawLoop()
方法:
void drawLoop() {
loadPixels();
for (int x = 0; x < windowW; x++) {
for (int y = 0; y < windowH; y++) {
if (cells0[x][y]) {
pixels[x * 700 + y] = alive;
int lives = lives(x, y);
if (lives<2) {
cells1[x][y] = true;
} else if (lives>4) {
cells1[x][y] = true;
}
} else {
pixels[x * 700 + y] = dead;
int lives = lives(x, y);
if (lives == 3) {
cells1[x][y] = true;
}
}
}
}
for (int x = 0; x < windowW; x++) {
for (int y = 0; y < windowH; y++) {
if (cells1[x][y]) {
cells0[x][y] = !cells0[x][y];
cells1[x][y] = false;
}
}
}
updatePixels();
}
我相信你可以弄清楚其余的。祝你好运!