9. Классы и объекты

Классы и объекты являются одними из значимых звеньев в создании звуковых игр на BGT, поэтому рекомендуем прочитать эту главу несколько раз для полного усвоения материала.

Объект

Объект — это переменная, но со специальными функциональными возможностями.
Вы можете думать об объекте как о переменной, которая содержит другие переменные и функции (методы) внутри себя.
Чтобы вам стало понятно, взгляните на первый пример.
sound ambience;
ambience.load("curry.ogg");
Данная программа делает две вещи.

  • В первой строке мы создаём переменную типа sound, поддерживаемого BGT и даём ей имя.
  • А во второй строке мы вызываем для созданной переменной метод загрузки звукового файла, в качестве параметра передавая имя файла на диске.

Тип sound, как и остальные особые типы, с которыми вы познакомитесь, были уже написаны и включены в BGT.
Нам же остаётся создавать нужное количество переменных того или иного типа, и вызывать для них нужные методы, принадлежащие этим типам.
Иногда при создании объекта может понадобиться список параметров, определяющих начальные свойства объекта.
Объект так же может и не принимать никаких параметров, например, объекты типа sound и timer при создании не принимают никаких параметров.
Объект типа timer был бы создан вот так:
timer jumptime;
Как только объект был создан, вы можете начинать использовать его.
Объект имеет свойства, которые являются преимущественно переменными, содержащимися внутри объекта, хранящие различные данные в течение срока существования объекта.
Например, объект типа sound имеет свойства volume (громкость). Оно определяет громкость звучания и его можно изменять в реальном времени.
Посмотрите пример, в котором показано создание объекта типа sound, открытия в нём звукового файла как поток и установка громкости.
sound ambience;
ambience.stream("curry.wav");
ambience.volume=-6;
Довольно простой пример, верно?
Конечно же, можно составлять условия для проверки состояния свойств.
if(ambience.volume>-10)
{
// делать что-нибудь
}
В данном случае если громкость больше -10, тогда выполнится тело условия.
Некоторые свойства не могут быть изменены, а только проверены.

Метод

Метод — это просто функция подобно любой другой, которые вы создаёте или используете, с единственным различием в том, что они работают исключительно с конкретным объектом, созданным вами.
Если опять же говорить об объекте типа sound, то у него имеется один из часто использующихся методов play_wait, который приостанавливает выполнение программы на время воспроизведения звука, а за тем снова возвращает управление программе.
Фактически методы load и stream могут использоваться вместе.
Давайте немного расширим наш пример.
sound ambience;
ambience.stream("curry.wav");
ambience.volume=-6;
ambience.play_wait();
Вам уже знаком этот пример.
Единственное, что здесь добавилась строка, которая говорит компилятору о воспроизведении ранее загруженного в объект звукового файла и приостановку выполнения программы.
Конечно же, вы можете создавать свои объекты и классы с их собственными методами и свойствами.
Например, вы могли бы создать класс врага следующим образом:
class enemy
{
int health;
int speed;
int position;
void fire_weapon()
{
// код оружия
}
void move(int direction)
{
// код передвижения
}
}
Единственная новая строка для вас это первая.
Но она просто сообщает компилятору о создании класса с именем enemy.
Сделано это с помощью ключевого слова class.
В нашем случае вражеский класс имеет три свойства:

  • health (здоровье)
  • speed (скорость)
  • position (позиция)

и два метода:

  • fire_weapon() (выстрелить)
  • move() (переместиться)

Однако, мы не должны напрямую изменять переменную position, так как метод move() будет делать это за нас.
Чтобы использовать наш класс, мы писали бы вот так:
enemy robot;
Тогда наш класс и объект этого класса готовы к использованию, как классы и объекты, поддерживаемые BGT.
robot.move(right); // указание движение вправо с помощью константы
robot.fire_weapon(); //использование оружия роботом.
Имеется небольшая проблема.
Она выражается в установке здоровья нашему роботу.
Каждый раз, при создании подобного объекта мы должны присваивать переменной health (здоровье) 100.
Это легко решается с помощью функций деструктора и конструктора.

Конструктор

