简体   繁体   English

随机映射div

[英]randomly mapping divs

I am creating a new "whack-a-mole" style game where the children have to hit the correct numbers in accordance to the question. 我正在创造一种新的“打鼹鼠”风格的游戏,孩子们必须根据问题打出正确的数字。 So far it is going really well, I have a timer, count the right and wrong answers and when the game is started I have a number of divs called "characters" that appear in the container randomly at set times. 到目前为止它真的很顺利,我有一个计时器,计算正确和错误的答案,当游戏开始时,我有一些称为“字符”的div,它们在设定的时间随机出现在容器中。

The problem I am having is that because it is completely random, sometimes the "characters" appear overlapped with one another. 我遇到的问题是,因为它是完全随机的,有时“字符”看起来彼此重叠。 Is there a way to organize them so that they appear in set places in the container and don't overlap when they appear. 有没有办法组织它们,以便它们出现在容器中的设置位置,并且在它们出现时不会重叠。

Here I have the code that maps the divs to the container.. 这里我有代码将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);
    });

I have a fiddle if it helps.. http://jsfiddle.net/pUwKb/8/ 如果它有帮助我有一个小提琴.. http://jsfiddle.net/pUwKb/8/

As @aug suggests, you should know where you cannot place things at draw-time, and only place them at valid positions. 正如@aug建议的那样,你应该知道在绘画时间不能放置东西的地方,只能把它们放在有效位置。 The easiest way to do this is to keep currently-occupied positions handy to check them against proposed locations. 最简单的方法是保持当前占用的位置,以便根据建议的位置进行检查。

I suggest something like 我建议像

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

Warning: untested code, beware the typos. 警告:未经测试的代码,请注意错别字。

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 ranges or your program constantly checks to make sure that the number chosen isn't within the boundary is up to you. the latter is easier to implement but is a bad way of going about it simply because you are entirely relying on chance). 您必须实现的基本思想是,当选择随机坐标时,理论上您应该知道不允许的边界,并且您的程序应该知道不要选择那些位置(无论您是找到算法还是简单地忽略这些位置的方法)范围或你的程序不断检查,以确保所选择的数字不在你的范围内。后者更容易实现,但仅仅因为你完全依赖机会是一种糟糕的方式。

Let's say for example coordinate 50, 70 is selected. 假设例如选择坐标50,70。 If the picture is 50x50 in size, the range of what is allowed would exclude not only the dimensions of the picture, but also 50px in all directions of the picture so that no overlap may occur. 如果图片的大小为50x50,则允许的范围不仅会排除图片的尺寸,还会排除图片所有方向的50px,这样就不会出现重叠。

Hope this helps. 希望这可以帮助。 If I have time, I might try to code an example but I hope this answers the conceptual aspect of the question if that is what you were having trouble with. 如果我有时间,我可能会尝试编写一个例子,但我希望这可以回答问题的概念方面,如果这是你遇到的麻烦。

Oh and btw forgot to say really great job on this program. 哦,顺便忘了说这个节目真的很棒。 It looks awesome :) 它看起来很棒:)

You can approach this problem in at least two ways (these two are popped up in my head). 你可以通过至少两种方式解决这个问题(这两种方式在我脑海中浮现)。

  1. How about to create a 2 dimensional grid segmentation based on the number of questions, the sizes of the question panel and an array holding the position of each question coordinates and then on each time frame to position randomly these panels on one of the allowed coordinates. 如何基于问题的数量,问题面板的大小和保持每个问题坐标的位置的数组创建二维网格分割,然后在每个时间帧上将这些面板随机定位在允许的坐标之一上。

Note: read this article for further information: http://eloquentjavascript.net/chapter8.html 注意:阅读本文以获取更多信息: http//eloquentjavascript.net/chapter8.html

  1. The second approach follow the same principle, but this time to check if the panel overlap the existing panel before you place it on the canvas. 第二种方法遵循相同的原则,但这次是在将面板放在画布上之前检查面板是否与现有面板重叠。
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();
        }
    }
}

Then on a separate function to create the collision check. 然后在单独的函数上创建碰撞检查。 I've created a gist for collision check in Actionscript, but you can use the same principle in Javascript too. 我在Actionscript中为碰撞检查创建了一个要点 ,但你也可以在Javascript中使用相同的原理。 I've created this gist for inspirational purposes. 为了鼓舞人心的目的,我创造了这个要点。

Just use a random number which is based on the width of your board and then modulo with the height... 只需使用一个基于电路板宽度的随机数,然后用高度模数...

You get a cell which is where you can put the mole. 你得到一个细胞,你可以放痣。

For the positions the x and y should never change as you have 9 spots lets say where the mole could pop up. 对于位置,x和y应该永远不会改变,因为你有9个斑点可以说鼹鼠可以弹出的位置。

x x x
x x x 
x x x

Each cell would be sized based on % rather then pixels and would allow re sizing the screen 每个单元格的大小将基于%而不是像素,并允许重新调整屏幕大小

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

Then no overlap is possible. 然后不可能重叠。

Once the mole is positioned it can be show or hidden or moved etc based on some extended logic if required. 一旦鼹鼠定位,如果需要,可以基于一些扩展逻辑显示或隐藏或移动等。

If want to keep things your way and you just need a quick re-position algorithm... just set the NE to the SW if the X + width >= x of the character you want to check by setting the x = y+height of the item which overlaps. 如果想按照自己的方式进行操作,只需要快速重新定位算法...如果要通过设置x = y + height检查要检查的字符的X +宽度> = x,则将NE设置为SW重叠的项目。 You could also enforce that logic in the drawing routine by caching the last x and ensuring the random number was not < last + width of the item. 您还可以通过缓存最后一个x并确保随机数不是项目的最后+宽度,在绘图例程中强制执行该逻辑。

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

There could still however be overlap... 然而,仍然可能有重叠......

If you wanted to totally eliminate it you would need to keep track of state such as where each x was and then iterate that list to find a new position or position them first and then all them to move about randomly without intersecting which would would be able to control with just padding from that point. 如果你想完全消除它,你需要跟踪状态,例如每个x所在的位置,然后迭代该列表以找到一个新位置或首先定位它们然后所有它们随机移动而不交叉,这将是能够的从那一点开始只用填充来控制。

Overall I think it would be easier to just keep X starting at 0 and then and then increment until you are at a X + character width > greater then the width of the board. 总的来说,我认为将X从0开始然后再增加直到你的X +字符宽度>大于电路板的宽度会更容易。 Then just increase Y by character height and Set X = 0 or character width or some other offset. 然后只需按字符高度增加Y,设置X = 0或字符宽度或其他偏移量。

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

That results in no overlap and having nothing to iterate or keep track of additional to what you do now, the only downside is the pattern of the displayed characters being 'checker board style' or right next to each other (with possible random spacing in between horizontal and vertical placement eg you could adjust the padding randomly if you wanted too) 这导致没有重叠,没有任何东西可以迭代或跟踪你现在所做的事情,唯一的缺点是显示的字符的模式是'棋盘格式'或彼此相邻(可能在它们之间的随机间距)水平和垂直放置,例如你可以随意调整填充)

It's the whole random thing in the first place that adds the complexity. 首先,这是一个随机的事情,增加了复杂性。

AND I updated your fiddle to prove I eliminated the random and stopped the overlap :) 我更新你的小提琴,以证明我删除了随机并停止重叠:)

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM