随机映射div

时间:2012-12-21 10:49:55

标签: javascript jquery math

我正在创造一种新的“whack-a-mole”风格游戏,孩子们必须根据问题找到正确的数字。到目前为止它确实很顺利,我有一个计时器,计算正确和错误的答案,当游戏开始时,我有一些称为“字符”的div,它们在设定的时间随机出现在容器中。

我遇到的问题是因为它完全是随机的,有时“字符”看起来彼此重叠。有没有办法对它们进行组织,使它们出现在容器中的设定位置,并且在它们出现时不会重叠。

这里我有将div映射到容器的代码..

    function randomFromTo(from, to) {
        return Math.floor(Math.random() * (to - from + 1) + from);
}

function scramble() {
    var children = $('#container').children();
    var randomId = randomFromTo(1, children.length);
    moveRandom('char' + randomId);
}

function moveRandom(id) {
    var cPos = $('#container').offset();
    var cHeight = $('#container').height();
    var cWidth = $('#container').width();
    var pad = parseInt($('#container').css('padding-top').replace('px', ''));
    var bHeight = $('#' + id).height();
    var bWidth = $('#' + id).width();
    maxY = cPos.top + cHeight - bHeight - pad;
    maxX = cPos.left + cWidth - bWidth - pad;
    minY = cPos.top + pad;
    minX = cPos.left + pad;
    newY = randomFromTo(minY, maxY);
    newX = randomFromTo(minX, maxX);
    $('#' + id).css({
        top: newY,
        left: newX
    }).fadeIn(100, function () {
        setTimeout(function () {
            $('#' + id).fadeOut(100);
            window.cont++;
        }, 1000);
    });

如果有帮助,我会有一个小提琴.. http://jsfiddle.net/pUwKb/8/

4 个答案:

答案 0 :(得分:5)

正如@aug建议的那样,你应该知道在绘画时间不能放置东西的地方,只能把它们放在有效位置。最简单的方法是保持当前占用的位置,以便根据建议的位置进行检查。

我建议像

// locations of current divs; elements like {x: 10, y: 40}
var boxes = [];

// p point; b box top-left corner; w and h width and height
function inside(p, w, h, b) {
     return (p.x >= b.x) && (p.y >= b.y) && (p.x < b.x + w) && (p.y < b.y + h);
}

// a and b box top-left corners; w and h width and height; m is margin
function overlaps(a, b, w, h, m) {
     var corners = [a, {x:a.x+w, y:a.y}, {x:a.x, y:a.y+h}, {x:a.x+w, y:a.y+h}];
     var bWithMargins = {x:b.x-m, y:b.y-m};
     for (var i=0; i<corners.length; i++) {
         if (inside(corners[i], bWithMargins, w+2*m, h+2*m) return true;
     }
     return false;
}

// when placing a new piece
var box;
while (box === undefined) {
   box = createRandomPosition(); // returns something like {x: 15, y: 92}
   for (var i=0; i<boxes.length; i++) {
      if (overlaps(box, boxes[i], boxwidth, boxheight, margin)) {
         box = undefined;
         break;
      }
   }
}
boxes.push(box);

警告:未经测试的代码,请注意错别字。

答案 1 :(得分:2)

您必须实现的基本思想是,当选择随机坐标时,理论上您应该知道不允许的边界,并且您的程序应该知道不选择那些位置(无论您是否找到算法或方法)只是忽略这些范围或你的程序不断检查以确保选择的数字不在边界范围内取决于你。后者更容易实现,但仅仅因为你完全依赖机会是一种糟糕的方式)。

假设例如选择坐标50,70。如果图片大小为50x50,则允许的范围不仅会排除图片的尺寸,还会排除图片各个方向的50px,以免发生重叠。

希望这会有所帮助。如果我有时间,我可能会尝试编写一个例子,但我希望这可以回答问题的概念方面,如果这是你遇到的麻烦。

哦,顺便忘了说这个节目真的很棒。它看起来很棒:))

答案 2 :(得分:2)

你可以通过至少两种方式解决这个问题(这两种方式在我脑海中浮现)。

  1. 如何基于问题的数量,问题面板的大小和保持每个问题坐标位置的数组创建二维网格分割,然后在每个时间框架上随机定位这些面板上的一个允许坐标。
  2. 注意:请阅读本文以获取更多信息:http://eloquentjavascript.net/chapter8.html

    1. 第二种方法遵循相同的原则,但这次是在将面板放在画布上之前检查面板是否与现有面板重叠。
    2. var _grids;
      var GRID_SIZE = 20 //a constant holding the panel size; 
      function createGrids() {
          _grids = new Array();
          for (var i = 0; i< stage.stageWidth / GRID_SIZE; i++) {
              _grids[i] = new Array();
              for (var j = 0; j< stage.stageHeight / GRID_SIZE; j++) {
                  _grids[i][j] = new Array();
              }
          }
      }
      

      然后在单独的函数上创建碰撞检查。我在Actionscript中为碰撞检查创建了gist,但您也可以在Javascript中使用相同的原则。为了鼓舞人心的目的,我创造了这个要点。

答案 3 :(得分:0)

只需使用一个基于电路板宽度的随机数,然后以高度模数...

你得到一个可以放痣的细胞。

对于位置,x和y应该永远不会改变,因为你有9个斑点可以说鼹鼠可以弹出的位置。

x x x
x x x 
x x x

每个单元格的大小将基于%而不是像素,并允许重新调整屏幕大小

1%3 = 1(x) 3%3 = 0(y)

然后不可能重叠。

一旦定位了痣,如果需要,它可以根据某些扩展逻辑显示,隐藏或移动等。

如果想按照自己的方式行事,只需要一个快速的重新定位算法......如果要通过设置x检查要检查的字符的X +宽度&gt; = x,只需将NE设置为SW即可= y +重叠项目的高度。您还可以通过缓存最后一个x并确保随机数不是&lt;而在绘图例程中强制执行该逻辑。最后+项目的宽度。

newY = randomFromTo(minY, maxY); newX = randomFromTo(minX, maxX); if(newX > lastX + characterWidth){ /*needful*/}

但是仍然可能有重叠...

如果你想完全消除它,你需要跟踪状态,例如每个x的位置,然后迭代该列表以找到新位置或首先定位它们然后所有它们随机移动而不交叉哪个会能从这一点上只用填充来控制。

总的来说,我认为将X从0开始然后再增加直到你处于X +字符宽度&gt;会更容易。大于板的宽度。然后只需按字符高度增加Y,设置X = 0或字符宽度或其他偏移量。

newX = 0; newX += characterWidth; if(newX + chracterWidth > boardWidth) newX=0; newY+= characterHeight;

这导致没有重叠,没有任何东西可以迭代或跟踪你现在所做的事情,唯一的缺点是显示的字符的模式是'棋盘格式'或彼此相邻(可能随机)水平和垂直放置之间的间距,例如,如果你也想要随机调整填充

首先,这是一个随机的事情,增加了复杂性。

我更新你的小提琴以证明我已经删除了随机并停止了重叠:)

http://jsfiddle.net/pUwKb/51/