Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 07.06.2016, 22:10
Профессор
Отправить личное сообщение для Bond Посмотреть профиль Найти все сообщения от Bond
 
Регистрация: 16.06.2013
Сообщений: 172

ООП. Летящие пули
Всем здравствуйте.
Задача состоит в следующем - при определенном событии - а нашем случае при клике на кнопку нужно создать элемент( к примеру пулю) и заставить ее двигаться - а при определенном условии (в нашем случае при пролете пули 1000 пикселей) удалить анимацию которая ее двигала и саму пулю (элемент)
Все это я реализовал так http://1.top-start.ru/bullet/
Вот код скомпилированный с TypeScript:
var Bullet = (function () {
    function Bullet() {
        this.element = document.getElementById('transline');
        this.create();
    }
    Bullet.prototype.create = function () {
        this.childElement = document.createElement("li");
        this.element.appendChild(this.childElement);
        this.move();
    };
    Bullet.prototype.move = function () {
        var left = 0;
        var _this = this;
        var move = setInterval(function () {
            _this.childElement.style.left = (left += 4) + "px";
            if (left > 1000) {
                clearInterval(move);
                _this.childElement.remove();
            }
        }, 10);
    };
    return Bullet;
}());
var button2 = document.getElementById("create");
button2.addEventListener('click', function () {
    new Bullet();
});


То есть имеется класс описывающий пулю, а при клике создается объект который все реализовывает для каждой отдельной пули.
Вопрос в следующем - правильный ли это подход?
Если да то получается при каждом клике создается объект - при достижении условия удаляется анимация и элемент изображающий пулю но сам объект остается - надо ли его удалять и если да то как? Ведь этих объектов теоретически может быть десятки а то и сотни тысяч.

Если мой подход неверный то как сделать что бы можно было создать один объект и что бы он управлял всеми пулями
В нашем случае это должно работать
var bullet = new Bullet();
var button2 = document.getElementById("create");
button2.addEventListener('click', function() {
	bullet.create();
});

Изначально так и думал сделать - но не получилось - там проблемы с setInterval возникает и все криво работает.
Буду признателен за помощь.

Последний раз редактировалось Bond, 07.06.2016 в 22:13.
Ответить с цитированием
  #2 (permalink)  
Старый 07.06.2016, 23:27
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Сообщение от Bond Посмотреть сообщение
но сам объект остается
Мне кажется если на него нет ссылок то он удалится автоматически.

Последний раз редактировалось Rise, 07.06.2016 в 23:33.
Ответить с цитированием
  #3 (permalink)  
Старый 07.06.2016, 23:27
Аватар для Coriolan161
Профессор
Отправить личное сообщение для Coriolan161 Посмотреть профиль Найти все сообщения от Coriolan161
 
Регистрация: 21.11.2015
Сообщений: 440

Bond,
Ты пишешь надо ли удалять объект... как удалить объект в этом языке?
Ответить с цитированием
  #4 (permalink)  
Старый 08.06.2016, 00:41
Профессор
Отправить личное сообщение для Bond Посмотреть профиль Найти все сообщения от Bond
 
Регистрация: 16.06.2013
Сообщений: 172

Rise, так и есть, поразбирался, погуглил, в коде поставил создание 10 объектов через каждые 100 мс за один клик - запустил в отладчике посмотрел - вроде все гуд, память очищается почти сразу же.

Coriolan161, ну может не сам объект а ссылки на него через delete.
А вообще имел ввиду стоит ли в моей ситуации заботиться о памяти и т.д
Ответить с цитированием
  #5 (permalink)  
Старый 08.06.2016, 18:12
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Сообщение от Bond Посмотреть сообщение
В нашем случае это должно работать
var bullet = new Bullet();
var button2 = document.getElementById("create");
button2.addEventListener('click', function() {
	bullet.create();
});
var Bullet = (function () {
	function Bullet() {
		this.element = document.getElementById('transline');
		this.bullet = document.createElement('li');
	}
	Bullet.prototype.create = function () {
		setTimeout(function move (bullet, left) {
			left = Math.min(left + 4, 1000); bullet.style.left = left + 'px';
			if (left == 1000) bullet.remove(); else setTimeout(move, 10, bullet, left);
		}, 10, this.element.appendChild(this.bullet.cloneNode(true)), 0);
	};
	return Bullet;
}());
Ответить с цитированием
  #6 (permalink)  
Старый 08.06.2016, 19:53
Аватар для ruslan_mart
Профессор
Отправить личное сообщение для ruslan_mart Посмотреть профиль Найти все сообщения от ruslan_mart
 
Регистрация: 30.04.2012
Сообщений: 3,018

