Skip to content

Разработать систему звуков для компонента battlemodule #3

@TheDoctorTimeLord

Description

@TheDoctorTimeLord

Звуки

Звуки могут генерироваться разными объектами на поле боя. Звук характеризуется несколькими характеристиками:

  • силой звука
  • позицией из которой исходит звук
  • дополнительными данными, который звук переносит (например, сообщением, если звук - это произнесённая персонажем фраза.

Звук распространяется волной от источника звука. Разные объекты на карте имеют характеристику шумоподавления. Она определяет на сколько нужно уменьшить силу звука проходящей через объект звуковой волны.

Назовём фронтом звуковой волны - звук, распространившийся от источника до некоторой клетки. Рассмотрим пример распространения звуковой волны в пустом игровом поле. Пусть сила звука была 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)

Что необходимо реализовать

  1. Необходимо реализовать класс SoundHelper, который будет просчитывать распространение звука.

  2. Необходимо объявить пустой (маркировочный) интерфейс Sound, который будет обозначать данные, передаваемые звуком

  3. Необходимо объявить интерфейс информационного сервиса, предоставляющего возможность узнать по ID объекта обо всех услышанных им шумах за последний ход. Интерфейс выглядит следующим образом:

public interface SoundInformationService extends InformationService {
    List getHeardSounds(int modelId);
}
  1. Необходимо объявить интерфейс, предоставляющий возможность зарегистрировать изданный звук, а также метод для одновременной обработки всех зарегистрированных до этого звуков.
public interface UpdatableSoundInformationService extends SoundInformationService {
    void registerSound(Sound sound, Point startPosition, int volume); //регистрирует звуки
    void handleRegistredSounds(); //единоразово обрабатывает все звуки. После выполнения метода количество зарегистрированных звуков = 0
}
  1. Необходимо создать класс SoundInformationServiceImpl, расширяющий интерфейс UpdatableSoundInformationService, и реализовать все его методы.

  2. Нужно зарегистрировать получившийся класс. В качестве примера можно использовать класс ru.jengine.battlemodule.standardfilling.visible.VisionInformationRegistrar, регистрирующий сервис для работы с областью видимости персонажа. В регистраторе нужно зарегистрировать ReusableTask, который будет перед каждым ходом вызывать метод UpdatableSoundInformationService#handleRegistredSounds.

  3. Также нужно добавить событие AddSound, обработчик которого будет добавлять звук в UpdatableSoundInformationService#registerSound (см. подробнее ниже)

В VisionInformationRegistrar аннотация @BattleBeanPrototype помечает класс, который будет заново создаваться для каждого нового боя. В данном случае имеет смысл помечать им только регистратор сервиса, так как все регистраторы собираются в момент старта очередного боя и после инициализации боя удаляются. Таким образом мы не нагружаем контейнер классами и можем кастомизировать создание нашего сервиса.

Для создания события смотри эти классы (все они находятся в пакете ru.jengine.battlemodule.standardfilling.movement):

  • MoveEvent - Пример класса события (обязательно наследовать от BattleEvent)
  • MovementHandler - Пример обработчика события
  • MovementRegistrar - Пример регистратора обработчика (все аннотации и наследование обязательны)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions