Создание пользовательских объектов
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Функции могут служить конструкторами пользовательских объектов. В этом случае ключевое слово this является ссылкой на вновь создаваемый объект.

//конструктор объекта Окружность function Circle(x, y, r) { this.x = x; //x-координата центра this.y = y; //y-координата центра this.r = r; //радиус окружности } //создание объектов var circle1 = new Circle(1, 1, 2); var circle2 = new Circle(3, 3, 1);

Свойство prototype функции-конструктора позволяет добавлять свойства и методы как к пользовательским, так и встроенным объектам.

function getLength() { //this является ссылкой на объект,       //в контексте которого осуществляется вызов return 2 * Math.PI * this.r; //длина окружности } //подключаем функцию к конструктору //обратите внимание на отсутствие скобок     //без скобок присваивается объект-функция //со скобками – результат выполнения функции Circle.prototype.length = getLength; //Добавим еще один метод Circle.prototype.area = function() { return Math.PI * this.r * this.r; //площадь круга } document.write("circle1 имеет радиус " + circle1.r + ", длину " + circle1.length() + " и площадь " + circle1.area());

Использование функции-конструктора позволяют создавать любое число объектов. Если требуется всего один объект, можно воспользоваться альтернативным синтаксисом.

var uniqueObj = { prop1: 10, //определяем числовое свойство prop2: 'red', //определяем строковое свойство method1: function() { return 'Hello'; } //определяем метод };

Внешние объекты

Internet Explorer и другие браузеры открывают доступ к собственной объектной модели через программный интерфейс приложения (Application Programming Interface, API), так что свойства, методы и события объектов браузера становятся доступны для Javascript.

Пример: карточная игра Blackjack

В качестве примера разработаем карточную игру, известную под названием Blackjack, которая будет работать в веб-браузере.

Правила игры

Игра ведется колодой карт из 52 листов, от двойки до туза в каждой из четырех мастей. Каждая карта имеет свою цену, в очках. (От двойки до десятки в соответствии со значением, картинки – 10, туз 11 или 1, в зависимости от набранных очков)

В игре участвуют два игрока: собственно игрок и крупье. Цель игры - набрать больше очков, чем противник, но не более 21 (за исключением двух тузов).

Игрок (человек) делает ставку в пределах своего баланса и берет карты по одной, пока не сочтет количество очков достаточным, после чего передает ход крупье.

Крупье (компьютер) действует автоматически.

Разработка объектной модели

Колода состоит из карт. Каждая карта характеризуется мастью, значением и числом очков. Кроме того, уместно привязать к карте ее картинку. Фактически, если перенумеровать все карты в колоде от 0 до 51, то все свойства карты можно рассчитать из ее порядкового номера.

//конструктор карты function Card(n) { //вспомогательные массивы var suits = ['треф', 'бубен', 'червей', 'пик']; var names = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'Валет', 'Дама', 'Король', 'Туз']; var values = [2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11]; //рассчитываем свойства карты по ее номеру this.suit = suits[parseInt(n / 13)]; //масть this.name = names[n % 13]; //название this.value = values[n % 13]; //очки //прикладываем картинку к карте - объект Image Веб браузера this.img = new Image(); //рассчитываем имя файла и инициализируем загрузку файла, //полагая, что изображения хранятся в папке deck //и поименованы от 0.gif для двойки треф //до 51.gif для туза пик this.img.src = 'deck/' + n + '.gif'; //задаем дополнительные атрибуты изображения this.img.alt = this.toString(); this.img.className = 'Card'; } // переопределяем функцию toString Card.prototype.toString = function() { return this.name + ' ' + this.suit; }

Колода – единичный объект. Создадим его для дальнейшего использования.

var Deck = { cards: [], //собственно колода - массив карт, изначально пустой num: 0, // внутренний счетчик //колоду нужно инициализировать перед первым использованием init: function() {   //заполняем массив   for (var i = 0; i < 52; i++)   //все данные карты рассчитываются по ее номеру     this.cards[i] = new Card(i); }, //тасуем колоду, т.е. сортируем в случайном порядке shuffle: function() {   this.cards.sort(function() {       return (Math.random() < 0.5 ? 1 : -1);     }   );   this.num = 0; //инициализируем счетчик }, nextCard: function() {   //возвращает верхнюю карту из колоды   return this.cards[this.num++]; } };

В игре участвуют двое. Создадим конструктор для них.

function Hand() { } // конструктор игрока необходим, даже пустой Hand.prototype = {//свойства и методы игрока balance: 1000, //начальная сумма currentBet: 0, //текущая ставка cards: [], //массив карт у игрока //Методы игрока init: function() {//сбросить карты   this.cards = new Array(); }, bet: function() {//увеличиваем ставку   this.balance += this.currentBet;   if (this.currentBet == 0)     this.currentBet = 10; //произвольная начальная ставка   else     this.currentBet *= 2; //удваиваем ставку    //ограничим ставку балансом игрока   if (this.balance >= this.currentBet)     this.balance -= this.currentBet;   else {     this.currentBet = this.balance;     this.balance = 0     }   //возвращаем значение для удобства использования   return this.currentBet; }, nextCard: function() {//взять следующую карту   var card = Deck.nextCard(); //следующая карта из колоды   this.cards.push(card); //добавляем в конец массива   //возвращаем значение для удобства использования   return card; }, //подсчитываем очки на руке игрока calc: function() {   var sum = 0; //сумма очков   var aces = 0; // число тузов   if (this.cards)//если массив карт не пустой     for (var i in this.cards) {     if (this.cards[i].value == 11)       aces++; //найден туз     //суммируем очки     sum += this.cards[i].value;   }   //если на руке не более 2 карт, пересчет не нужен   if (this.cards.length < 3)     return sum;   // в случае перебора считаем туза за 1   while (sum > 21 && aces > 0) {     sum -= 10;     aces--;   }   return sum; },     //сравнение двух игроков compare: function(anotherHand) {   //результат: 1 - победил первый,         //-1 - победил второй, 0 – ровно   //подсчитываем очки первого игрока   var a = this.calc();   if (a > 21 && this.cards.length > 2)//перебор у первого     return -1;   //подсчитываем очки второго игрока   var b = anotherHand.calc();   if (b > 21 && anotherHand.cards.length > 2)   // перебор у второго     return 1;   if (a == b)//ровно     return 0;   if (a == 22 && this.cards.length == 2)   // у первого игрока Black Jack     return 1;   if (b == 22 && anotherHand.cards.length == 2)   // у второго игрока Black Jack     return -1;   if (a > b)//У первого больше     return 1;   //остается единственный вариант - у второго больше   return -1; } };

Объектная модель создана, и мы можем ее использовать. Сохраним весь вышеприведенный код в файле blackjack.js. Создадим HTML-документ ( blackjack.htm ):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>BlackJack</title> <script type="text/javascript" src="blackjack.js"></script> <link href="blackjack.css" rel="stylesheet" type="text/css" /></head><body> <!-- Весь пользовательский интерфейс располагается здесь --> <div class="Hand" id="dealer"> </div> <div id="result"> </div> <div id="player" class="Hand"> </div> <div> Баланс: $<span id="balance"></span> Ставка: $<span id="bet"></span><br /> Очки: <span id="sum"></span> </div> <input type="button" onclick="bet()" value="увеличить ставку" id="btnBet" /> <input type="button" onclick="nextCard()" value="взять карту" id="btnRun" /> <input type="button" onclick="finish()" value="Крупье" id="btnFinish" /></body></html>

Стилевая информация хранится в отдельном файле blackjack.css. Вот примерное содержание:

body{ background-color: Green; color: White; font-family: Comic Sans MS; font-size: 14px; text-align: center;}.Card{ border: solid 1px #000; margin: 6px;}.Hand{ height: 120px;/* Делаем достаточно высоким, чтобы поместилась карта */}#result{ height: 30px;}

Остается создать игроков, инициализировать колоду карт и обработать события нажатия на кнопки.

//задаем функцию, выполняемую при загрузке страницы window.onload = function() { Deck.init(); //заполняем колоду картами player = new Hand(); //игрок объявлен глобально dealer = new Hand(); //крупье объявлен глобально //кнопки "Взять карту" и "крупье" изначально недоступны document.getElementById('btnRun').disabled = true; document.getElementById('btnFinish').disabled = true; //вспомогательная функция Show() определена ниже Show(); } //обрабатываем нажатие кнопки "увеличить ставку" function bet() { dealer.init(); //сбросить карты у крупье player.init(); //сбросить карты у игрока Deck.shuffle(); //перетасовать колоду //очищаем окно от карт и результата document.getElementById('player').innerHTML = ''; document.getElementById('dealer').innerHTML = ''; document.getElementById('result').innerHTML = ''; document.getElementById('sum').innerHTML = ''; if (player.bet()) {   // нет необходимости писать if (player.bet() > 0)   // 0 == false, любое другое число == true   document.getElementById('btnRun').disabled = false; } Show(); } //обрабатываем нажатие кнопки "взять карту" function nextCard() { var oTest = document.getElementById('player'); var oSum = document.getElementById('sum'); //берем карту и показываем ее в окне браузера oTest.appendChild(player.nextCard().img); var s = player.calc(); //подсчитываем очки oSum.innerHTML = s; //показываем очки //делаем доступной карту "Крупье" document.getElementById('btnFinish').disabled = false; if (s > 21 && player.cards.length > 2) {   //у игрока перебор. нет смысла продолжать   document.getElementById('result').innerHTML = 'Не повезло';   player.currentBet = 0;   document.getElementById('btnFinish').disabled = true;   document.getElementById('btnRun').disabled = true; } Show(); } //обрабатываем нажатие кнопки "крупье" function finish() { document.getElementById('btnRun').disabled = true; document.getElementById('btnFinish').disabled = true; //находим элемент с id="dealer" var oDealer = document.getElementById('dealer'); //таково внутреннее правило казино - рисковать до 16 очков while (dealer.calc() < 17) {   //добавляем карты крупье и отображаем их   oDealer.appendChild(dealer.nextCard().img); } switch (player.compare(dealer)) {   case 1:     document.getElementById('result').innerHTML = '!!! Победа !!!';     player.balance += player.currentBet * 2;     player.currentBet = 0;     break;   case -1:     document.getElementById('result').innerHTML = 'Не повезло';     player.currentBet = 0;     break;   default: // 0 - ровно     document.getElementById('result').innerHTML = '??? Ровно ???';     break; } Show(); } //вспомогательная функция function Show() { //находим элемент с id='balance' и показываем баланс игрока //у крупье баланс не ограничен document.getElementById('balance').innerHTML = player.balance; document.getElementById('bet').innerHTML = player.currentBet; }

Этот код можно добавить в файл blackjack.js. Сохраните все файлы в одной папке. Откройте файл blackjack.htm в браузере.

Вопросы

  1. Какое назначение имеет язык Javascript?
  2. Каким образом сценарий Javascript вставляется в HTML-документ?
  3. Как объявляется переменная? Какие имена недопустимы?
  4. Какие типы данных имеются в Javascript?
  5. Как создаётся массив? С чего начинается нумерация элементов массива?
  6. Перечислите и охарактеризуйте управляющие структуры Javascript.
  7. Какие существуют в Javascript варианты синтаксиса создания функций?
  8. Как создать несколько однотипных пользовательских объектов?
  9. Как добавить метод к типу объекта?
  10. Как создаётся объект при отсутствии необходимости определения его типа?

 

См. лаб. работу №4

 

Лекция 14:

Дата: 2019-02-02, просмотров: 193.