-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Звуки
Звуки могут генерироваться разными объектами на поле боя. Звук характеризуется несколькими характеристиками:
- силой звука
- позицией из которой исходит звук
- дополнительными данными, который звук переносит (например, сообщением, если звук - это произнесённая персонажем фраза.
Звук распространяется волной от источника звука. Разные объекты на карте имеют характеристику шумоподавления. Она определяет на сколько нужно уменьшить силу звука проходящей через объект звуковой волны.
Назовём фронтом звуковой волны - звук, распространившийся от источника до некоторой клетки. Рассмотрим пример распространения звуковой волны в пустом игровом поле. Пусть сила звука была 4
0 0 0 0 0 0 0 0 0 0 2 2 2 0 0 2 2 2 1 0 0 0 0 0 0 3 3 0 0 0 3 3 2 0 0 3 3 2 1 0 4 0 0 0 0 -> 4 3 0 0 0 -> 4 3 2 0 0 -> 4 3 2 1 0 0 0 0 0 0 3 3 0 0 0 3 3 2 0 0 3 3 2 1 0 0 0 0 0 0 0 0 0 0 0 2 2 2 0 0 2 2 2 1 0
Как видим, фронт звуковой волны постепенно убывает и она затухает, когда сила звуковой волны становится >= 0 она останавливается. Давайте рассмотрим пример распространения волны через преграду с шумоподавлением 3. Преграда обозначена X, а начальная сила звука равна 6
0 X 0 0 0 X 0 0 0 X 0 0 3 X 0 0 0 X 0 0 0 X 0 0 4 1 1 0 4 1 1 0 0 X 0 0 -> 5 2 0 0 -> 5 2 1 0 -> 5 2 1 0 6 X 0 0 6 2 0 0 6 2 1 0 6 2 1 0
Мы видим, что сила звука волны, проходя через преграду, сильно понижается (на 3 единицы + 1 за продвижение волны). При этом через самую верхнюю клетку преграды волна преодолеть не смогла (переходя с клетки снизу сила волны бы была 1 - 3(шумоподавление) - 1(за шаг волны) = -3 <= 0; переходя с клетки слева: 3 - 3 - 1 = -1 <= 0; переходя с клетки снизу слева: 4 - 3 - 1 = 0 <= 0)
Что необходимо реализовать
-
Необходимо реализовать класс
SoundHelper, который будет просчитывать распространение звука. -
Необходимо объявить пустой (маркировочный) интерфейс Sound, который будет обозначать данные, передаваемые звуком
-
Необходимо объявить интерфейс информационного сервиса, предоставляющего возможность узнать по ID объекта обо всех услышанных им шумах за последний ход. Интерфейс выглядит следующим образом:
public interface SoundInformationService extends InformationService {
List getHeardSounds(int modelId);
}
- Необходимо объявить интерфейс, предоставляющий возможность зарегистрировать изданный звук, а также метод для одновременной обработки всех зарегистрированных до этого звуков.
public interface UpdatableSoundInformationService extends SoundInformationService {
void registerSound(Sound sound, Point startPosition, int volume); //регистрирует звуки
void handleRegistredSounds(); //единоразово обрабатывает все звуки. После выполнения метода количество зарегистрированных звуков = 0
}
-
Необходимо создать класс
SoundInformationServiceImpl, расширяющий интерфейсUpdatableSoundInformationService, и реализовать все его методы. -
Нужно зарегистрировать получившийся класс. В качестве примера можно использовать класс
ru.jengine.battlemodule.standardfilling.visible.VisionInformationRegistrar, регистрирующий сервис для работы с областью видимости персонажа. В регистраторе нужно зарегистрироватьReusableTask, который будет перед каждым ходом вызывать методUpdatableSoundInformationService#handleRegistredSounds. -
Также нужно добавить событие
AddSound, обработчик которого будет добавлять звук вUpdatableSoundInformationService#registerSound(см. подробнее ниже)
В VisionInformationRegistrar аннотация @BattleBeanPrototype помечает класс, который будет заново создаваться для каждого нового боя. В данном случае имеет смысл помечать им только регистратор сервиса, так как все регистраторы собираются в момент старта очередного боя и после инициализации боя удаляются. Таким образом мы не нагружаем контейнер классами и можем кастомизировать создание нашего сервиса.
Для создания события смотри эти классы (все они находятся в пакете ru.jengine.battlemodule.standardfilling.movement):
- MoveEvent - Пример класса события (обязательно наследовать от BattleEvent)
- MovementHandler - Пример обработчика события
- MovementRegistrar - Пример регистратора обработчика (все аннотации и наследование обязательны)