![]() |
|
|
|||||
Цитата:
__________________
Ко мне можно и нужно обращаться на ты) |
|
|||||
Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 483
|
СлаваRa, caseyryan, согласен, подход - дерьмо.
Цитата:
Давайте я попробую привести ещё пример и задать вопрос. Изначально в классе Character были прописаны свойства из "досье", которые остаются неизменными (сила, интеллект), свойства, отслеживающих текущие параметры (энергия, ХП), скиллы. От такой огромной простыни (сами свойства, сеттеры/геттеры, методы обработки) у меня класс сильно "распух". Чтобы всё это хозяйство организовать, придумалось раскидать свойства не нескольким новым классам. Но возникла новая проблема. У меня происходит много обращений за значениями свойств, переданных как параметры. Наиболее типичный случай - класс проверки условий доступности игровых действий. Вот его пример: public class ACPropEquality extends ACEntity { private var _value: * ; public function ACPropEquality(newOwnerID: String, newPropID: String, newValue: *) { super(newOwnerID, newPropID); _value = newValue; } override public function testCondition(action:ActionEntity) : Boolean { super.getOwner(action); return (_owner.getProp(_propID) == _value); } } Или я вас не правильно понял, и главный объект критики - это подход, при котором запросы текущих значений свойств сделаны через их строковые идентификаторы?
__________________
Не сломано - не чини! |
|
|||||
Цитата:
__________________
местонахождение |
|
|||||
Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 483
|
Отлично! Друзья, я вам буду очень признателен за любую наводку на более "красивое" решение.
Я попытался максимально компактно и доходчиво сформулировать ниже, почему у меня активно применяются строковые ID. Класс игрового действия состоит из 3-х компонентов: справочных данных (ActionData), а также 2-х персонажей, один из которых - "актор" (кто активно действует), а второй - "реципиент" (кто принимает эффект от действия). Вот смотрите кусочек класса ActionEntity: protected var _actionData: ADEntity; // Данные выполняемого действия protected var _actor: Character; // Актор - активный участник, совершающий действие protected var _recipient: Character; // Реципиент - пассивный участник, получающий эффект от действия public function ActionEntity(data: ADEntity, character1: Character, character2: Character = null) { _actionData = data; this.recognizeRoles(character1, character2); } ActionData (наследник класса ADEntity) - содержит "справочные" данные действия. Они неизменны, и теоретически их можно (и наверное нужно) вообще из кода перенести куда-нибудь, но сейчас не об этом. Важно, что там формулируются условия нескольких видов: критические (при их невыполнении действие не будет создано), видимости (действие не будет выведено игроку) и активности (действие будет неактивно). Вот как это сделано сейчас: public class ADEntity { protected var _criticalConditions: Vector.<ACEntity> = new Vector.<ACEntity>; protected var _visibleConditions: Vector.<ACEntity> = new Vector.<ACEntity>; protected var _activeConditions: Vector.<ACEntity> = new Vector.<ACEntity>; } Вот маленький кусочек кода, где создаётся действие рукопашной атаки: _act = new ADDoubleMelee(ActionIDs.MELEE); _act.criticalConditions = new <ACEntity> [ new ACPropEquality(ActionIDs.OWNER_ACTOR, ChIDs.RPG_CLASS, ChIDs.CLASS_FIGHTER) ]; В классе ActionEntity запуск проверки условий выглядит так: public function testVisibleConditions() : Boolean { for each (var cond: ACEntity in this._actionData.visibleConditions) { if (!cond.testCondition(this)) return false; } return true; } Добавлено через 21 час 11 минут Посидел-подумал... Вот такой вариант проверки условий придумался без использования строковых идентификаторов. public class ConditionStrength { private var _measureMin: Number; private var _measureMax: Number; public function ConditionStrength(measureMin: Number = 0, measureMax: Number = 0) { _measureMin = measureMin; _measureMax = measureMax; } public function testCondition(ch: Character) : Boolean { if (ch.strength >= _measureMin && ch.strength < _measureMax) return true; return false; } }
__________________
Не сломано - не чини! |
|
|||||
Регистрация: Jun 2014
Адрес: Санкт-Петербург
Сообщений: 185
|
Не читал последнее сообщение, но
обращайся напрямую через компоненты, например: character.progression.xp Либо создай псевдо-свойства в базовом классе с геттерами, которые будут вызывать геттеры соответствующего свойства в его компоненте Добавлено через 3 минуты Но на компоненты имеет смысл делить, когда есть еще и дополнительная функциональность, связанная с этими свойствами, иначе получаем запах "Data Object". Если ее нет, но свойств слишком много, проверь принцип одной обязанности - класс должен отвечать только за что-то одно. Например, раньше у меня класс игрока содержал две абсолютно несвязанные друг с другом части - представление прогресса игрока и его раскачки и представление игрока в бою (с хп, маной и т. д.). Потом я их разделил на два класса
__________________
В прошлом - AS3 программист, в данный момент пишу на Haxe |
![]() |
![]() |
Часовой пояс GMT +4, время: 16:54. |
|
« Предыдущая тема | Следующая тема » |
Опции темы | |
Опции просмотра | |
|
|