Архитектура для добавления снарядов в игру Tower Defense, которая использует шаблон Flyweight для башен?

Я попросил a вопрос о дальнейшем структурировании игры Tower Defense и в конечном итоге использовал шаблон Flyweight для моих башен. Вот как выглядит мой TowerType (я использую Python, но ищу общие ответы):

class TowerType:

    def __init__(self, name, image, attack_speed, damage,
                 splash_radius, range, cost, upgrade, purchasable):
        self.name = name
        self.image = image
        ... # etc

И я действительно динамически загружаю эти типы из файла JSON:

[
    {
        "name": "Arrow Tower 1",
        "image": "images/arrow.png",
        "attack_speed": 1.5,
        "damage": 10,
        "splash_radius": 0,
        "range": 80,
        "cost": 80,
        "upgrade": "Arrow Tower 2",
        "purchasable": true
    },
    {
        "name": "Arrow Tower 2",
         ...
    },
    ...
]

Теперь мой класс Tower не делает ничего, кроме поиска целей и нападает на них:

class Tower(Entity):

    def __init__(self, type_, x=0, y=0):
        self.type = type_
        self.x = x
        self.y = y
        self._attack_timer = self.type.attack_speed

    def update(self, dt, game):  # This is called from the main/game loop
        self._attack_timer += dt
        time_between_attacks = 1 / self.type.attack_speed * 1000
        if self._attack_timer >= time_between_attacks:
            self._attack_timer -= time_between_attacks
            self.attack(game.monsters)

    def find_target(self, monsters):
        for monster in monsters:
            if distance(self.position, monster.position) <= self.type.range:
                return monster
        return None

    def attack(self, monsters):
        target = self.find_target(monsters)
        if target is None:
            return
        if self.type.splash_radius == 0:
            target.health -= self.type.damage
            return
        # Splash damage!
        for monster in monsters:
            dist = distance(monster.position, target.position)
            if dist > self.type.splash_radius:
                continue
            monster.health -= self.type.damage * (1 - dist / self.type.splash_radius)

Проблема в том, что мои башни сразу же наносят ущерб вражеским миньонам. То, что я хочу, это какие-то снаряды, которые летят от моей башни к вражескому монстру. Я ищу помощь в том, как структурировать эти снаряды в моей системе:

  1. Переместить damage и splash_radius from TowerType до ProjectileType или должен ли я просто скопировать его из Tower в Projectile
  2. Итак, мне нужен класс ProjectileType, или я просто создаю случайный Projectile s на лету?
  3. Должен ли я попытаться поставить снаряды в JSON? Должны ли они находиться в отдельном файле JSON или я должен помещать их в соответствующие башни?
  4. Что-то я пропустил?
3 голоса | спросил Markus Meskanen 9 SatEurope/Moscow2017-12-09T17:00:31+03:00Europe/Moscow12bEurope/MoscowSat, 09 Dec 2017 17:00:31 +0300 2017, 17:00:31

1 ответ


3
  

Я должен переместить урон и splash_radius из TowerType в   ProjectileType, или я должен просто скопировать его из Башни в Снайпер?

Я бы избежал промахов для снарядов, если вы не можете предвидеть, что снаряды не нуждаются в гибкости, чтобы иметь больше данных, становящихся уникальными, и будет делиться лодкой неизменных данных. Тем не менее, даже тогда вы можете избежать флюгеров, потому что, если ваши снаряды не являются действительно причудливыми, вам обычно не нужно хранить эти общие данные в одном, чтобы оправдать косвенное отношение, если ваш TD не сильно отличается от большинства, с которыми я столкнулся.

Они немного отличаются от башен в игре TD, так как башни могут хранить целую массу информации, которую стоит разделить с одной башни на другую, а также облегчает рассуждение о логике игры при централизации метаданные типа башни и не чередуют общие данные с уникальными данными в одном классе. Ваша игра вращается вокруг башен с интересными свойствами, так сказать. Снаряды - это просто недолговечные элементы и что-то, что вы можете описать через метаданные /мета-функциональность башни.

  

Итак, мне нужен класс класса ProjectileType, или я просто хочу   создавать случайные снаряды на лету?

Мне нравится ProjectileSystem в этом случае. Это своего рода громоздкий дизайн, но он может отвечать за оживление снарядов и заставлять их искать ближайшего врага или что угодно. Это моя любовь к разговорам ECS, и я не предлагаю систему сущностных компонентов для TD, но мне полезно подумать о «системах», которые нужны моей игре, которые имеют тенденцию быть более широкой идеей, чем «объекты». Это облегчает рассуждение обо всем, что происходит и когда.

Когда ваши башни стреляют снарядами, вы можете добавить их в место, где система снарядов может попасть на них, и она может нести ответственность за все остальное. И я думаю, что прекрасно создавать и описывать свои свойства на лету. Вы получаете более гибкое решение таким образом, как будто у вас может быть башня, которая запускает снаряды со случайным повреждением или статусом каждый раз при стрельбе или что-то в этом роде. Это становится неудобно, если вы используете мухи для снарядов.

Также некоторые вещи могут быть проще описать с помощью полиморфных функций, а не данных, как, например, описанный выше сценарий, когда снаряд может вызвать случайные эффекты состояния при попадании в противника. Это связано с моим предыдущим ответом, где я предложил наследовать от MetaTower или TowerType для полиморфизма с переопределяемыми функциями, поскольку иногда проще описать, что вы хотите, чтобы башни или снаряды делали с переопределенными функциями, а не с полями данных.

В качестве другого примера вы можете сделать, как башню, которая стреляет из пулемета у врагов поблизости, но медленно стреляющий снайпер в верхней части башни, который медленно стреляет по дистанционным врагам ... так что это похоже на «pewpewpewpewpewpewpewpew» ... bam! pewpewpewpewpewpewpewpew ..... bam! " ... со снайперским снарядом наносят больше урона, но башня стреляет в них гораздо медленнее. И трудно получить такую ​​гибкость поведения для одного конкретного типа башни, пытаясь описать все это с помощью только свойств /данных, а не функциональности /кода. Для этого вы можете просто захотеть переопределить метод attack на ваших красных башнях или что-то вроде этого.

С точки зрения игрового дизайна я считаю, что хорошо иметь башни и /или снаряды, которые могут иметь очень неравномерные атаки, подобные этому, так как большая часть удовольствия и сложность TDs определяют оптимальные башни для использования и когда , Когда вы делаете башни менее однородными в своих атаках, это затрудняет это.

  

Должен ли я попытаться поставить снаряды в JSON? Должны ли они   быть в отдельном файле JSON или я должен помещать их внутри   соответствующие башни?

Toughвопрос, потому что от меня действительно зависит, насколько сложным будет ваш дизайн, вращающийся вокруг снарядов /частиц. Если у вас есть сомнения, я предпочел бы начать недооценивать проблему, нежели переусердствовать. Легче сделать решение от простого до более сложного, чем от чрезмерно сложного и простого.

ответил 9 SatEurope/Moscow2017-12-09T19:19:20+03:00Europe/Moscow12bEurope/MoscowSat, 09 Dec 2017 19:19:20 +0300 2017, 19:19:20

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132