Подтвердить что ты не робот

Случайное отображение divs

Я создаю новую игру стиля "whack-a-mole", в которой дети должны набирать правильные цифры в соответствии с вопросом. Пока все идет хорошо, у меня есть таймер, подсчитывают правильные и неправильные ответы, и когда игра запущена, у меня есть несколько div, называемых "символами", которые появляются в контейнере случайным образом в заданное время.

Проблема, с которой я столкнулась, состоит в том, что, поскольку она полностью случайна, иногда "символы" появляются друг с другом. Есть ли способ организовать их, чтобы они отображались в заданных местах в контейнере и не перекрывались, когда они появляются.

Здесь у меня есть код, который отображает divs в контейнер.

    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/

4b9b3361

Ответ 1

Как подсказывает @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);

Предупреждение: непроверенный код, остерегайтесь опечаток.

Ответ 2

Основная идея, которую вам придется реализовать, заключается в том, что, когда выбрана случайная координата, теоретически вам следует знать границы того, что недопустимо, и ваша программа должна знать, чтобы не выбирать эти места (вы найдете алгоритм или способ просто игнорируя эти диапазоны или ваша программа постоянно проверяет, чтобы убедиться, что выбранный номер не находится в пределах границы, зависит от вас, последний проще реализовать, но это плохой способ обойти это просто потому, что вы полностью полагаетесь на случайность).

Скажем, например, выбрана координата 50, 70. Если размер изображения равен 50x50, диапазон допустимых значений будет исключать не только размеры изображения, но и 50 пикселей во всех направлениях изображения, чтобы не возникало перекрытия.

Надеюсь, это поможет. Если у меня будет время, я могу попытаться привести пример, но я надеюсь, что это ответит на концептуальный аспект вопроса, если это то, с чем вы столкнулись.

О и btw забыли сказать действительно отличную работу в этой программе. Это выглядит потрясающе:)

Ответ 3

Вы можете подойти к этой проблеме, по крайней мере, двумя способами (эти два появляются у меня в голове).

  • Как создать 2-мерную сегрегацию сетки на основе количества вопросов, размеров панели вопросов и массива, содержащего положение каждого вопроса, а затем на каждом временном интервале для случайного размещения этих панелей на одном из разрешенные координаты.

Примечание: прочитайте эту статью для получения дополнительной информации: http://eloquentjavascript.net/chapter8.html

  • Второй подход соответствует тому же принципу, но на этот раз, чтобы проверить, перекрывает ли панель существующую панель, прежде чем разместить ее на холсте.
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();
        }
    }
}

Затем на отдельной функции для создания проверки столкновения. Я создал gist для проверки конфликтов в ActionScript, но вы можете использовать тот же принцип и в Javascript. Я создал этот принцип для вдохновляющих целей.

Ответ 4

Просто используйте случайное число, основанное на ширине вашей доски, а затем по модулю с высотой...

Вы получаете ячейку, в которую вы можете положить родинку.

Для позиций 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 + высота элемента, который перекрывается. Вы могли бы также применять эту логику в процедуре рисования путем кэширования последнего x и обеспечения того, чтобы случайное число не было < last + width элемента.

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/