【发布时间】:2013-08-17 04:49:29
【问题描述】:
我有一个函数来生成一个随机地图给定的瓷砖数量、一张起始地图和要使用的网格类型(三角形、正方形、十六进制)。它返回一个瓦片数组map,带有两个额外的属性:seed,使用的起始地图,和adjy*。最初,map 设置为等于seed。出于某种原因,map.seed 不等于 seed 参数。相反,map.seed 等于 map。我发现seed 被map.push() 改变了。我试过"use strict";,使用arguments[1]而不是seed,并移动语句map.seed=seed;(这些没有任何效果)。该代码在 jsHint 中没有任何错误,也不会在控制台中抛出任何错误。
*adjy是邻接的缩写,三角形为0,正方形为1,六边形为2。
我准备了一个jsFiddle,代码也在下面:
console.clear();
var canvas=document.getElementById('canvas'),
ctx=canvas.getContext('2d');
canvas.width=window.innerWidth;
canvas.height=window.innerHeight;
ctx.translate(canvas.width/2,canvas.height/2);
Array.prototype.equals=function(a){//array1==array2 is broken, create substitute
return this.length==a.length&&this.every(
function(e,i){
return e instanceof Array?
a[i]instanceof Array&&e.equals(a[i]):
!(a[i]instanceof Array)&&e==a[i];
}
);
};
Array.prototype.includes=function(n){
return this.some(
function(e){
return n instanceof Array?
n.equals(e):
n==e;
}
);
};
function Map(tiles,seed,adjy){
if(!arguments.length)return [];
if(arguments.length<2)
if(tiles)seed=[[0,0]];
else return [];
if(arguments.length<3)
if(tiles<seed.length)return adjy;//returns undefined
else adjy=1;
var map=seed,cdd=[],nos=//candidate tiles,Neighbors Of Square (or tile)
[[[0,1,-1],[1,0,0]],//triangle
[[0,1,0,-1],[1,0,-1,0]],//square
[[0,1,1,0,-1,-1],[1,0,-1,-1,0,1]]][adjy];//hex
function addAdj(p){//adds adjacent tiles to candidates (cdd)
var c;
for(var i=0;i<nos[0].length;i++)
if(!cdd.includes(
c=[p[0]+nos[0][i],p[1]+nos[1][i]])&&
!map.includes(c))
cdd.push(c);
}
function pickR(){//pick a random tile
var p=cdd.splice(
~~(Math.random()*cdd.length),1)[0];//~~ is the same as floor
addAdj(p);
map.push(p);//the line where the problem happens
}
seed.forEach(addAdj);
while(tiles>map.length)pickR();
map.seed=seed;
map.adjy=adjy;
return map;
}
function drawMap(map){
if(!map.hasOwnProperty('adjy'))return void 0;
function draw0(c){
var x=c[0],y=c[1];
ctx.beginPath();
switch((x+y)%2){
case 0:
x*=5;y*=7;
ctx.moveTo(x,y);
ctx.lineTo(x-5,y+7);
ctx.lineTo(x+5,y+7);
break;
default:
x*=5;y*=7;
ctx.moveTo(x,y+7);
ctx.lineTo(x+5,y);
ctx.lineTo(x-5,y);
}
ctx.closePath();
ctx.fill();
}
function draw1(c){
var x=c[0],y=c[1];
ctx.fillRect(x*10,y*10,10,10);
}
function draw2(c){
var x=c[0]*7,y=c[1];
x+=y*3.5;
y*=7.5;
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(x,y+5);
ctx.lineTo(x+3.5,y+7.5);
ctx.lineTo(x+7,y+5);
ctx.lineTo(x+7,y);
ctx.lineTo(x+3.5,y-2.5);
ctx.closePath();
ctx.fill();
}
switch(map.adjy){
case 0:
map.forEach(draw0);
break;
case 1:
map.forEach(draw1);
break;
default:
map.forEach(draw2);
}
}
var board=new Map(37*6,[[-5,0],[5,0]],2);
console.log(board.seed);
drawMap(board);
我已经包含了所有代码,以防问题实际上不是 seed 在 map 更新时更新,尽管我的开发者控制台测试表明这一点。
【问题讨论】:
-
与问题无关,但值得注意的是:ES6(JavaScript 语言标准的下一个版本)可能包含
Map构造函数,因此您可能需要重命名您的构造函数以避免将来出现兼容性问题。 -
var map=seed如果种子是一个数组(或对象),map 将是相同的数组(不是副本)。也许这就是问题所在?抱歉,我无法弄清楚整个代码。 -
如果你想要一份副本,请使用
var map = seed.slice(0) -
看不到问题,但代码读起来很痛苦,空格是免费的。
-
还有花括号本周发售。 :)
标签: javascript arrays function object