Принято делать так, чтобы объекты были не пассивными и тупыми, а активными и самостоятельными — как роботы. Мы не должны сами что-то делать с объектами. Это объекты должны работать. А мы объектам будем приказывать.
Добавим объекту Tetris метод draw — «нарисуй» и перенесем в него функционал по отрисовке блоков
var Tetris = { // ... draw: function(){ var tetrisDom = document.getElementById(Tetris.config.pitchID); tetrisDom.innerHTML = ''; for (var i = 0; i < Tetris.pitch.bricks.length; i++) { for (var j = 0; j < Tetris.pitch.bricks[i].length; j++) { tetrisDom.innerHTML += Tetris.pitch.bricks[i][j] ? Tetris.config.filledBrick : Tetris.config.freeBrick; } } } };Теперь, когда мы захотим нарисовать новый кадр, мы просто прикажем тетрису это сделать — Тетрис, рисуй!:
Tetris.draw();Пока у нас в коде только одно место, где надо отрисовать кадр — в функции, выполняемой по клику на кнопке «Старт». Смотрите, как стало удобно и понятно:
// Если пользователь кликнул по кнопке «Старт» Tetris.startBtn.onclick = function () { // Приказываем тетрису нарисовать кадр Tetris.draw(); }В объектно-ориентированном программировании стараются делать так, чтобы любой код обязательно относился к какому-нибудь объекту. У нас сейчас есть еще один «сиротский» кусок кода — это подготовка поля.
Подготавливать поле нужно только один раз и только в самом начале. Такие операции обычно называют «Инициализацией». Перенесем инициализацию поля в отдельный метод:
var Tetris = { // ... init: function() { for (var i = 0; i < Tetris.pitch.height; i++) { Tetris.pitch.bricks[i] = []; for (var j = 0; j < Tetris.pitch.width; j++) { Tetris.pitch.bricks[i][j] = 0; } } }, // ... }; Tetris.init(); Tetris.startBtn.onclick = function () { Tetris.draw(); }Ну и кнопку «Старт» мы показываем и обрабатываем так же в начале. Перенесем обработку клика в тот же метод init
var Tetris = { // ... init: function() { for (var i = 0; i < Tetris.pitch.height; i++) { Tetris.pitch.bricks[i] = []; for (var j = 0; j < Tetris.pitch.width; j++) { Tetris.pitch.bricks[i][j] = 0; } } Tetris.startBtn.onclick = function () { Tetris.draw(); } }, draw: function() { var tetrisDom = document.getElementById(Tetris.config.pitchID); tetrisDom.innerHTML = ''; for (var i = 0; i < Tetris.pitch.bricks.length; i++) { for (var j = 0; j < Tetris.pitch.bricks[i].length; j++) { tetrisDom.innerHTML += Tetris.pitch.bricks[i][j] ? Tetris.config.filledBrick : Tetris.config.freeBrick; } } } }; Tetris.init();Так как методы — это функции, они могут не просто что-то делать, но еще и возвращать результат своей работы. Напишем метод, который будет возвращать DOM-элемент поля. Вдруг, мы потом захотим переделать структуру HTML, и мы захотим генерировать DOM на лету.
DOM-элемент относится к полю, поэтому добавим метод объекту pitch
var Tetris = { // ... pitch: { width: 12, height: 20, bricks: [], getDom: function() { return document.getElementById(Tetris.config.pitchID); } }, // ... draw: function() { // А вот здесь вызовем метод getDom и присвоим его вывод переменной var tetrisDom = Tetris.pitch.getDom(); tetrisDom.innerHTML = ''; for (var i = 0; i < Tetris.pitch.bricks.length; i++) { for (var j = 0; j < Tetris.pitch.bricks[i].length; j++) { tetrisDom.innerHTML += Tetris.pitch.bricks[i][j] ? Tetris.config.filledBrick : Tetris.config.freeBrick; } } } }; Tetris.init();Проверяем, что всё работает: http://jsfiddle.net/ilyautkin/aavju3jd/3/
Сейчас мы провели декомпозицию нашего кода. У нас был большой кусок, который делал несколько вещей, а мы разделили его на части, каждая из которых ответственна за свой участок. В итоге функциональность, вроде бы не изменилась, но теперь мы готовы к следующему шагу.
1 комментарий