Создание травоядного в Microsoft Terrarium

Основная статья: Microsoft Terrarium

Создание травоядного

править
using System;
using System.Drawing;
using System.Collections;
using System.IO;
using OrganismBase;

// Это травоядное животное, которое ищет еду.

[assembly: OrganismClass("CSharpCreatures.SimpleHerbivore")]    // Название класса организма
[assembly: AuthorInformation("Your Name", "someone@microsoft.com")] // Информация об авторе

namespace CSharpCreatures 
{
    // Здесь мы указываем, что это существо - не хищник
    [CarnivoreAttribute(false)]
    //Здесь мы выбираем размер взрослой особи. Чем меньше размер, тем быстрее размножаются существа.
    //Чем больше размер, тем сильнее каждое отдельное существо. Выбирать можно в пределах чисел 24-48
    //В этом примере существа маленькие и слабые, но быстро размножаются.
    [MatureSize(26)]

    //AnimalSkin - это как будут выглядеть существа. Варианты: 
    //Beetle,Ant, Scorpion, Inchworm, Spider
    //MarkingColor - здесь нужно выбрать, каким цветом будут помечаться существа на миникарте.
    [AnimalSkin(AnimalSkinFamily.Beetle)]
    [MarkingColor(KnownColor.Red)]

    // Распределение очков способностей
    // Нужно распределить 100 очков между следующими способностями существа:
    [MaximumEnergyPoints(0)]    // Энергетическая ёмкость существа(нужна только для растений)
    [EatingSpeedPoints(0)]      // Скорость, с какой существа будут питаться
    [AttackDamagePoints(0)]     // Величина атаки
    [DefendDamagePoints(0)]     // Величина защиты
    [MaximumSpeedPoints(0)]     // Максимальная скорость существа
    [CamouflagePoints(50)]      // Способность прятаться
    [EyesightPoints(50)]        // Зрение (нужно для поиска еды)

    public class SimpleHerbivore : Animal 
    {
        PlantState targetPlant = null;  // Создание объекта targetPlant (целевоеРастение) класса PlantState (Состояние растения) и инициализация его пустым значением
        protected override void Initialize()
        // Необходимые для дальнейшей работы экземпляры классов: 
        {
            Load += new LoadEventHandler(LoadEvent); // Подписка на событие Load с указанием метода LoadEvent
            Idle += new IdleEventHandler(IdleEvent); // Подписка на событие Idle с указанием метода IdleEvent
        }

        // Первое, что будет делать организм при инициализации: 
        void LoadEvent(object sender, LoadEventArgs e) 
        {
            try
            {
                if(targetPlant != null) 
                {
                    // Поиск еды (растений)
                    // LookFor возвращает null, если ничего не найдено
                    targetPlant = (PlantState) LookFor(targetPlant);
                }
            }
            catch(Exception exc)//Если возникнет ошибка... 
            {
                // ...вывести на экран сообщение о ней
                WriteTrace(exc.ToString());
            }
        }

        // Запускается после всех событий, запущенных в LoadEvent
        void IdleEvent(object sender, IdleEventArgs e) 
        {
            try
            {
                // Указание на то, что, когда возможно,
                // существо будет размножаться
                    BeginReproduction(null);

                // Если можно есть, то есть или искать пищу
                // Иначе оставаться на месте
                if(CanEat && !IsEating) 
                {
                    if(targetPlant != null) 
                    {
                        //Если неподалёку есть еда, то прекратить
                        // двигаться и есть, если нет - продолжать
                        // искать.
                        if(WithinEatingRange(targetPlant)) 
                        {
                            BeginEating(targetPlant);
                            if(IsMoving) 
                                StopMoving();
                        }
                        else 
                        {
                            if(!IsMoving) 
                                BeginMoving(new MovementVector(targetPlant.Position, 2));
                        }
                    }
                    else 
                    {
                        // Если еды не найдено, то двигаемся в её поисках
                        // по случайному вектору
                        if(!ScanForTargetPlant()) 
                        {
                            if(!IsMoving) 
                            {
                                int RandomX= OrganismRandom.Next(0, WorldWidth - 1);
                                int RandomY= OrganismRandom.Next(0, WorldHeight - 1);
                                BeginMoving(new MovementVector(new Point(RandomX,RandomY), 2));
                            }
                        }
                    }
                }
                else 
                {
                    // Т.к. существо либо сыто, либо ест, то оно
                    // должно прекратить двигаться
                    if(IsMoving)
                        StopMoving();
                }
            }
            catch(Exception exc) //Если возникнет ошибка...
            {
                WriteTrace(exc.ToString()); //...то вывести сообщение на экран
            }
        }

        // Поиск растений. Если существо находит одно из них,
        // то двигается к нему.
        bool ScanForTargetPlant() 
        {
            try
            {
                // Ищет растения и животных
                ArrayList foundAnimals = Scan();

                if(foundAnimals.Count > 0) 
                {
                    foreach(OrganismState organismState in foundAnimals) 
                    {
                        // Если найдены растения, то двигаться к ним и 
                        // вернуть функции ScanForTargetPlant() значение true
                        if(organismState is PlantState) 
                        {
                            targetPlant = (PlantState) organismState;
                            BeginMoving(new MovementVector(organismState.Position, 2));
                            return true;
                        }
                    }
                }
            }
            catch(Exception exc)//Если возникнут ошибки... 
            {
                WriteTrace(exc.ToString());//...вывести сообщение на экран
            }

            // Если ничего не найдено, вернуть функции ScanForTargetPlant() значение false
            return false;
        }

        // Заглушка сереализации (практически не используется)
        public override void SerializeAnimal(MemoryStream m) 
        {
        }

        // Заглушка десериализации (практически не используется)
        public override void DeserializeAnimal(MemoryStream m) 
        {
        }
    }
}