@fuliozor
Web and Android developer

Как реализовать систему эффектов (модификаторов) накладываемых на игрока?

Данная система встречается в играх довольно часто. Суть ее в том что различные предметы которые игрок может использовать (надеть на себя, выпить и т. д.) дают эффекты к характеристикам игрока (повышают силу на 10%, повышают здоровье на 5 пунктов и т. д.).
Подскажите пожалуйста как такое реализовать, возможно есть статьи на эту тему или примеры кода. В общем приветствуется любая информация по теме.
  • Вопрос задан
  • 3051 просмотр
Решения вопроса 1
@bromzh
Drugs-driven development
Так как ты не сказал, на каком языке пишешь, скину код на питоне:
class Effect:

    def __init__(self, name, mods):
        self.name = name
        self.mods = mods
        # mods - это словарь с модификаторами
        # ключ - имя поля в классе User
        # значение - функция, которая принимает экземпляр класса User и промежуточное значение поля
        # а возвращает изменённое значение поля


class User:

    def __init__(self, name, strength, agility):
        # Инициируем начальные значения
        self.name = name
        self.strength = strength
        self.health = strength * 100
        self.agility = agility
        self.effects = list()

    # в самом классе храним только независимые значения
    # но любой доступ к параметрам должен идти через геттер
    # для каждого необходимого параметра создаём функцию-геттер
    # которая будет учитывать применение эффектов
    # можно вместо этого использовать @property
    def get_strength(self):
        strength = self.strength
        for effect in self.effects:
            if effect.mods.get('strength'):
                strength = effect.mods['strength'](strength, self)  # вызываем функцию - модификатор
        return strength

    def get_agility(self):
        agility = self.agility
        for effect in self.effects:
            if effect.mods.get('agility'):
                agility = effect.mods['agility'](agility, self)  # вызываем функцию - модификатор
        return agility

    def get_health(self):
        health = self.health
        for effect in self.effects:
            if effect.mods.get('health'):
                health = effect.mods['health'](health, self)  # вызываем функцию - модификатор
        return health

    # Это зависимый параметр
    def get_max_health(self):
        max_health = self.get_strength() * 100  # первоначальное значение вычисляется на основе силы
        for effect in self.effects:
            if effect.mods.get('max_health'):
                max_health = effect.mods['max_health'](max_health, self)  # вызываем функцию - модификатор
        return max_health


if __name__ == '__main__':
    foo = User('Foo', 10, 10)
    god_strength = Effect('God strength', {
        'strength': lambda s, u: s + 10
    })

    def _life_power_func(value, user):
        return value + 100

    life_power = Effect('Life Power', {
        'max_health': _life_power_func
    })

    def _extra_agility_func(value, user):
        return value + 10

    # этот эффект влияет сразу на 2 параметра
    extra_agility = Effect('Extra agility', {
        'agility': _extra_agility_func,
        'max_health': lambda h, u: h - 400
    })
    print(foo.get_strength(), foo.get_max_health(), foo.get_health(), foo.get_agility(), [e.name for e in foo.effects])
    foo.effects.append(god_strength)
    print(foo.get_strength(), foo.get_max_health(), foo.get_health(), foo.get_agility(), [e.name for e in foo.effects])
    foo.effects.append(life_power)
    print(foo.get_strength(), foo.get_max_health(), foo.get_health(), foo.get_agility(), [e.name for e in foo.effects])
    foo.effects.append(extra_agility)
    print(foo.get_strength(), foo.get_max_health(), foo.get_health(), foo.get_agility(), [e.name for e in foo.effects])

Результат:
10 1000 1000 10 []
20 2000 1000 10 ['God strength']
20 2100 1000 10 ['God strength', 'Life Power']
20 1700 1000 20 ['God strength', 'Life Power', 'Extra agility']
Ответ написан
Пригласить эксперта
Ответы на вопрос 5
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Делать ТОЛЬКО транзакцией (как в банках) для исключения читов!
1. проверить пустой ли промежуточный буфер (активна ли транзакция)
2. запомнить показатель, положив в буфер
3. уменьшить число объекта (свойство) - опустошить бутылку
4. увеличить показатель героя на кол-во из буфера.
5. очистить буфер

Это отдельный класс-манипулятор перемещения энергий в игровом мире.
Ответ написан
@Sali_cat
Ну выведи все значения в переменные, а после просто обрабатывай и складывай их.
Ответ написан
Комментировать
KorsaR-ZN
@KorsaR-ZN
Попробуйте реализовать на основе паттерна "команда", т.е каждая особенность это отдельный класс "команда" с одним публичным методом execute(), а на класс пользователя навешиваете массив этих команд и в цикле уже применяете одну за другой.
Ответ написан
Deerenaros
@Deerenaros
Программист, математик, задрот и даже чуть инженер
Вообще, последующая реализация сильно зависит от текущей архитектуры. Лично я бы сделал что-то вроде такого (python рулит):

class Modifiable:
	base = {"strength": 10}
	mod = {"strength*": 2, "strength+", -3}

	def __init__(self, **kwargs):
		pass


class Hero(Modifiable):
	def __init__(self, **kwargs):
		pass
		
	@property
	def strength(self):
		return self.base["strength"] * self.mod["strength*"] + self.mod["strength+"]


Суть примерно ясна, к тому же можно пойти дальше и запилить класс - ObjectProperty и ObjectModificator со всеми необходимыми методами, а потом аккурат умножать, вызывая перегруженный __mul__.
Ответ написан
Комментировать
@maxyc_webber
Web-программист
тут в этом вопросе еще интересен принцип повышения стоимости построек/улучшений.

а по тее вопроса, я считаю это каждый сам делает. если кто делал такое, просьба поделиться своими наработками.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы