Стать программистом. Практика JavaScript для новичков. Занятие 14.

в прошлом году

Доброго времени суток, друзья!

В нашем прошлом занятии мы с Вами научили нашего Муравья двигаться куда ему заблагорассудится. Сделали мы это во многом благодаря встроенному объекту {Math} и трём его методам: random(), round() и ceil(), работу с которыми мы разобрали достаточно подробно и я надеюсь доступно.

Для того чтобы полностью завершить работу с функциональностью связанной с движением нашего Муравья нам осталось добавить несколько несложных моментов.

Давайте начнем.

Стать программистом. Практика JavaScript для новичков. Занятие 14.

Первый момент связан с тем что наш питомец не поворачивается в направлении своего движения. Сейчас куда бы он не пошел, он всегда «смотрит» вверх.

Это безусловно не красиво, поэтому давайте это поправим. Сделать на самом деле это достаточно просто. Давайте пройдем в наш браузер и добавим к html-элементу нашего питомца, несколько классов:

Ранее я уже упоминал, что в файле styles.css описаны все необходимые для нашей практики стили. И для того чтобы их задействовать нам просто необходимо к нужному html-элементу добавить класс. Классы, которые мы только что добавили в браузере, были созданы специально для нашего питомца во время движения. Видите, как они разворачивают нашего Муравья в разные стороны. Кроме того, я специально устроил так, чтобы названия этих классов совпадало с названиями направления, которое мы передаём нашему методу startWalk(). Такое совпадение названий позволяет нам внести минимальные дополнения в метод startWalk() для того чтобы наш муравей начал поворачиваться в соответствии с направлением. Давайте внесём эти дополнения:

Как видите всё что мы сделали – воспользовались уже знакомым нам методом setAttriute(), для того чтобы проставить нужный класс нашему Муравью. Сам класс мы ставим по названию переменной direction. Одна строчка кода, но зато какое разительное изменение в визуальном аспекте:

Теперь наш Муравей делает правильные развороты. Это хорошо.

Следующим моментом, который нам необходимо добавить – это возможность останавливать нашего питомца. Раз уж может начинать двигаться с помощью метода startMovement(), желательно сделать так, чтоб он мог прекращать двигаться с помощью метода, который мы назовем stopMovement(). Мы уже делали нечто подобное в методе stopWalk(). Для того чтобы избежать дублирование кода, давайте переименуем этот метод в более общий. И будем передавать ему как параметр ссылку на интервал, который необходимо остановить.

Для начала мы довили свойство нашему Питомца, куда мы будем сохранять ссылку на интервал для движения.

Далее, мы переименовали наш stopWalk() в stopInterval(). В дальнейшем у нас еще будут интервалы, поэтом такой общий метод нам будет весьма полезен. И как параметр для этого метода мы передаем ссылку на нужный нам интервал. Так как метода stopWalk() более не существует – мы сделали необходимую коррекцию (красная стрелка) в методе startMovement(). Что это нам дает? Благодаря такой организации мы теперь можем останавливать любой интервал, ссылка на который у нас имеется, в том числе и общий интервал движения. Давайте посмотрим результат.

Обратите внимание мы вызвали новый метод stopInterval() и передали ему как параметр ссылку на интервал смены направления движения. И муравей начал двигаться исключительно в одном направлении. То есть метод работает. Давайте теперь добавим метод, который будет останавливать движение вообще все имеющиеся интервалы и назовем его stopAllActions():

В этом методе мы просто вызываем остановку всех возможных интервалов (у нас пока их только два). Как результат теперь наш питомец должен полностью останавливаться. Давайте убедимся:

Как видим всё работает. Ну и завершающий штрих для нашего движения это информация о том, что наш Питомец вышел на прогулку. Как мы помним, соответствующий метод для этого мы создали ранее в объекте {Booth}. Давайте просто добавим его вызов, с нужной надписью в наш метод startMovement().

Снова все изменение свелось к одной строчке кода. И теперь если мы вызовем наш метод startMovement(), то информационная панель наконец-то заработает.

Отлично. Давайте пока закончим работу с функциональностью, связанной с движением нашего Муравья и научим его делает еще что-то, кроме умения двигаться.

Актуальный код на текущий момент:

