12

我正在创建一个新的“打地鼠”风格的游戏,孩子们必须根据问题打出正确的数字。到目前为止一切都很好,我有一个计时器,计算正确和错误的答案,当游戏开始时,我有一些称为“字符”的 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

4 回答 4

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);

警告:未经测试的代码,请注意拼写错误。

于 2012-12-21T11:39:12.500 回答
2

The basic idea you will have to implement is that when a random coordinate is chosen, theoretically you SHOULD know the boundaries of what is not permissible and your program should know not to choose those places (whether you find an algorithm or way of simply disregarding those范围或您的程序不断检查以确保选择的数字不在边界内由您决定。后者更容易实现,但只是因为您完全依赖机会,所以这是一种不好的方法)。

例如,假设选择了坐标 50、70。如果图片大小为50x50,允许的范围不仅不包括图片的尺寸,还包括图片各个方向的50px,这样就不会发生重叠。

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

哦,顺便说一句,忘了说这个节目做得很好。它看起来棒极了:)

于 2012-12-21T11:09:03.183 回答
2

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

  1. 如何根据问题的数量、问题面板的大小和保存每个问题坐标位置的数组创建二维网格分割,然后在每个时间范围内将这些面板随机定位在允许的坐标之一上。

注意:阅读本文了解更多信息:http ://eloquentjavascript.net/chapter8.html

  1. 第二种方法遵循相同的原则,但这次是在将面板放置在画布上之前检查面板是否与现有面板重叠。
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 中的碰撞检查创建了一个要点,但您也可以在 Javascript 中使用相同的原理。出于鼓舞人心的目的,我创建了这个要点。

于 2012-12-21T11:22:53.707 回答
0

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

你会得到一个可以放置痣的单元格。

对于位置,x 和 y 永远不应该改变,因为你有 9 个点,让我们说一下痣会在哪里弹出。

x x x
x x x 
x x x

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

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

那么就不可能有重叠。

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

如果想保持你的方式,你只需要一个快速的重新定位算法......只需将 NE 设置为 SW 如果 X + width >= x 你想通过设置 x = y+height 检查字符重叠的项目。您还可以通过缓存最后一个 x 并确保随机数不 < last + 项目的宽度来在绘图例程中强制执行该逻辑。

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

然而,仍然可能有重叠......

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

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

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

这导致没有重叠,也没有什么可以迭代或跟踪您现在所做的事情,唯一的缺点是显示字符的模式是“棋盘样式”或彼此相邻(之间可能有随机间距水平和垂直放置,例如,如果您愿意,也可以随机调整填充)

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

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

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

于 2013-01-09T09:02:10.000 回答