如何在地图上生成对象,而不在HTML5 Canvas上占用相同的空间或重叠?
在一定程度上随机生成X坐标。我想在数组内查看它是否已经存在,然后是接下来的20个值(考虑到宽度),没有运气。
var nrOfPlatforms = 14,
platforms = [],
platformWidth = 20,
platformHeight = 20;
var generatePlatforms = function(){
var positiony = 0, type;
for (var i = 0; i < nrOfPlatforms; i++) {
type = ~~(Math.random()*5);
if (type == 0) type = 1;
else type = 0;
var positionx = (Math.random() * 4000) + 500 - (points/100);
var duplicatetest = 21;
for (var d = 0; d < duplicatetest; d++) {
var duplicate = $(jQuery.inArray((positionx + d), platforms));
if (duplicate > 0) {
var duplicateconfirmed = true;
}
}
if (duplicateconfirmed) {
var positionx = positionx + 20;
}
var duplicateconfirmed = false;
platforms[i] = new Platform(positionx,positiony,type);
}
}();
我最初通过让他们在大约4000大的区域内生成,减少赔率来做出作弊修复,但我希望随着游戏的进展增加难度,让他们看起来更加团结,使其变得更难。但后来他们重叠了。
粗略的图片形式,我想要这个
....[]....[].....[]..[]..[][]...
不是这个
......[]...[[]]...[[]]....[]....
我希望这是有道理的。
作为参考,这里是阵列检查前的代码和难度,只是便宜的距离黑客。
var nrOfPlatforms = 14,
platforms = [],
platformWidth = 20,
platformHeight = 20;
var generatePlatforms = function(){
var position = 0, type;
for (var i = 0; i < nrOfPlatforms; i++) {
type = ~~(Math.random()*5);
if (type == 0) type = 1;
else type = 0;
platforms[i] = new Platform((Math.random() * 4000) + 500,position,type);
}
}();
编辑1
经过一些调试后,复制品将作为[对象对象]而不是索引号返回,但不确定为什么
编辑2
问题是对象是在数组平台中,而x是在数组对象中,那么我怎样才能再次在里面搜索? ,这就是它之前失败的原因。 感谢firebug和console.log(平台);
platforms = [Object { image=img, x=1128, y=260, more...}, Object { image=img, x=1640, y=260, more...} etc
答案 0 :(得分:7)
您可以实现一个尝试插入对象的while循环,如果它发生碰撞则静默失败。然后添加一个计数器并在放置所需数量的成功对象后退出while循环。如果对象靠近在一起,则此循环可能会运行更长时间,因此您可能还希望为其提供最长寿命。或者你可以实现'甚至可以将z对象放在x和y的地图上'以防止它永远运行。
以下是此示例(demo):
//Fill an array with 20x20 points at random locations without overlap
var platforms = [],
platformSize = 20,
platformWidth = 200,
platformHeight = 200;
function generatePlatforms(k) {
var placed = 0,
maxAttempts = k*10;
while(placed < k && maxAttempts > 0) {
var x = Math.floor(Math.random()*platformWidth),
y = Math.floor(Math.random()*platformHeight),
available = true;
for(var point in platforms) {
if(Math.abs(point.x-x) < platformSize && Math.abs(point.y-y) < platformSize) {
available = false;
break;
}
}
if(available) {
platforms.push({
x: x,
y: y
});
placed += 1;
}
maxAttempts -= 1;
}
}
generatePlatforms(14);
console.log(platforms);
答案 1 :(得分:2)
以下是如何实现网格捕捉哈希:http://jsfiddle.net/tqFuy/1/
var can = document.getElementById("can"),
ctx = can.getContext('2d'),
wid = can.width,
hei = can.height,
numPlatforms = 14,
platWid = 20,
platHei = 20,
platforms = [],
hash = {};
for(var i = 0; i < numPlatforms; i++){
// get x/y values snapped to platform width/height increments
var posX = Math.floor(Math.random()*(wid-platWid)/platWid)*platWid,
posY = Math.floor(Math.random()*(hei-platHei)/platHei)*platHei;
while (hash[posX + 'x' + posY]){
posX = Math.floor(Math.random()*wid/platWid)*platWid;
posY = Math.floor(Math.random()*hei/platHei)*platHei;
}
hash[posX + 'x' + posY] = 1;
platforms.push(new Platform(/* your arguments */));
}
请注意,我正在连接x和y值并将其用作哈希键。这是为了简化检查,并且只是一个可行的解决方案,因为我们将x / y坐标捕捉到特定的增量。如果我们没有捕捉,碰撞检查会更复杂。
对于大型集合(似乎不太可能符合您的标准),使用排除方法可能更好:生成所有可能位置的数组,然后对于每个“平台”,随机从数组中选择一个项目,然后从数组中删除它。这类似于你可能会如何改变一副牌。
编辑 - 有一点需要注意,numPlatforms <= (wid*hei)/(platWid*platHei)
必须评估为true,否则while循环将永远不会结束。
答案 2 :(得分:0)
我在另一个问题(Searching for objects in JavaScript arrays)上找到答案,使用这段代码搜索数组中的对象
function search(array, value){
var j, k;
for (j = 0; j < array.length; j++) {
for (k in array[j]) {
if (array[j][k] === value) return j;
}
}
}
我最终还是重写了一堆代码,以便在其他地方加速并更好地回收平台。
它有效,但缺点是我有更少的平台,因为它真的开始减速。最后这是我想要的,但这样做不再可行。
var platforms = new Array();
var nrOfPlatforms = 7;
platformWidth = 20,
platformHeight = 20;
var positionx = 0;
var positiony = 0;
var arrayneedle = 0;
var duplicatetest = 21;
function search(array, value){
var j, k;
for (j = 0; j < array.length; j++) {
for (k in array[j]) {
if (array[j][k] === value) return j;
}
}
}
function generatePlatforms(ind){
roughx = Math.round((Math.random() * 2000) + 500);
type = ~~(Math.random()*5);
if (type == 0) type = 1;
else type = 0;
var duplicate = false;
for (var d = 0; d < duplicatetest; d++) {
arrayneedle = roughx + d;
var result = search(platforms, arrayneedle);
if (result >= 0) {
duplicate = true;
}
}
if (duplicate = true) {
positionx = roughx + 20;
}
if (duplicate = false) {
positionx = roughx;
}
platforms[ind] = new Platform(positionx,positiony,type);
}
var generatedplatforms = function(){
for (var i = 0; i < nrOfPlatforms; i++) {
generatePlatforms(i);
};
}();
答案 3 :(得分:0)
你去大数据,生成所有可能性,将每个存储在一个数组中,随机播放数组, 修剪前X项,这是你的非启发式算法。