我正在尝试制作一个简单的类似于CandyCrush的游戏,但我一直收到此错误,不知道该怎么办。
未捕获的TypeError:无法设置未定义的属性'color' 在testForClick(numbercrunch2.html:50) 更新时(numbercrunch2.html:62)
要重新创建错误,只需在文本框中输入一些数字,请单击开始按钮,然后单击一个随机图块。
var c = document.getElementById("canvas");
var ctx = c.getContext("2d");
var tilesX = 0,
tilesY = 0,
tilesWidthX, tilesWidthY, space = 3;
var numb = [];
var mousepos = {
x: 0,
y: 0
},
click = false;
function init(rows, cols) {
tilesWidthX = (canvas.height - rows * 3) / rows;
tilesWidthY = (canvas.height - cols * 3) / cols;
tilesX = rows;
tilesY = cols;
for (var i = 0; i < tilesX; i++) {
numb[i] = [];
for (var j = 0; j < tilesY; j++) {
numb[i][j] = {
val: 1 + Math.round(Math.random() * 6),
color: "grey"
};
ctx.beginPath();
ctx.fillStyle = numb[i][j].color;
ctx.fillRect(space + i * (tilesWidthY + space), space + j * (tilesWidthX + space), tilesWidthY, tilesWidthX);
ctx.closePath();
ctx.beginPath();
ctx.fillStyle = "white";
ctx.font = "20px Arial";
ctx.fillText(numb[i][j].val, 15 + i * (tilesWidthY + space), 30 + j * (tilesWidthY + space), 50);
ctx.closePath();
}
}
}
function testForClick(x, y) {
if (space + x * (tilesWidthX + space) <= mousepos.x && space + y * (tilesWidthY + space) <= mousepos.y && (x + 1) * (tilesWidthX + space) >= mousepos.x && (y + 1) * (tilesWidthY + space) >= mousepos.y) {
numb[x][y].color = "green"; //line 50
}
}
function drawTile(x, y) {
}
function update() {
for (var i = 0; i < 9; i++) {
numb[i] = [];
for (var j = 0; j < 9; j++) {
testForClick(i, j);
drawTile(i, j);
}
}
}
setInterval(update, 300);
function mouseposition(e) {
}
document.getElementById("canvas").addEventListener("click", function(e) {
mousepos.x = e.clientX;
mousepos.y = e.clientY;
}, false);
<canvas id="canvas" height="600" width="600"></canvas>
<form name="formname">
Rows: <input type="text" name="rows"> Columns: <input type="text" name="columns">
<input type="button" value="Start" onClick="init(this.form.rows.value, this.form.columns.value)">
</form>
<div id="t"></div>
答案 0 :(得分:0)
每次运行update()
时,实际上都是通过将前一个对象替换为空的numb
来更新Array object
变量,因此在调用testForClick()
时不会抛出任何对象error
。
function update() {
for (var i = 0;i < 9;i++) {
numb[i] = [];
for ( var j = 0;j < 9;j++) {
testForClick(i,j);
drawTile(i,j);
}
}
} setInterval(update,300);
应该是:
function update()
{
for (var i = 0; i < 9; i++)
{
for (var j = 0; j < 9; j++)
{
testForClick(i, j);
drawTile(i, j);
}
}
};
我创建了一个片段,显示了如何注释(或删除)numb[i] = [];
中的update()
行。
我更新了您的脚本:
// Also, I renamed your 'c' var to 'canvas' because in your init() you are calling it canvas and not 'c'.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var tilesX = 0, tilesY = 0, tilesWidthX, tilesWidthY, space = 3;
var numb = [];
var mousepos = {x: 0, y: 0}, click = false;
function init(rows, cols)
{
tilesWidthX = (canvas.height - rows * 3) / rows;
tilesWidthY = (canvas.height - cols * 3) / cols;
tilesX = rows;
tilesY = cols;
for (var i = 0; i < tilesX; i++)
{
numb[i] = [];
for (var j = 0; j < tilesY; j++)
{
numb[i][j] = {
val: 1 + Math.round(Math.random() * 6),
color: 'grey'
};
ctx.beginPath();
ctx.fillStyle = numb[i][j].color;
ctx.fillRect(space + i * (tilesWidthY + space), space + j * (tilesWidthX + space), tilesWidthY, tilesWidthX);
ctx.closePath();
ctx.beginPath();
ctx.fillStyle = 'white';
ctx.font = '20px Arial';
ctx.fillText(numb[i][j].val, 15 + i * (tilesWidthY + space), 30 + j * (tilesWidthY + space), 50);
ctx.closePath();
}
}
}
function testForClick(x, y)
{
// Now your 'numb' variable hasn't been changed.
console.log('testForClick', numb);
if (space + x * (tilesWidthX + space) <= mousepos.x && space + y * (tilesWidthY + space) <= mousepos.y && (x+1) * (tilesWidthX + space) >= mousepos.x && (y+1) * (tilesWidthY + space) >= mousepos.y)
{
numb[x][y].color = 'green'; //line 50
}
}
function drawTile(x, y)
{
}
function update()
{
for (var i = 0; i < 9; i++)
{
// Every time you update you replace your object with 'val' and 'color' for an empty array.
// that is the reason why every time you call testForClick you have no object in it.
// Just comment/delete this line so your object never disappears.
// numb[i] = [];
for (var j = 0; j < 9; j++)
{
testForClick(i, j);
drawTile(i, j);
}
}
};
// Changed the interval because I didn't have enough time to enter the rows and columns.
setInterval(update, 5000);
function mouseposition(e)
{
}
document.getElementById('canvas').addEventListener('click', function(e){
mousepos.x = e.clientX;
mousepos.y = e.clientY;
}, false);
片段:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var tilesX = 0, tilesY = 0, tilesWidthX, tilesWidthY, space = 3;
var numb = [];
var mousepos = {x: 0, y: 0}, click = false;
function init(rows, cols)
{
tilesWidthX = (canvas.height - rows * 3) / rows;
tilesWidthY = (canvas.height - cols * 3) / cols;
tilesX = rows;
tilesY = cols;
for (var i = 0; i < tilesX; i++)
{
numb[i] = [];
for (var j = 0; j < tilesY; j++)
{
numb[i][j] = {
val: 1 + Math.round(Math.random() * 6),
color: 'grey'
};
ctx.beginPath();
ctx.fillStyle = numb[i][j].color;
ctx.fillRect(space + i * (tilesWidthY + space), space + j * (tilesWidthX + space), tilesWidthY, tilesWidthX);
ctx.closePath();
ctx.beginPath();
ctx.fillStyle = 'white';
ctx.font = '20px Arial';
ctx.fillText(numb[i][j].val, 15 + i * (tilesWidthY + space), 30 + j * (tilesWidthY + space), 50);
ctx.closePath();
}
}
}
function testForClick(x, y)
{
// Now your 'numb' variable hasn't been changed.
console.log('testForClick', numb);
if (space + x * (tilesWidthX + space) <= mousepos.x && space + y * (tilesWidthY + space) <= mousepos.y && (x+1) * (tilesWidthX + space) >= mousepos.x && (y+1) * (tilesWidthY + space) >= mousepos.y)
{
numb[x][y].color = 'green'; //line 50
}
}
function drawTile(x, y)
{
}
function update()
{
for (var i = 0; i < 9; i++)
{
for (var j = 0; j < 9; j++)
{
testForClick(i, j);
drawTile(i, j);
}
}
};
setInterval(update, 5000);
function mouseposition(e)
{
}
document.getElementById('canvas').addEventListener('click', function(e){
mousepos.x = e.clientX;
mousepos.y = e.clientY;
}, false);
<!DOCTYPE html>
<html>
<head>
<title>numbercrunch 2</title>
<meta charset="utf-8">
<style>
canvas {
border: 2px solid black;
}
</style>
</head>
<body>
<canvas id="canvas" height="600" width="600"></canvas>
<form name="formname">
Rows: <input type="text" name="rows">
Columns: <input type="text" name="columns">
<input type="button" value="Start" onClick="init(this.form.rows.value, this.form.columns.value)">
</form>
<div id="t"></div>
</body>
</html>