首页 > 解决方案 > p5.j​​s 中的变量不变

问题描述

(我是编程的初学者,如果答案很明显,很抱歉。)我试图在 javascript 上制作一个基本的俄罗斯方块克隆,但一个特定的问题一直给我带来麻烦。这是我到目前为止的所有代码:

var w = 10;
var h = 22;
var s = 20;
var blocks = [];
var time;
var rand;
var I = [[3, 0], [4, 0], [5, 0], [6, 0], 0, 255, 255];
var O = [[4, -1], [5, -1], [4, 0], [5, 0], 255, 255, 0];
var T = [[4, 0], [5, -1], [5, 0], [6, 0], 170, 0, 255];
var S = [[4, -1], [5, -1], [5, 0], [6, 0], 0, 255, 0];
var Z = [[4, 0], [5, 0], [5, -1], [6, -1], 255, 0, 0];
var J = [[4, -1], [4, 0], [5, 0], [6, 0], 0, 0, 255];
var L = [[4, 0], [5, 0], [6, 0], [6, -1], 255, 165, 0];
function setup() {
	time = Number(second());
	rand = [I, O, T, S, Z, J, L];
	rand = shuffle(rand);
	createCanvas(s * w + 2, s * h + 1);
	let x = -1;
	let y = -2;
	for (i = 0; i < w * h; i++) {
		x++;
		if (x > 9) {
			x = 0;
			y++;
		}
		blocks.push(new Block(x, y));
	}
	currentBlock = sevenRand();
} // does grid building
var currentBlock;
function getBlock(x, y) {
	for (i = 0; i < blocks.length; i++) {
		if (blocks[i].idx == x && blocks[i].idy == y) {
			return i;
		}
	}
	return false;
} // gets block number in array from x and y coordinates
function Block(x, y, idx, idy) {
	this.x = x * s;
	this.y = y * s;
	this.idx = x;
	this.idy = y;
	this.w = s;
	this.h = s;
	this.r = 255;
	this.g = 255;
	this.b = 255;
	this.update = function() {};
}
function draw() {
	empty();
	for (n = 0; n < 4; n++) {
		blocks[getBlock(currentBlock[n][0], currentBlock[n][1])].r = currentBlock[4];
		blocks[getBlock(currentBlock[n][0], currentBlock[n][1])].g = currentBlock[5];
		blocks[getBlock(currentBlock[n][0], currentBlock[n][1])].b = currentBlock[6];
	}
	if (time != Number(second())) {
		move();
		time = Number(second());
	}
	if (currentBlock[0][1] > 19 || currentBlock[1][1] > 19 || currentBlock[2][1] > 19 ||currentBlock[3][1] > 19) {
		currentBlock = sevenRand();
	}
	for (i = 2 * w; i < blocks.length; i++) {
		fill(blocks[i].r, blocks[i].g, blocks[i].b);
		rect(blocks[i].x, blocks[i].y, blocks[i].w, blocks[i].h);
	}
}

//block positions

//var rand = ["I", "O", "T", "S", "Z", "J", "L"];
function shuffled(array) {
	var currentIndex = array.length,
		temporaryValue,
		randomIndex;
	while (0 !== currentIndex) {
		randomIndex = Math.floor(Math.random() * currentIndex);
		currentIndex -= 1;
		temporaryValue = array[currentIndex];
		array[currentIndex] = array[randomIndex];
		array[randomIndex] = temporaryValue;
	}

	return array;
} //shuffles array

var n = -1;
function sevenRand() {
	n += 1;
	if (n > 6) {
		rand = shuffled(rand);
		n = 0;
	}
	return rand[n];
} //7-bag randomizer
//function collision() {}

function empty() {
	//later have to save positions of previous block
	for (i = 0; i < blocks.length; i++) {
		blocks[i].r = 255;
		blocks[i].g = 255;
		blocks[i].b = 255;
	}
}

function move() {
	for (n = 0; n < 4; n++) {
		currentBlock[n][1]++;
	}
} // drops the block
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.js"></script>

(对不起,长代码片段)

我遇到问题的部分是它在第一次接触地面后重置块,

if (
  currentBlock[0][1] > 19 ||
  currentBlock[1][1] > 19 ||
  currentBlock[2][1] > 19 ||
  currentBlock[3][1] > 19
) {
  currentBlock = sevenRand();
}

它在接触地面后创建了一个新块,但是,它第二次无法更改变量并完全停止绘制循环。(如果你运行足够长的时间,你可以看到它。)我一直在尝试很长时间才能找到问题,但无济于事。有什么帮助吗?

标签: javascriptp5.js

解决方案


您的问题在于 function sevenRand()。问题是您的程序正在直接编辑rand变量中的数据。因此,当形状到达屏幕底部时,它会反映在该变量内的 x 和 y 位置。所以本质上,在第三轮执行时sevenRand(),它选择了一个 x 和 y 坐标已经在屏幕底部的形状,这就是你得到错误的原因:

未捕获的类型错误:无法设置未定义的属性“r”

解决此问题的一种方法是在变量中创建值的完整副本,rand这样您就不会更改原始值。一个快速的方法是:JSON.parse(JSON.stringify(rand))[n];

这是 sevenRand()应该的样子:

function sevenRand() {
    n += 1;
    if (n > 6) {
        rand = random(rand);
        n = 0;
    }
    return JSON.parse(JSON.stringify(rand))[n]
}

推荐阅读