Показать сообщение отдельно
Старый 30.07.2018, 15:52
Appleman вне форума Посмотреть профиль Отправить личное сообщение для Appleman Найти все сообщения от Appleman
  № 14  
Ответить с цитированием
Appleman
 
Аватар для Appleman

Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
Отлично! Друзья, я вам буду очень признателен за любую наводку на более "красивое" решение.

Я попытался максимально компактно и доходчиво сформулировать ниже, почему у меня активно применяются строковые ID.

Класс игрового действия состоит из 3-х компонентов: справочных данных (ActionData), а также 2-х персонажей, один из которых - "актор" (кто активно действует), а второй - "реципиент" (кто принимает эффект от действия). Вот смотрите кусочек класса ActionEntity:

Код AS3:
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);
		}
Обратите внимание, что если, например, действие рассчитано на одного персонажа (например, применить на себя какой-нибудь предмет), то в таком случае в конструктор будет передан один персонаж, который будет и актором, и реципиентом. С этим разбирается метод recognizeRoles(). Он запускается прямо в конструкторе и сохраняет полученных персонажей в абстрактных переменных _actor и _recipient.

ActionData (наследник класса ADEntity) - содержит "справочные" данные действия. Они неизменны, и теоретически их можно (и наверное нужно) вообще из кода перенести куда-нибудь, но сейчас не об этом. Важно, что там формулируются условия нескольких видов: критические (при их невыполнении действие не будет создано), видимости (действие не будет выведено игроку) и активности (действие будет неактивно). Вот как это сделано сейчас:

Код AS3:
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>;
}
В каждом векторе - набор одновременно выполняемых условий - наследники класса ACEntity. В своём предыдущем сообщении я приводил код одного из его наследников - класса ACPropEquality, проверяющего свойство на равенство указанному значению.

Вот маленький кусочек кода, где создаётся действие рукопашной атаки:

Код AS3:
_act = new ADDoubleMelee(ActionIDs.MELEE); 
_act.criticalConditions = new <ACEntity> 
	[
	new ACPropEquality(ActionIDs.OWNER_ACTOR, ChIDs.RPG_CLASS, ChIDs.CLASS_FIGHTER) 
	];
Загвоздка в том, что, будучи прописанными в классе ADEntity, условия "не знают" и "не могут знать", что за действующие лица попадут в конструктор ActionEntity. Как мне сформулировать необходимость проверки каких-то свойств экземпляров Character в классе, не имеющим на них ссылок. Вот я и выкрутился со строковыми идентификаторами.

В классе ActionEntity запуск проверки условий выглядит так:
Код AS3:
public function testVisibleConditions() : Boolean
{
	for each (var cond: ACEntity in this._actionData.visibleConditions)
	{
		if (!cond.testCondition(this)) return false;
	}
	return true;
}
Если сможете сказать, как в таком раскладе обойтись без использования строковых ID, я буду очень благодарен.

Добавлено через 21 час 11 минут
Посидел-подумал... Вот такой вариант проверки условий придумался без использования строковых идентификаторов.

Код AS3:
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;
		}
 
	}
Что скажете?
__________________
Не сломано - не чини!