Чтобы элемент передвигался рандомно
По полю передвигается квадратик (вверх-вниз, влево-вправо)
http://plnkr.co/edit/wx0ygfaGTWHj9dSz07G0?p=preview 1) Как сделать так чтобы он передвигался рандомно? Т.е. либо влево на 20рх, либо вправо на 20рх, либо вверх, либо вниз. Естественно нужно чтобы он это это делал в пределах контейнера, и передвигался постоянно (знаю что может помочь Math.random(), но как именно его прописать?) 2) На поле есть неподвижные квадратики - это камни. На них элемент не может заходить - он должен их обходить 3) Как создать второй такой же элемент, чтобы он рождался в рандомном месте(кроме камня и другого элемента), также ходил, но при встрече двух элементов, они не могли вставать друг на друга, а обходили друг друга |
yaparoff,
массив надо делать, чтобы знать где можно ходить, а где какой-то обьект.много кода ... коллизии обьектов вычислять. |
Цитата:
Т.е. есть массив массивов list где есть 8 вариантов, куда сделать шаг, потом это перебирается Math.random() и выбирается одно направление. и как результат этого вставить в мой код? var randomDirection = { list: [ [0, -20], [20, -20], [20, 0], [20, 20], [0, 20], [-20, 20], [-20, 0], [-20, -20] ], already: [], random: function () { return this.directions[Math.floor(Math.random() * this.list.length)]; }, get: function () { var direction = this.random(); if (this.already.length >= this.list.length) { this.already = []; return direction; } if (this.already.indexOf(direction) !== -1) { return this.get(); } else { this.already.push(direction); return direction; } } }; alert(randomDirection.get()); |
Цитата:
var stones = document.querySelectorAll('.stone'); var stonesCoords = []; for (var i = 0; i < stones.length; i++) { stonesCoords.push(getCoords(stones[i])); } function getCoords(element) { var box = element.getBoundingClientRect(); return { top: box.top + pageYOffset, left: box.left + pageXOffset, right: box.right + pageXOffset, bottom: box.bottom + pageYOffset }; } В код добавил http://plnkr.co/edit/wx0ygfaGTWHj9dSz07G0?p=preview Хотелось бы добавить, что элемент должен видеть только в пределах одного хода - дальше он не видит. |
Как теперь это все воедино соединить?
|
yaparoff,
может ну его нафиг? |
Цитата:
|
Rise,
Да. Из книги выразительный JavaScript Автор рассказывает как делать, НО нужна своя реализация, нельзя копировать код. Автор так объясняет, что мне не остается просто брать и копировать оттуда код. Но так нельзя. Мне код автора во многих местах не понятен. Поэтому реализовываю по своему, чтобы каждая строчка кода мне понятна была. В итоге примерно вот что должно получиться http://eloquentjavascript.net/code/#7.2 но объектов может быть меньше чем там |
yaparoff, может чем поможет
Броуновское движение на js |
Цитата:
(о нем здесь написано) Копировать нельзя function Vector(x, y) { this.x = x; this.y = y; } Vector.prototype.plus = function(other) { return new Vector(this.x + other.x, this.y + other.y); }; var grid = ["top left", "top middle", "top right", "bottom left", "bottom middle", "bottom right"]; function Grid(width, height) { this.space = new Array(width * height); this.width = width; this.height = height; } Grid.prototype.isInside = function(vector) { return vector.x >= 0 && vector.x < this.width && vector.y >= 0 && vector.y < this.height; }; Grid.prototype.get = function(vector) { return this.space[vector.x + this.width * vector.y]; }; Grid.prototype.set = function(vector, value) { this.space[vector.x + this.width * vector.y] = value; }; var grid = new Grid(5, 5); grid.set(new Vector(1, 1), "X"); console.log(grid.get(new Vector(1, 1))); |
И вот это как самому реализовать, не копируя?
var directions = { "n": new Vector( 0, -1), "ne": new Vector( 1, -1), "e": new Vector( 1, 0), "se": new Vector( 1, 1), "s": new Vector( 0, 1), "sw": new Vector(-1, 1), "w": new Vector(-1, 0), "nw": new Vector(-1, -1) }; /* Вот простое тупое существо, которое просто идёт, пока не врезается в препятствие, а затем отскакивает в случайном направлении. */ function randomElement(array) { return array[Math.floor(Math.random() * array.length)]; } function BouncingCritter() { this.direction = randomElement(Object.keys(directions)); }; BouncingCritter.prototype.act = function(view) { if (view.look(this.direction) != " ") this.direction = view.find(" ") || "s"; return {type: "move", direction: this.direction}; }; |
Цитата:
У меня задача - сделать собственную реализацию. Копировать запрещено В поисках этого решения и пришел сюда. Просто забить и сказать "да ну его нафиг" - не получиться. Мне обязательно нужно это сделать |
(удалено)
|
черновой набросок
<style> .container { position:absolute; top:30px; left:20px; width:400px; height:400px; border:1px solid gray; } .animal { width:20px; height:20px; transition: 0.3s; border-radius: 10px; background-color: red; } .stone { width:20px; height:20px; border-radius: 10px; background-color: black; } </style> Количество животных: <input type='number' id ='aCount' value='2'> Количество камней: <input type='number' id ='sCount' value='10'> <input type='button' id='mainBut' value='Пуск'> <div class='container'></div> <script> var field = document.querySelector('.container'), fieldTop = +field.style.top, fieldLeft = +field.style.left, unit, units = [], animals = [], stoneCount = 10, animalCount = 2, stopFlag = false; function createUnit(unitType) { var unitTop, unitLeft, noFree = true, unitPos = {}; do { unitTop = (Math.round(Math.random() * 19 ) * 20 - fieldTop) + 'px'; unitLeft = (Math.round(Math.random() * 19 ) * 20 - fieldLeft) + 'px'; noFree = false; for(var i = 0; i < units.length; i++){ if(units[i].top == unitTop && units[i].left == unitLeft) noFree = true; } } while (noFree); unit = document.createElement('div'); unit.classList.add(unitType); unit.style.position = 'absolute'; unit.style.top = unitTop; unit.style.left = unitLeft; field.appendChild(unit); unitPos.top = unitTop; unitPos.left = unitLeft; units.push(unitPos); if(unitType == 'animal') { animals.push(unitPos); unit.id = "a" + i; unit.innerText = i; } } function moveAnimals() { var stepTop, stepLeft, unitTop, unitLeft, noFree, unitPos = {}; for(var i = 0; i<animals.length;i++) { noFree = true; do { stepTop = Math.round(Math.random() * 2 - 1) * 20; stepLeft = Math.round(Math.random() * 2 - 1) * 20; unitTop = +animals[i].top.replace(/\D/g,"") + stepTop; unitLeft = +animals[i].left.replace(/\D/g,"") + stepLeft; if(unitTop < 0 || unitLeft < 0 || unitTop > 380 || unitLeft > 380) { noFree = true; } else { unitTop = unitTop + "px"; unitLeft = unitLeft + "px"; noFree = false; for(var j = 0; j< units.length; j++){ if(units[j].top == unitTop && units[j].left == unitLeft) noFree = true; } } } while (noFree); units[i].top = unitTop; units[i].left = unitLeft; animals[i].top = unitTop; animals[i].left = unitLeft; var elem = document.querySelector('#a' + i); elem.style.top = unitTop; elem.style.left = unitLeft; } } function start() { if(stopFlag) return; moveAnimals(); setTimeout(start, 500); }; function startLife() { for(var i = 0; i < animalCount;i++){ createUnit('animal'); } for(var i = 0; i < stoneCount;i++){ createUnit('stone'); } start(); } document.querySelector('#mainBut').onclick = function() { if(this.value == 'Пуск') { stopFlag = false; animalCount = +document.querySelector('#aCount').value; stoneCount = +document.querySelector('#sCount').value; this.value = 'Стоп'; startLife(); } else { stopFlag = true; this.value = 'Пуск'; field.innerHTML = ""; units = []; animals = []; } } </script> |
Dilettante_Pro, огромное спасибо!
В целом код понятен, правда хотелось бы некоторые моменты уточнить: 1) Для чего стоит "+" у +field.style.top. Он преобразует в число, но ведь там и так будет число. Или нет? А понял, туда поступает допустим 20рх и он обрезает "рх" и оставляет только "20" - я правильно понял? 2) Что означает noFree = true ? То что ячейка занята? 3) На 36 строке для чего мы Math.random() умножаем именно на 19 ? Затем всё это умножаем на 20 и после вычитаем fieldTop? Почему именно так? 4) Что означает эта запись (строка 40): if(units[i].top == unitTop && units[i].left == unitLeft) noFree = true; 5) Для чего в 60-ой строке стоит noFree = true; ? 6) Для чего нужен второй цикл на 71 строке ? 7) Строки 77 и 79: для чего мы задаем одно и то же значение для units[i].left и animals[i].left ? 8) Как существо понимает, что на камень нельзя заходить? |
76 units[i],top = unitTop; 78 animals[i],top = unitTop; Вот, а в strict mode бы не пустило. |
Цитата:
|
yaparoff,
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
units - все элементы - камни и животные, для проверки занятости ячеек animals - животные, для управления Цитата:
Цитата:
PS: имейте в виду, что строки скрипта немного сдвинулись в связи с расширением функциональности в последней редакции |
Цитата:
|
игра кролики и клубника (передвижение обьекта в массиве рандомно)
yaparoff,
запусти кроликов в огород (клик по полю) <!DOCTYPE html> <html> <head> <title>Untitled</title> <meta charset="utf-8"> <style type="text/css"> *{ padding: 0; margin: 0; } .cell { text-align: center; float: left; height: 23px; width: 23px; border: #0000CD 1px solid; background-color: #FFEBCD; font-size: 12px; -webkit-transition: all .5s ease-in-out; -moz-transition: all .5s ease-in-out; -o-transition: all .5s ease-in-out; transition: all .5s ease-in-out; } #matrix{ display: inline-block; margin: 50px auto; } .red{ border-radius: 4px; background-image: url(http://www.smayly.ru/gallery/big/vkBunny/12.png); background-repeat: no-repeat; background-size: cover; } .yellow{ background: #FFFF00; } .green{ background-image: url(http://moyhutor.net/images/klubnika2.png); background-repeat: no-repeat; background-size: cover; } .blue{ background: #0000FF } </style> <script> window.addEventListener("DOMContentLoaded", function() { var matrix = document.getElementById("matrix"), l = (Math.random() * 15 | 0) + 10; t = (Math.random() * 10 | 0) + 10, n = l * t; function createMatrix() { var w; for (var i = 0; i < n; i++) { var div = document.createElement("div"); div.className = "cell"; Math.random() < .07 && div.classList.add("green"); div.dataset.index = i; matrix.appendChild(div); if (i == l - 1) w = matrix.offsetWidth + 1 } matrix.style.width = w + "px"; matrix.style.display = "block" } function chec(indx, size) { var s = [], x = indx % l, y = indx / l | 0; size = size || 1; for (var i = y - size; i <= y + size; i++) for (var k = x - size; k <= x + size; k++) { var num = k + i * l, max = Math.max(Math.abs(i - y), Math.abs(k - x)); i > -1 && i < t && k > -1 && k < l && num < i * l + l && num != indx? s.push(num): s.push(null) } return { s: s } } createMatrix(); var divs = [].slice.call(document.querySelectorAll(".cell"), 0); matrix.addEventListener("click", function(event) { var el = event.target, cls = el.classList; if (cls && cls.contains("cell") && !cls.contains("green") && !cls.contains("red")) { var index = el.dataset.index; move(index, Math.random() * 8 | 0) } }); function move(index, num) { var arr = chec(index, 1); m = []; var k = arr.s.filter(function(indx,i) { return indx !== null && !divs[indx].classList.contains("green") && !divs[indx].classList.contains("red") && indx != index && m.push(i) }); if (k.length) { divs[index].classList.remove("red"); if (m.indexOf(num) == -1|| Math.random() < .17) num = m[Math.floor(Math.random() * m.length)]; k = arr.s[num]; divs[k].classList.add("red"); window.setTimeout(function() { move(k, num) }, 500) } else window.setTimeout(function() { move(index, num) }, 2000) } }); </script> </head> <body> <p></p> <div id="matrix" ></div> </body> </html> |
рони,
Похоже, я телепат: я чувствовал, что что-то подобное появится |
Dilettante_Pro,
:) |
:write: изменил алгоритм движения кроликов пост №23
|
Прикрутил к коду Dilettante_Pro кое-что еще:
добавил некоторые элементы ООП; добавил новый юнит - траву. Теперь думаю над следующим: 1) Нужно реализовать эффект зарастания травы по всему полю. Т.е если на клетке трава, то через некоторое время(допустим через 4 сек) на соседней клетке (выбирается рандомно) тоже должна появиться трава. (смотреть строку № 100) http://plnkr.co/edit/yFvDmjtbARSTLjoKK0rW?p=preview 2) Животное (красный квадратик) должно кушать эту траву и получать энергию (баллы). Если оно не ест (количество баллов = 0) - через какое-то время оно умирает. Сейчас же животное не может даже зайти на траву, т.к. никакой юнит не может заходить на другого юнита |
yaparoff,
У вас при движении животных получается двойной forEach - при вызове функции moveAnimal() и внутри этой функции. Из-за этого животные прыгают как сумасшедшие |
Цитата:
Написал вот так: setInterval(function() { moveAnimal(); }, 1000); Но интерпретатор не может понять что это за moveAnimal(); К нему надо подобраться по другому. Как? |
Цитата:
Animal.prototype.moveAnimal = function(i) { var stepTop, stepLeft, unitTop, unitLeft, noFree, unitPos = {}; // for (var i = 0; i < animals.length; i++) { noFree = true; do { stepTop = Math.round(Math.random() * 2 - 1) * 20; stepLeft = Math.round(Math.random() * 2 - 1) * 20; unitTop = +animals[i].top.replace(/\D/g,"") + stepTop; unitLeft = +animals[i].left.replace(/\D/g,"") + stepLeft; if (unitTop < 0 || unitLeft < 0 || unitTop > 380 || unitLeft > 380) { noFree = true; } else { unitTop = unitTop + 'px'; unitLeft = unitLeft + 'px'; noFree = false; for(var j = 0; j< units.length; j++) { if(units[j].top == unitTop && units[j].left == unitLeft) { noFree = true; } } } } while (noFree); units[i].top = unitTop; units[i].left = unitLeft; animals[i].top = unitTop; animals[i].left = unitLeft; var elem = document.querySelector('#a' + i); elem.style.top = unitTop; elem.style.left = unitLeft; // } } setInterval(function() { newAnimals.forEach(function(animal, index) { console.log(animal); animal.moveAnimal(index); }); }, 1000); |
Часовой пояс GMT +3, время: 22:19. |