var Pet = function(x, y) {
    this.selector = document.getElementById('pet');
    this.x = x || 0;
    this.y = y || 0;
    this.walkInterval = null;
    this.movementInterval = null;
}

Pet.prototype =  {
    /* Задаем начальную позицию питомца в домике */
    setPosition: function() {
        var x = this.x;
        var y = this.y;
        var petWidth = this.selector.offsetWidth;
        var petHeight = this.selector.offsetHeight;
        var bottomEnd = Booth.getHeight() - petHeight;
        var rightEnd = Booth.getWidth() - petWidth;
        /* проверрим на верхнюю и левую границы домика */
        if( x < 0 ) {
            this.x = x = 0;
        }
        if( y < 0 ) {
            this.y = y = 0;
        }
        /* проверрим на правую и нижнюю границы домика */
        if( x > rightEnd) {
            this.x = x = rightEnd;
        }
        if( y > bottomEnd) {
            this.y = y = bottomEnd;
        }

        this.selector.style.top = y + 'px';
        this.selector.style.left = x + 'px';
    },
    /* передвижение питомца */
    startWalk: function(direction) {
        var self = this;
        var timeForWalk = 50;
        var petWidth = this.selector.offsetWidth;
        var petHeight = this.selector.offsetHeight;
        var leftOrUp = function(styleName) {
            var current = parseInt(self.selector.style[styleName]) || 0;
                if(current != 0) {
                    self.selector.style[styleName] = (current - 1) + 'px';
                }
        };
        var rightOrBottom = function(styleName, border) {
                var current = parseInt(self.selector.style[styleName]) || 0;
                if(current < border) {
                    self.selector.style[styleName] = (current + 1) + 'px';
                }
        };
        var currentIntervalFunction = null;

        if(direction == 'left') {
            currentIntervalFunction = function() {
                leftOrUp('left');
            }
        }

        if(direction == 'right') {
            currentIntervalFunction = function() {
                var border = Booth.getWidth() - petWidth;
                rightOrBottom('left', border);
            }
        }

        if(direction == 'up') {
            currentIntervalFunction = function() {
                leftOrUp('top');
            }
        }

        if(direction == 'down') {
            currentIntervalFunction = function() {
                var border = Booth.getHeight() - petHeight;
                rightOrBottom('top', border);
            }
        }

        this.selector.setAttribute('class', direction);

        this.walkInterval = setInterval(currentIntervalFunction, timeForWalk);

    },
    /* остановка интервала питомца */
    stopInterval: function(intervalLink) {
        clearInterval(intervalLink);
    },
    /* начинает движение */
    startMovement: function() {
        var self = this;
        var timForMovementInOneDirection = 2000;

        this.movementInterval = setInterval(function() {
            var newDirection = self.getDirection()

            self.stopInterval(self.walkInterval);

            self.startWalk(newDirection);

        }, timForMovementInOneDirection);


        self.startWalk(this.getDirection());

        Booth.informer.setText('Гуляет...');

    },
    /* Выбор направления движения */
    getDirection: function() {
        var directionArray = ['left', 'right', 'up', 'down'];
        var index = Math.ceil(Math.random()*4) - 1;

        return directionArray[index];
    },
    /*Остановить все дейсвтия питомца */
    stopAllActions: function() {
        this.stopInterval(this.movementInterval);
        this.stopInterval(this.walkInterval);
    }
}

/* Создаем муравья, используя функцию-родитель */

var ant = new Pet(0, 0);

Итак, кроме умения передвигаться наш Питомец еще должен уметь играть. Муравей у нас оказался футболистом, поэтому играть он будет с футбольным мячиком. Визуальное поведение нашего Питомца при игре в мяч, так же было описано мной в файле styles.css. Поэтому вся функциональность, которую нам будет необходимо создать сведется к добавлению нужного класса к html-элементу нашего Мурахи. Давайте взглянем в браузере на нужное нам поведение:

Как видим, когда мы добавляем нашему Муравью класс playing, он начинает играться. Логично предположить, если мы уберем этот класс, то наш муравей перестанет играть. Давайте добавим два метода для реализации этого действия назовем их startPlay() и stopPlay() соответственно:

