我的问题是关于javascript中的slice()
我正在创造我的第一部生命游戏。它完成得非常快,但我马上就完成了 注意到它没有按预期工作。我一直在尝试调试它 几个小时和几个小时和它的种类。但它一直在困扰着我 是不是它首先打破了它...我改变的方式 几代人用某种奇怪的方式打破了整个逻辑,使它成为我的游戏 生活在一个奇怪的迷宫看起来模式中失去控制。它只是一个版本的 用户选择放入种子模式的生命游戏,然后单击上 放入屏幕并启动游戏。
// Basic vars
var width, height, life;
// Seed vars
var seedPlanted = false; // Is the game on?
var seedPos = {
x: 0,
y: 0
};
// Different seeds
var acorn = [
[0, 0, 1],
[1, 0, 1],
[0, 0, 0],
[0, 1, 0],
[0, 0, 1],
[0, 0, 1],
[0, 0, 1]
];
var rPentomino = [
[0, 1, 0],
[1, 1, 1],
[1, 0, 0]
];
var dieHard = [
[0, 1, 0],
[0, 1, 1],
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
[0, 0, 1],
[1, 0, 1],
[0, 0, 1]
];
var gosperGliderGun = [
[0, 0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 1],
[0, 0, 1, 0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 1, 0],
[0, 0, 0, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 0, 0, 0, 0],
[0, 0, 1, 1, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 0, 0, 0, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 0, 0, 0, 0]
];
var beeHive = [
[0, 1, 0],
[1, 0, 1],
[1, 0, 1],
[0, 1, 0]
];
var loaf = [
[0, 1, 0, 0],
[1, 0, 1, 0],
[1, 0, 0, 1],
[0, 1, 1, 0]
];
var toad = [
[0, 1],
[1, 1],
[1, 1],
[1, 0]
];
// p5 canvas setup
function setup() {
width = windowWidth;
height = windowHeight;
createCanvas(width, height);
}
// Capture user click and set it as the seed position and start the game
function mouseClicked() {
if (!seedPlanted) {
seedPos.x = mouseX;
seedPos.y = mouseY;
seedPlanted = true;
life = new Life(gosperGliderGun, seedPos); // Initiate the Life object
}
}
// p5 draw
function draw() {
background(51);
if (seedPlanted) { // Check if the game is on
life.generate(); // Generate a new generation
life.display(); // Display the new generation
}
}
// The Life object constuctor
function Life(seed, pos) {
this.cellWidth = 4; // Width of the cells in px
this.caWidth = Math.ceil(width / this.cellWidth); // Calculate the grid Width
this.caHeight = Math.ceil(height / this.cellWidth);// And grid height
this.curGen = []; // Declare an array for the current generation
// Fill the curGen with arrays full of 0's
for (var i = 0; i < this.caWidth; i++) {
this.curGen[i] = [];
for (var j = 0; j < this.caHeight; j++) {
this.curGen[i][j] = 0;
}
}
// Apply the seed to the curGen
pos.x = Math.round(pos.x / this.cellWidth); // Convert seedPos from px to cells
pos.y = Math.round(pos.y / this.cellWidth);
for (var i = 0; i < seed.length; i++) { // Place the seed to the curGen
for (var j = 0; j < seed[i].length; j++) {
this.curGen[(this.caWidth + pos.x + i) % this.caWidth][(this.caHeight + pos.y + j) % this.caHeight] = seed[i][j];
}
}
// Create and fill the nextGen array variable with empty arrays
this.nextGen = [];
for (var i = 0; i < this.caWidth; i++) {
this.nextGen[i] = [];
}
// Generate a new generation
this.generate = function() {
for (var i = 0; i < this.caWidth; i++) { // Loop through the cells
for (var j = 0; j < this.caHeight; j++) {
var neighbors = 0;
for (var k = -1; k <= 1; k++) { // At every cell, loop through its neighbors in a 3x3 grid
for (var l = -1; l <= 1; l++) {
// Count the neighbors and wrap aroundthe edges with "modulo trick"
neighbors += this.curGen[(this.caWidth + i + k) % this.caWidth][(this.caHeight + j + l) % this.caHeight];
}
}
neighbors -= this.curGen[i][j]; // Subract the cell itself from the neighbors
// Rules of survival and birth
if (this.curGen[i][j] === 1 && neighbors < 2) { // Underpopulation
this.nextGen[i][j] = 0;
} else if (this.curGen[i][j] === 1 && neighbors > 3) { // Overpopulation
this.nextGen[i][j] = 0;
} else if (this.curGen[i][j] === 0 && neighbors === 3) { // Reproduction
this.nextGen[i][j] = 1;
} else { // Stasis
this.nextGen[i][j] = this.curGen[i][j];
}
}
}
这是问题部分。现在我必须将新创建的一代设置为
当前一代,以便它将显示和生成。
我的第一个想法是使用slice()来切除来自的信息
新的nextGen并把它放在旧的curGen。然后我可以在下一个基础上写字
在下一轮。这似乎是一个像我一样的新手,但它创造了
一些奇怪的失控增长和消失。我经历了所有的循环
和数组,并在屏幕上绘制各种东西,以了解什么不是
工作。我发现邻居没有被计算在内,而且
它使像“蟾蜍”这样基本稳定的种子消失了。
然后我去了其他例子,其他人是如何做到的,这就是“交换”
p5js.org中的方法生命游戏的例子引起了我的注意,你只需要交换
在一个临时变量的帮助下,世代将另一个变为另一个
时刻。不知怎的,这使得同样的逻辑起作用。我不明白为什么。
然后我尝试修复我的旧方法,只是在徒劳的nextGen上写0。
没工作。然后我试着把它写成全新的数组,它起作用了。我不
理解为什么交换方法有效,让其他阵列充满旧状态
等待被覆盖,并且slice()方法将相同的旧状态留给了
被覆盖到其他阵列不起作用。除非我写完全新的
阵列。 slice()函数是否会留下对旧数组或somehing的引用?
如果取消注释 FastFix 行,它将起作用,
或者如果取消注释三个“swap”方法行,并注释掉slice()
具有以下for循环的方法。它会工作。但不是只有slice()。
有人可以告诉我为什么吗? slice()做什么,“交换”没有?
//var temp = this.curGen; //
//this.curGen = this.nextGen; // Why this "swap" method works?
//this.nextGen = temp; //
this.curGen = this.nextGen.slice(0); // And this slice() not?
for (var i = 0; i < this.caWidth; i++) { // This
//this.nextGen[i] = []; //<---*FastFix* // is all
for (var j = 0; j < this.caHeight; j++) { // a fix that I
this.nextGen[i][j] = 0; // that I tried.
} // But it wont
} // work without
} // the *FastFix*
// which is a
// stupid hack
// Display the cells
this.display = function() {
for (var i = 0; i < this.caWidth; i++) { // Loop through the cells
for (var j = 0; j < this.caHeight; j++) {
noStroke();
if (this.curGen[i][j] == 1) { // Decide fill based on the cell state
fill(255);
} else {
fill(51);
}
rect(i * this.cellWidth, j * this.cellWidth, this.cellWidth, this.cellWidth); // And draw it
}
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.js"></script>
<html>
<head>
<meta charset="UTF-8">
<script language="javascript" type="text/javascript" src="libraries/p5.js"></script>
<script language="javascript" type="text/javascript" src="sketch.js"></script>
<script language="javascript" type="text/javascript" src="life.js"></script>
<style>
body {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
</body>
</html>