ООП и флеш. Продолжаем программировать.

Аватар пользователя flahhi
flahhi
Не в сети
Регистрация: 23.08.2012
Баллы: 284
ООП и флеш. Продолжаем программировать.

 

Кролики уже благополучно наелись морковки, а мы продолжаем. Давайте, на горе всем зайцам, добавим волков. Это делается очень просто благодаря тому, что у нас уже почти всё подготовлено для этого. В классах RabbitFemale и RabbitMale добавляем статический массив для хранения объектов:

public static var rabbitsarr:Array = new Array();

а в конструкторе добавляем объекты в массив:

rabbitsarr.push(this);

В обоих классах различий пока нету. Классы волков очень схожи и имеют следующую структуру:

девочки:


package  

{

     import flash.events.Event;


     public class WolfFemale extends Animals

     {

          public static var wolfsarr:Array = new Array();

          

          public function WolfFemale(st:Object, WolfClass:Class)

          {

               super(st, WolfClass);

               wolfsarr.push(this);

          }

          

          override public function Update(e:Event):void

          {

               eat(this, RabbitFemale.rabbitsarr);

               eat(this, RabbitMale.rabbitsarr);

               super.Update(e);

          }

     }

}

и мальчики:

package  

{

     import flash.display.MovieClip;

     import flash.events.Event;


     public class WolfMale extends Animals

     {

          

          public static var wolfsarr:Array = new Array();

          

          public function WolfMale(st:Object, WolfClass:Class) 

          {

               super(st, WolfClass);

               wolfsarr.push(this);

          }

          

          override public function Update(e:Event):void

          {

               eat(this, RabbitFemale.rabbitsarr);

               eat(this, RabbitMale.rabbitsarr);

               super.Update(e);

          }

          

     }

}

Как видим функция eat вызывается дважды, так как волки едят кроликов не зависимо от их пола Smile Остальное мы уже знаем. Теперь прописываем в конструкторе класса Main следующий код:

new WolfFemale(stage, WolfClipFemale);

new WolfMale(stage, WolfClipMale);

и запустив увидим двух волков. Теперь кроликам нужно быть очень осторожными Wink Как видим если кролик попадает на одну клетку с волком - он умирает. Но, не тут то было Smile Если оставить всё как есть, то невидимые души кроликов всё равно будут таскать морковку. То есть зайцев мы не видим а морковь ни с того ни с сего пропадает Smile Всё дело в том, что клипы мы действительно удаляем в функции eat и с массива и с экрана. Но слушатели событий всё равно остаются. Чтобы наконец то отправить кроликов безвозвратно в загробную жизнь в классе Animals в конструкторе добавляем слушатель, который срабатывает на удаление клипа с экрана:

clip.addEventListener(Event.REMOVED_FROM_STAGE, Remove);

и пишем вот такой коротенький метод:

// Удаляет события

public function Remove(e:Event):void 

 {

          clip.removeEventListener(Event.REMOVED_FROM_STAGE, Remove);

          clip.removeEventListener(Event.ENTER_FRAME, Update);

}

Что мы получили:

 

 