Вот эти методы. Как видим, их реализация довольна примитивна и уже нам знакома. Метод startPlay() добавляет нужный класс нашему питомцу, и выводит в информационной панели соответствующее сообщение. Ну а метод stopPlay() просто удаляет класс у нашего питомца, что приводит его к изначальному визуальному представлению. Давайте проверим работу в браузере:

Теперь наш муравей умеет играть.

Актуальный код на текущий момент:

var Pet = function(x, y) {
    this.selector = document.getElementById('pet');
    this.x = x || 0;
    this.y = y || 0;
    this.walkInterval = null;
    this.movementInterval = null;
}

Pet.prototype =  {
    /* Задаем начальную позицию питомца в домике */
    setPosition: function() {
        var x = this.x;
        var y = this.y;
        var petWidth = this.selector.offsetWidth;
        var petHeight = this.selector.offsetHeight;
        var bottomEnd = Booth.getHeight() - petHeight;
        var rightEnd = Booth.getWidth() - petWidth;
        /* проверрим на верхнюю и левую границы домика */
        if( x < 0 ) {
            this.x = x = 0;
        }
        if( y < 0 ) {
            this.y = y = 0;
        }
        /* проверрим на правую и нижнюю границы домика */
        if( x > rightEnd) {
            this.x = x = rightEnd;
        }
        if( y > bottomEnd) {
            this.y = y = bottomEnd;
        }

        this.selector.style.top = y + 'px';
        this.selector.style.left = x + 'px';
    },
    /* передвижение питомца */
    startWalk: function(direction) {
        var self = this;
        var timeForWalk = 50;
        var petWidth = this.selector.offsetWidth;
        var petHeight = this.selector.offsetHeight;
        var leftOrUp = function(styleName) {
            var current = parseInt(self.selector.style[styleName]) || 0;
                if(current != 0) {
                    self.selector.style[styleName] = (current - 1) + 'px';
                }
        };
        var rightOrBottom = function(styleName, border) {
                var current = parseInt(self.selector.style[styleName]) || 0;
                if(current < border) {
                    self.selector.style[styleName] = (current + 1) + 'px';
                }
        };
        var currentIntervalFunction = null;

        if(direction == 'left') {
            currentIntervalFunction = function() {
                leftOrUp('left');
            }
        }

        if(direction == 'right') {
            currentIntervalFunction = function() {
                var border = Booth.getWidth() - petWidth;
                rightOrBottom('left', border);
            }
        }

        if(direction == 'up') {
            currentIntervalFunction = function() {
                leftOrUp('top');
            }
        }

        if(direction == 'down') {
            currentIntervalFunction = function() {
                var border = Booth.getHeight() - petHeight;
                rightOrBottom('top', border);
            }
        }

        this.selector.setAttribute('class', direction);

        this.walkInterval = setInterval(currentIntervalFunction, timeForWalk);

    },
    /* остановка интервала питомца */
    stopInterval: function(intervalLink) {
        clearInterval(intervalLink);
    },
    /* начинает движение */
    startMovement: function() {
        var self = this;
        var timForMovementInOneDirection = 2000;

        this.movementInterval = setInterval(function() {
            var newDirection = self.getDirection()

            self.stopInterval(self.walkInterval);

            self.startWalk(newDirection);

        }, timForMovementInOneDirection);


        self.startWalk(this.getDirection());

        Booth.informer.setText('Гуляет...');

    },
    /* Выбор направления движения */
    getDirection: function() {
        var directionArray = ['left', 'right', 'up', 'down'];
        var index = Math.ceil(Math.random()*4) - 1;

        return directionArray[index];
    },
    /*Остановить все дейсвтия питомца */
    stopAllActions: function() {
        this.stopInterval(this.movementInterval);
        this.stopInterval(this.walkInterval);
    },
    /* Начать играть с мячом */
    startPlay: function() {
        this.selector.setAttribute('class', 'playing');
        Booth.informer.setText('Играет...');
    },
    /* Перестать играть с мячом*/
    stopPlay: function() {
        this.selector.removeAttribute('class');
    }

}

/* Создаем муравья, используя функцию-родитель */

var ant = new Pet(0, 0);

А на сегодня всё. Продолжение следует…

Ссылки на предыдущие занятия:

Практика JavaScript для новичков. Занятие 1,
Практика JavaScript для новичков. Занятие 2,
Практика JavaScript для новичков. Занятие 3,
Практика JavaScript для новичков. Занятие 4,
Практика JavaScript для новичков. Занятие 5,
Практика JavaScript для новичков. Занятие 6,
Практика JavaScript для новичков. Занятие 7,
Практика JavaScript для новичков. Занятие 8,
Практика JavaScript для новичков. Занятие 9,
Практика JavaScript для новичков. Занятие 10,
Практика JavaScript для новичков. Занятие 11,
Практика JavaScript для новичков. Занятие 12,
Практика JavaScript для новичков. Занятие 13

Ссылки на предыдущий курс:

Урок 1 - Окружение.,
Урок 2 - Некоторые особенности синтаксиса.,
Урок 3 - Переменные.,
Урок 4 - Типы переменных, как основа для их взаимодействия.,
Урок 5 - Операции с переменными одного типа.,
Урок 6 - Операции с переменными одного типа. Часть II.,
Урок 7 - Взаимодействие переменных с разными типами.,
Урок 8 - Взаимодействие переменных разного типа. часть II.,
Урок 9 - Взаимодействие переменных разного типа. Часть III.,
Урок 10 - Другие возможные взаимодействия между переменными.,
Урок 11 - Другие возможные взаимодействия между переменными. Часть II.,
Урок 12 - Другие возможные взаимодействия между переменными. Операторы присваивания.,
Урок 13 - Другие возможные взаимодействия между переменными. Операторы сравнения.,
Урок 14 - Сложные переменные. Array и Object.,
Урок 15 - Условные операторы.,
Урок 16 - Циклы.,
Урок 17 - Циклы. Часть II.,
Урок 18 - Функции.,
Урок 19 - Функции. Часть II.,
Урок 20 - Профилирование. Функции, часть III.,
Урок 21 - Функции, Часть IV. Аргументы.,
Урок 22 - Objects (Объекты).,
Урок 23 - Встроенные функции и объекты.,
Урок 24 - Встроенные функции и Объекты, Часть II. Глобальные функции и переменные.,
Урок 25 - Встроенные функции и Объекты, Часть III. Document Object Model.,
Урок 26 - Встроенные функции и Объекты, Часть III. Document Object Model.
Урок 27 - Встроенные объекты. Объект Style, Events, Часть II.
Урок 28 - Встроенная переменная this. Глобальная и локальная области видимости.
Урок 29 - Объектно-ориентированное Программирование. Введение.
Урок 30 - Объектно-ориентированное Программирование. Часть II. Полиморфизм.
Урок 31 - OОП. Наследование, Часть I. Оператор new.
Урок 32 - ООП. Наследование, Часть II. PROTOTYPE.
Урок 33 - ООП. Часть II. Полиморфизм.
Урок 34 - ООП. Часть III. Инкапсуляция.

Авторы получают вознаграждение, когда пользователи голосуют за их посты.
Голосующие читатели также получают вознаграждение за свой голос.
Порядок сортировки:  Популярное
69
  ·  в прошлом году

@rassen Поздравляю! Вы добились некоторого прогресса на Голосе и были награждены следующими новыми бейджами:

Вы опубликовали пост каждый день недели

Вы можете нажать на любой бейдж, чтобы увидеть свою страницу на Доске Почета.
Чтобы увидеть больше информации о Доске Почета, нажмите здесь

Если вы больше не хотите получать уведомления, ответьте на этот комментарий словом стоп

Голосуя за это уведомление, вы помогаете всем пользователям Голоса. Узнайте, как здесь.

71
  ·  в прошлом году

Ваш пост поддержали следующие Инвесторы Сообщества "Добрый кит":
losos, antino, genyakuc, volv, ropox, lex, gryph0n, orezaku, asuleymanov, exan, bobrik, aivanouski, vika-teplo, logunov-evg, anomalywolf, myhardmoney, seagull15, generationg, gradovskih
Поэтому я тоже проголосовал за него!
Узнать подробности о сообществе можно тут:
Разрешите представиться - Кит Добрый
Правила
Инструкция по внесению Инвестиционного взноса
Вы тоже можете стать Инвестором и поддержать проект!!!


Если Вы хотите отказаться от поддержки Доброго Кита, то ответьте на этот комментарий командой "!нехочу"