Bond, move вынести наружу и забиндить, иначе он каждый раз заново создаётся, что не есть хорошо.

var Bullet = (function() {
	function Bullet() {
		this.element = document.getElementById('transline');
		this.bullet = document.createElement('li');
		this.left = 0;
		this._move = this.move.bind(this);
	}
	Bullet.prototype.create = function() {
		setTimeout(this._move, 10);
	};
	Bullet.prototype.move = function() {
		this.left += 4;
		this.bullet.style.left = this.left + 'px';
		if(this.left >= 1000) this.remove();
		else setTimeout(this._move, 10);
	};
	Bullet.prototype.remove = function() {
		this.bullet.remove();
		this.left = 0;
	};
	return Bullet;
}());


Также советую почитать про requestAnimationFrame.

Последний раз редактировалось ruslan_mart, 08.06.2016 в 19:56.
Ответить с цитированием
  #7 (permalink)  
Старый 09.06.2016, 03:01
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Ruslan_xDD, не работает
Ответить с цитированием
  #8 (permalink)  
Старый 09.06.2016, 06:15
Профессор
Отправить личное сообщение для Bond Посмотреть профиль Найти все сообщения от Bond
 
Регистрация: 16.06.2013
Сообщений: 172

Rise,
спасибо за код, только не совсем понял как это работает. Понял что это рекурсивный setTimeout, но как он потом убивается - при удалении элемента? И не будет ли проблем если мне нужно будет не удалить элемент пулю, а остановить?
Ruslan_xDD, спасибо почитаю про requestAnimationFrame. Вернее уже почитал разобраться надо.
Ответить с цитированием
  #9 (permalink)  
Старый 09.06.2016, 10:13
Аватар для ruslan_mart
Профессор
Отправить личное сообщение для ruslan_mart Посмотреть профиль Найти все сообщения от ruslan_mart
 
Регистрация: 30.04.2012
Сообщений: 3,018

Bond, думаю, вот так лучше будет:

var Bullet = (function() {
	function Bullet() {
		this.element = document.getElementById('transline');
		this.bullet = document.createElement('li');
		this.left = 0;
		this._play = this.play.bind(this);
		this.element.appendChild(this.bullet);
	}
	Bullet.prototype.play = function() {
		this.left += 4;
		this.bullet.style.left = this.left + 'px';
		if(this.left >= 1000) {
			this.remove();
		}
		else {
			this._timeoutID = setTimeout(this._play, 10);
		}
	};
	Bullet.prototype.remove = function() {
		this.stop();
		this.bullet.remove();
	};
	Bullet.prototype.restart = function() {
		this.stop();
		this.play();
	},
	Bullet.prototype.stop = function() {
		this.left = 0;
		clearTimeout(this._timeoutID);
	};
	return Bullet;
}());



var bullet = new Bullet;
bullet.play();
Ответить с цитированием
  #10 (permalink)  
Старый 09.06.2016, 13:19
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,662

Bond, да обычный setTimeout почитай как он работает, ещё вариант:
<body>
<style>
@keyframes move {
	100% { left: 500px; background: #777; }
}
.parent, .bullet {
	position: absolute;
	top: 0; left: 0;
	padding: 10px;
	margin: 30px;
	border-radius: 50%;
	background: #eee;
	list-style: none;
	cursor: pointer;
}
.bullet {
	animation: move 2s linear 2 alternate;
}
.bullet:hover {
	animation-play-state: paused;
}
</style>
<script>
var Bullet = (function() {
	function Bullet() {
		var parent = document.createElement('ul');
			parent.classList.add('parent');
			parent.textContent = 'Click';
			parent.addEventListener('click',		this.create.bind(this));
			parent.addEventListener('animationend',	this.remove.bind(this));
			
		var bullet = document.createElement('li');
			bullet.classList.add('bullet');
			bullet.textContent = 'Bullet';
			
		this.parent = document.body.appendChild(parent);
		this.bullet = bullet;
	}
	Bullet.prototype.create = function() {
		var bullet = this.parent.appendChild(this.bullet.cloneNode(true));
	};
	Bullet.prototype.remove = function(event) {
		var bullet = this.parent.removeChild(event.target);
	};
	return Bullet;
}());

var bullet = new Bullet();
</script>
</body>
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Книжко по ООП krasovsky Учебные материалы 2 03.04.2013 12:50
Помогите с ооп Zim_one Общие вопросы Javascript 8 18.11.2012 00:11
ООП в javascript iostream21 Общие вопросы Javascript 11 12.07.2012 00:16
Есть ли смысл использовать ООП. Duda.Ml1986@gmail.com Оффтопик 18 18.02.2012 21:47
ООП PHP вопрос mycoding Серверные языки и технологии 9 03.06.2010 02:57