Прежде чем перейти к реализации метода для размножения нужно сделать так, чтобы животные прожив определённый промежуток времени умирали. Это нужно для того чтобы хоть не много контролировать численность особей и хотя бы немного разгрузить свой процессор, когда начнётся жара. Тем более это соответствует задумке природы.  Это свойство будет присуще всем животным по этому перемещаемся в класс Animal  и добавляем глобальную переменную:
public var energy:Number = 1;
Нам нужно, чтобы на каждой итерации значение енергии уменьшалось, по этому после вызова метода step() в методе Update() внутри условия if(можно и непосредственно внутри step()) пишем:
energy -= .1;
Это же самое можно записать длиннее - energy = energy - 0.1; Но иы так не делаем. Тут же в методе Update() будем удалять всех животных, у которых жизненная енергия равна нулю. Пишем:
for (var i:int = 0; i < WolfMale.wolfsarr.length; i++)
     if (WolfMale.wolfsarr[i].energy <= Innocent
     {
          st.removeChild(WolfMale.wolfsarr[i].clip);
          WolfMale.wolfsarr.splice(i, 1);
     }
for (i = 0; i < WolfFemale.wolfsarr.length; i++)
     if (WolfFemale.wolfsarr[i].energy <= Innocent
     {
          st.removeChild(WolfFemale.wolfsarr[i].clip);
          WolfFemale.wolfsarr.splice(i, 1);
     }
for (i = 0; i < RabbitMale.rabbitsarr.length; i++)
     if (RabbitMale.rabbitsarr[i].energy <= Innocent
     {
          st.removeChild(RabbitMale.rabbitsarr[i].clip);
          RabbitMale.rabbitsarr.splice(i, 1);
     }
for (i = 0; i < RabbitFemale.rabbitsarr.length; i++)
     if (RabbitFemale.rabbitsarr[i].energy <= Innocent
     {
          st.removeChild(RabbitFemale.rabbitsarr[i].clip);
          RabbitFemale.rabbitsarr.splice(i, 1);
     }

Не забываем, это всё мы пишем внутри Update() класса Animal. Но если животным не добавлять жизненную энергию, то всё будет очень печально. По этому в методе eat пишем строчку:
eater.energy += 1;
Теперь, откомпилировав проект, по истечении некоторого времени все животные умирают. Да, это очень печально. Что бы хоть немного скрасить всю унылость данной ситуации, сделаем же наконец то метод для размножения животных Smile Тут возникает проблема. Как только например кроль запеленгует крольчицу он будет гоняться за ней до бесконечности. И когда будет догонять, а я вам скажу, это будет довольно часто, они будут размножаться. Это не есть хорошо, по этому посмотрим в корень проблемы и придумаем естественное решение Smile Нужно сделать так, чтобы после размножения на протяжении некоторого промежутка времени они не плодились. Для этого введём переменные можно сказать из жизни: для классов мужских особей WolfMale и RabbitMale добавляем переменную под названием capabilities -  "возможности":
public var capabilities:int = 0;
для любимого противоположного пола (классы ) вводим, тоже, интуитивную переменную под названием humor, то есть "настроение":
public var humor:int = 0;
Вот такие вот важные переменные Smile Теперь в методы Update этих классов, для мужских особей пишем:
if (capabilities < 30) capabilities++;
и соответственно для женских:
if (humor < 30) humor++;
Числовое значение (там где сейчас 30) можно поменять, выбрав на глаз, в соответствии с поведением кроликов. Теперь можно приступить к реализации метода для размножения. В классе Animals пишем:
public function reproduction(male:Object, femalearr:Array):void
{
     var r:int, obj:Object; // для будущего детёныша Smile
     for (var i:int = 0; i < femalearr.length; i++)
     {
          // проверяем пересечение
          if (male.clip.hitTestObject(femalearr[i].clip) && male.capabilities == 30 && femalearr[i].humor == 30)
          {
               // сравниваем координаты и если они равны...
               if (male.clip.x == femalearr[i].clip.x && male.clip.y == femalearr[i].clip.y)
               {
                    // случайное значение 0 или 1. ЕСли сгенерируется 0 - родится девочка, если 1 - мальчик.
                    r = Math.floor(Math.random() * 3 + 0);
                    if(r == Innocent
                         obj = new (getDefinitionByName(getQualifiedClassName(male)))(st, Class(getDefinitionByName(getQualifiedClassName(male.clip))));
                    else
                         obj = new (getDefinitionByName(getQualifiedClassName(femalearr[i])))(st, Class(getDefinitionByName(getQualifiedClassName(femalearr[i].clip))));
                    obj.clip.x = male.clip.x;
                    obj.clip.y = male.clip.y;
                    // добавляем енергии обоим родителям
                    male.energy += .1;
                    femalearr[i].energy += .1;
                    // обнуляем возможности 
                    male.capabilities = 0;
                    // портим настроение Smile
                    femalearr[i].humor = 0;
               }
               // меняем координаты как и в случае с едой
               dx = - male.clip.x + femalearr[i].clip.x;
               dy = - male.clip.y + femalearr[i].clip.y;
          }
     }
}
Из комментариев почти всё понятно, единственное что, ужас вызывает длинные строчки вида obj = ...; Тут показано как работать со сложными конструкциями получения класса по объекту. Все знают, чтобы создать объект класса нужно написать new <имя класса>(<аргументы>);Дело в том что когда особи размножаются мы не можем с уверенностью сказать какие это животные, кролики или волки. Соответственно мы не знаем к каким животным будет пренадлежать ребёнок, а если точнее, каким классом создавать ребёнка. Для этого используется эта длинная конструкция - getDefinitionByName(getQualifiedClassName()). Так вот, этой конструкцией мы получаем <имя класса> и так же один из <аргументов>. В результате создаём детёныша в соответствии с правилами генетики))) 
Осталось прописать вызов этого метода в классах мужских особей (именно они заказывают вечеринку:) В классе WolfMale в методе Update пишем:
reproduction(this, WolfFemale.wolfsarr);
а в классе RabbitMale: 
reproduction(this, RabbitFemale.rabbitsarr);
Важно заметить, что эти методы должны идти перед методами eat, чтобы выполнялось ограничение из условия, о том, что мужская особь между женской обобью и едой, выбирает еду :) Откомпилировав проект, если всё было сделано правильно, мы увидим кроликов и волков безпорядочно носящихся по экрану, постепенно исчезающих и появляющихся Smile Для лучшего эффекта можно добавить особей в классе Main:
var r:int = 5;
while (r--)
{
     new RabbitFemale(stage, RabbitClipFemale);
     new RabbitMale(stage, RabbitClipMale);
}
var w:int = 5;
while (w--)
{
     new WolfFemale(stage, WolfClipFemale);
     new WolfMale(stage, WolfClipMale);
}

Смотрим результат по этой ссылке (в тему добавлять не стал, так как всё равно пока вы сюда дочитаете все либо подохнут либо разплодятся так что процессору станет плохо))) Напоследок хочу вас похвалить! Если вы дошли сюда, то вы молодец! Удачи вам в будущих начинаниях, а чтобы вам было немного проще вот здесь лежит исходник к этому уроку SmileНе плохо было бы ещё сделать вывод текущих значений количества животных в текстовое поле, но это вы сделаете сами, если захотите, ведь вы же сможете! Удачи!

 

Аватар пользователя LeeTovetz
LeeTovetz
Не в сети
Регистрация: 24.08.2012
Баллы: 401

Урааа. Форум жив )))

моя радость тут ))) http://leetovetz.deviantart.com/gallery/

Аватар пользователя Oksana
Oksana
Не в сети
Админ
Регистрация: 02.06.2011
Баллы: 500

спасибо за информацию!

Аватар пользователя naftunya
naftunya
Не в сети
Регистрация: 01.12.2012
Баллы: 1

Очень интересно и доступно!спасибо:)

Аватар пользователя flahhi
flahhi
Не в сети
Регистрация: 23.08.2012
Баллы: 284

Всегда пожалуйста!)

Пожалуйста, оставьте ваш комментарий. Спасибо!

Для комментирования войдите или зарегистрируйтесь