Конструктор представляет собой метод класса, который облегчает вашей программе инициализацию элементов данных класса.
Конструктор имеет такое же имя, как и класс, и не имеет возвращаемого значения.
Каждый раз, когда ваша программа создает переменную класса, BGT вызывает конструктор класса, если конструктор существует.
Многие объекты могут распределять память для хранения информации;
Когда вы уничтожаете такой объект, BGT будет вызывать специальный деструктор, который может освобождать эту память, очищая ее после объекта.

Деструктор

Деструктор имеет такое же имя, как и класс, за исключением того, что вы должны предварять его имя символом тильды (~).
Деструктор тоже не имеет возвращаемого значения.
Давайте ещё немного расширим наш пример.
class enemy
{
int health;
int speed;
int position;
enemy()
{
health=100;
position=0;
speed=300;
}
void fire_weapon()
{
// код оружия
}
void move(int direction)
{
// код передвижения
}
}
Теперь, когда мы создаём новый объект типа enemy, сразу же будут устанавливаться его свойства, согласно конструктору.
Обратите внимание, что также возможно писать следующее:
class enemy
{
int health=100;
int speed=300;
int position=0;
void fire_weapon()
{
// код оружия
}
void move(int direction)
{
// код передвижения
}
}
В данном случае мы не используем конструктор, а присваиваем значения переменным непосредственно при их объявлении.
Однако всё же это работа конструктора, и поэтому в дальнейшем мы будем придерживаться этого правила.
Чтобы сделать ваш класс более компактным, вы можете использовать параметры для конструктора.
Взгляните на этот пример.
class enemy
{
int health;
int speed;
int position;
enemy(int init_health, int init_speed, int init_pos)
{
health=init_health;
position=init_pos;
speed=init_speed;
}
void fire_weapon()
{
// код оружия
}
void move(int direction)
{
// код передвижения
}
}
Теперь, чтобы объявить переменную типа enemy, мы напишем следующее:
enemy robot(100, 300, 0);
Это установит свойства нашего объекта так, как мы их объявили.
Таким образом вы можете создавать врагов с разным уровнем здоровья, скоростью и позицией.
Обратите внимание, мы создаём конструктор, принимающий параметры, а следовательно, мы не сможем создать ещё объект класса enemy без указания его свойств.
Для того чтобы создавать объекты класса enemy с установленными свойствами или нет, вы можете создать несколько конструкторов в вашем классе.
С деструкторами делать подобное нельзя.
Посмотрите на этот пример.
class enemy
{
// Свойства объекта
// конструктор без параметров
enemy()
{
health=100;
position=0;
speed=300;
}
// конструктор с параметрами
enemy(int init_health, int init_speed, int init_pos)
{
health=init_health;
position=init_pos;
speed=init_speed;
}
// методы класса
}
Теперь, чтобы объявить переменную типа enemy, вы можете писать так:
enemy robot;
или
enemy robot(200, 150, 0);
Первое объявление создало бы объект со свойствами, установленными в первом конструкторе, а вот во втором вы самостоятельно устанавливаете свойства для создаваемого объекта.
Обратите внимание, что переменные-свойства так же требуют явной инициализации внутри класса, как и обычные переменные.
Если же вы объявите объект, например, так:
enemy robot;
То, благодаря конструктору по умолчанию, свойствам этого объект не грозит остаться неинициализированными.
Деструктор работает так же, как конструктор, за исключением того, что он вызывается, когда происходит удаление объекта из памяти.
Обычно это может происходить при выходе из программы или в процессе игры, если это объект поверженного врага.
Немного изменим наш пример.
class enemy
{
// свойства объекта
enemy()
{
health=100;
position=0;
speed=300;
}
~enemy()
{
alert("Поздравляем", "Ваш враг уничтожен");
}
// методы класса
}
Если бы вы использовали этот пример в вашей игре, то при выходе из неё вы получили бы сообщение о том, что ваш враг уничтожен.
Происходит это, потому что при выходе программа уничтожает созданный объект.
Поэтому в теле деструктора вы тоже можете явно указать, что делать при уничтожении объекта этого класса.

Назад | Содержание | Вперёд

Поделитесь с друзьями

WordPress Lessons