随机映射div
我正在创造一种新的“打鼹鼠”风格的游戏,孩子们必须根据问题打出正确的数字。 到目前为止它真的很顺利,我有一个计时器,计算正确和错误的答案,当游戏开始时,我有一些称为“字符”的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/
正如@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 (px >= bx) && (py >= by) && (px < bx + w) && (py < by + 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:ay}, {x:ax, y:a.y+h}, {x:a.x+w, y:a.y+h}]; var bWithMargins = {x:bx-m, y:by-m}; for (var i=0; i
警告:未经测试的代码,请注意错别字。
您必须实现的基本思想是,当选择随机坐标时,理论上您应该知道不允许的边界,并且您的程序应该知道不要选择那些位置(无论您是找到算法还是简单地忽略那些范围或你的程序不断检查,以确保选择的数字不在边界范围内取决于你。后者更容易实现,但只是因为你完全依赖机会是一个糟糕的方式。
假设例如选择坐标50,70。 如果图片的大小为50×50,则允许的范围不仅会排除图片的尺寸,还会排除图片所有方向的50px,这样就不会出现重叠。
希望这可以帮助。 如果我有时间,我可能会尝试编写一个例子,但我希望这可以回答问题的概念方面,如果这是你遇到的麻烦。
哦,顺便忘了说这个节目真的很棒。 它看起来很棒:)
你可以通过至少两种方式解决这个问题(这两种方式在我脑海中浮现)。
- 如何基于问题的数量,问题面板的大小和保持每个问题坐标的位置的数组创建二维网格分割,然后在每个时间帧上将这些面板随机定位在允许的坐标之一上。
注意:阅读本文以获取更多信息: http : //eloquentjavascript.net/chapter8.html
- 第二种方法遵循相同的原则,但这次是在将面板放在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(); } } }
然后在单独的函数上创建碰撞检查。 我在Actionscript中为碰撞检查创建了一个要点 ,但你也可以在Javascript中使用相同的原理。 我为了鼓舞人心的目的创造了这个要点。
只需使用一个基于电路板宽度的随机数,然后用高度模数…
你得到一个细胞,你可以放痣。
对于位置,x和y应该永远不会改变,因为你有9个斑点可以说鼹鼠可以弹出的位置。
xxx xxxxxx
每个单元格的大小将基于%而不是像素,并允许重新调整屏幕大小
1%3 = 1(x)3%3 = 0(y)
然后不可能重叠。
一旦鼹鼠被定位,如果需要,可以基于一些扩展逻辑显示或隐藏或移动等。
如果想按照自己的方式进行操作并且只需要一个快速的重新定位算法…如果要通过设置x = y +高度检查要检查的字符的X +宽度> = x,则将NE设置为SW重叠的项目。 您还可以通过缓存最后一个x并确保随机数不是<项目的最后+宽度来在绘图例程中强制执行该逻辑。
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;
这导致没有重叠,没有任何东西可以迭代或跟踪你现在所做的事情,唯一的缺点是所显示的字符的模式是“棋盘格式”或彼此相邻(两者之间可能存在随机间距)水平和垂直放置,例如你可以随意调整填充)
首先,这是一个随机的事情,增加了复杂性。
我更新你的小提琴,以certificate我删除了随机并停止重叠:)