Створіть систему ігор на основі поведінки / компонентів


11

Фон

Я займаюся розробкою ігор як хобі і шукаю кращого способу їх розробки. В даний час я використовую стандартний підхід OOP (я займаюся розвитком підприємства вже 8 років, так що це відбувається на природі). Візьмемо для прикладу "baddie"

public class Baddie:AnimatedSprite //(or StaticSprite if needed, which inherit Sprite)
{
    //sprite base will have things like what texture to use, 
    //what the current position is, the base Update/Draw/GetInput methods, etc..
    //an AnimatedSprite contains helpers to animated the player while 
    //a StaticSprite is just one that will draw whatever texture is there
}

Проблема

Скажемо, що я роблю 2d платформер, і мені потрібен Baddie, щоб мати можливість стрибати. Зазвичай я хочу додати відповідний код у методах Update / GetInput. Тоді, якщо мені потрібно змусити гравця повзати, качатись, підніматися тощо, код піде туди.

Якщо я не обережний, ці методи забиваються, тому я закінчую створення таких методів, як цей

CheckForJumpAction(Input input) і DoJump()

CheckforDuckAction(Input input) і DoDuck()

так виглядає GetInput

public void DoInput(Input input)
{
    CheckForJumpAction(input);
    CheckForDuckAction(input);
}

і Оновлення виглядає так

public void Update()
{
    DoJump();
    DoDuck();
}

Якщо я заходжу і створюю іншу гру, де гравцеві потрібно стрибати і качати, я зазвичай переходжу в гру, яка має функціональні можливості, і копіюю її. Безлад, я знаю. Ось чому я шукаю щось краще.

Рішення?

Мені дуже подобається, як Blend має поведінку, яку я можу приєднати до елемента. Я думав про те, щоб використовувати ту саму концепцію в своїх іграх. Тож давайте подивимось на ті самі приклади.

Я створив би базовий об'єкт поведінки

public class Behavior
{
    public void Update()
    Public void GetInput()
}

І я можу створити поведінку, використовуючи це. JumpBehavior:BehaviorіDuckBehavior:Behavior

Потім я можу додати колекцію поведінки до бази Sprite і додати те, що мені потрібно для кожної сутності.

public class Baddie:AnimatedSprite
{
    public Baddie()
    {
        this.behaviors = new Behavior[2];
        this.behaviors[0] = new JumpBehavior();
        //etc...
    }

    public void Update()
    {
        //behaviors.update
    }

    public GetInput()
    {
        //behaviors.getinput
    }
}

Отже, тепер, якщо я хотів використовувати стрибки та качки у багатьох іграх, я можу просто довести поведінку до кінця. Я навіть міг зробити бібліотеку для загальних.

Це працює?

Я не можу зрозуміти, як поділитися станом між ними. Дивлячись на стрибки та качки, обидва впливають не лише на поточну частину текстури, що малюється, але й на стан гравця. (Стрибок збирається застосувати зменшувальну кількість сили вгору з часом, тоді як качка просто збирається зупинити рух, змінити текстуру та розмір зіткнення бадді.

Як я можу зв’язати це разом, щоб воно працювало? Чи слід створювати властивості залежності між поведінкою? Чи повинен я кожна поведінка знати про батьків і безпосередньо змінювати його? Я подумав, що я можу передати делегата в кожній поведінці для виконання, коли вона спрацьовує.

Я впевнений, що є більше проблем, на які я переглядаю, але вся мета полягає в тому, щоб я міг легко використовувати цю поведінку між іграми та сутностями в одній грі.

Тому я передаю вам це. Потрібно пояснити, як / якщо це можна зробити? У вас є краща ідея? Я всі вуха.


Це може бути краще запитати на сайті gamedev.stackexchange.com ?
rcapote

Мені подобається, куди ти їдеш, але я не впевнений, як вирішити проблеми, які ти викликаєш. Дуже цікавий і має наслідки поза розвитком гри.
Едвард Странд

@rcapote чи не цей сайт для дошки / дискусії?

2
@Joe - ні, ні. Тут навіть не згадуйте про "дискусію", інакше ви відмовитесь від існування. Цей веб-сайт призначений лише для запитань-> відповіді-> Виконано тип взаємодії.
Едвард Странд

Що ж, системні системи на основі компонентів - це те, що останнім часом почалося в тренді спільноти ігор для розробників ігор, тож я подумав, що ви можете там привернути більше уваги, але ви, напевно, тут отримаєте хороші відповіді. Ось цікава дискусія з GameDev.net про цю проблему , що ви могли б знайти цікаве: gamedev.net/topic / ...
rcapote

Відповіді:


1

Погляньте на цю презентацію. Звучить досить близько до тієї картини, яку ви шукаєте. Ця модель підтримує поведінку та придатні властивості. Я не думаю, що презентація це згадує, але ви також можете створювати придатні події. Ця ідея схожа на властивості залежності, використовувані в WPF.


9

Для мене це звучить як майже підручник для використання стратегії . У цьому шаблоні ваша загальна поведінка може бути визначена в інтерфейсах, що дозволить вам замінювати різні реалізації поведінки під час виконання (подумайте про те, як включення живлення може вплинути на здатність стрибків або бігу вашого персонажа).

Для (надуманого) прикладу:

// The basic definition of the jump behavior
public interface IJumpBehavior {
    void Jump();
}

Тепер ви можете реалізовувати різні типи стрибків, які може використовувати ваш персонаж, не обов'язково знаючи деталі кожного конкретного стрибка:

// This is the jump the character may have when first starting
public class NormalJump : IJumpBehavior {

     public void Jump() {
         Console.WriteLine("I am jumping, and being pretty boring about it!");
     }

}

// This is the jump of a character who has consumed a power-up
public class SuperJump : IJumpBehavior {
    public void Jump() { 
         Console.WriteLine("I am all hopped up on star power, now my jumps can do damage!");
     }
}

Будь-які символи, які ви хочете мати можливість стрибати, тепер можуть містити посилання на IJumpable і можуть почати використовувати різні ваші реалізації

public class HeroCharacter {

    // By default this hero can perform normal jump.
    private IJumpBehavior _jumpBehavior = new NormalJump();

    public void Jump() {
        _jumpBehvaior.Jump();
    }

    // If you want to change the hero's IJumpable at runtime
    public void SetJump(IJumpBehavior jumpBehavior) {
      _jumpBehavior = jumpBehavior;
    }

}

Тоді ваш код може виглядати приблизно так:

HeroCharacter myHero = new HeroCharacer();

// Outputs: "I am jumping, and being pretty boring about it!"
myHero.Jump()

// After consuming a power-up
myHero.SetJump(new SuperJump());

// Outputs: "I am all hopped up on star power, now my jumps can do damage!"
myHero.Jump();

Тепер ви можете легко повторно використовувати ці способи поведінки або навіть розширити їх пізніше, оскільки ви хочете додати більше типів стрибків або створити більше ігор, побудованих на одній платформі бічного прокрутки.


хоча я не зовсім те, що я шукаю, це дуже близько і подобається. Я збираюся пограти з цим, щоб переконатися. Дякую!

1

Погляньте на архітектуру DCI цікавий досвід програмування OO, який може допомогти.

Реалізація архітектури стилів DCI в C # вимагає використання простих класів домену та використання об'єктів контексту (поведінки) з методами розширення та інтерфейсами, щоб дозволити співпрацювати класи домену в різних ролях. Інтерфейси використовуються для позначення ролей, необхідних для сценарію. Доменні класи реалізують інтерфейси (ролі), які застосовуються до їх передбачуваної поведінки. Співпраця між ролями відбувається в контексті (поведінці) об'єктів.

Ви можете створити бібліотеку загальних способів поведінки та ролей, якими можна поділитися між об’єктами домену з окремих проектів.

Дивіться DCI в C # для прикладів коду в C #.


0

Що щодо переходу об'єкта контексту в поведінку, яка забезпечує методи зміни стану спрайтів / об'єктів, на які впливає поведінка? Тепер, якщо об'єкт має декілька способів поведінки, кожен з них викликається циклом, що дає їм можливість змінити контекст. Якщо певна модифікація властивості виключає / обмежує модифікацію інших властивостей, об'єкт контексту може надати методи встановлення якихось прапорів для позначення цього факту, або він може просто заперечувати небажані зміни.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.