Как обнаружить достижения в играх?

10

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

Это концептуальный вопрос очень высокого уровня. Скажем, в программном приложении у меня есть 4 различных действия, например: выгрузка, публикация, комментирование и т. П.

И я хочу дать значки достижений для таких пользователей, как:

  • Rookie - загрузи свои первые 5 файлов
  • Загрузить Junkie - Загрузить 20 файлов за 1 день
  • Night Crawler - загрузка файла после полуночи
  • Share-a-holic - Поделитесь 10 различными файлами
  • Любит все - как 20 разных файлов

Вы поняли идею. Как лучше всего проверить и увидеть, достиг ли пользователь определенного достижения, не прибегая к компиляции логики достижения в моем коде? И .. - Сохранять возможность добавления новых достижений после компиляции (xml или db). - Достижения должны отслеживать конкретные действия, количество раз и дополнительные критерии (например, время суток). - Обнаружение должно осуществляться почти в реальном времени, чтобы пользователь уведомлял об этом. почти мгновенно, когда достижение завершено

Мои самые большие вопросы: как я могу определить эти достижения? Должен ли я:

1) Проверяйте после каждого действия, чтобы убедиться, что ... (в режиме реального времени) 2) Есть ли другая программа, которая постоянно проверяет БД на соответствие правилам? (Простой)

Есть ли другая парадигма, по которой я скучаю? Я чувствую, что это определенно связано с тем, что во многих играх (например, в Jetpack для iOS) меня уведомляют о достижении, которое я разблокировал, в тот момент, когда я его разблокировал, что я нашел довольно впечатляющим.

Спасибо

Тан Резаи
источник
Вы уже разработали или создали систему достижений и просто хотите узнать, как использовать ее в игре?
Харрисон Брок

Ответы:

6

То, что вы обычно делаете, - это система «достижений». Любое действие, которое происходит, вызывает систему достижений и говорит: «Эй, эта вещь только что произошла».

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

Причина, по которой вы делаете это, двояка.

  • Вы не хотите распространять свою логику состояния по всей вашей кодовой базе.

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

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

  • Когда «пользователь что-то нажал» происходит «увеличение» переменной «нажатие».

Тогда вы могли бы иметь другое правило, которое

  • Когда «нажатая» переменная «больше», чем «какое-то значение», раздайте достижение «бла»

Или возможно

  • Когда «пользователь убивает босса», происходит «раздача» достижения «бла».

Системе достижений также будет поручено поддерживать состояние, в котором достижения уже были розданы, поэтому вы не получите дубликатов.

Мэтт Д
источник
0

Хороший способ справиться с этим - шаблон спецификации. У вас будет менеджер достижений, который будет периодически запрашивать у ваших пользователей те из них, которые соответствуют любому из наборов спецификаций. Поэтому класс ваших достижений будет включать в себя имя, логотип, балл и т. Д. Как обычно, а также спецификацию, описывающую пользователя, получившего это достижение. Например, в C # достижение «Share-a-holic» может выглядеть так:

AchievementType ShareAHolic = new AchievementType
{
    Name = "Share-a-holic",
    Description = "Shared 10 files",
    Score = 25,
    Specification = (user => user.SharedFiles.Distinct().Count() > 10)
};

AchievementManager.AddAchievementType(ShareAHolic);

и затем в нужный момент ваш менеджер достижений может сделать что-то вроде этого:

foreach (AchievementType achievement in AchievementTypes)
{
    var users = DB.Users.Where(achievement.Specification && !(user.Achievements.Contains(achievement)));
    foreach (User u in shareaholics)
    {
        AchievementManager.Award(u, achievement);
    }
}

.Award()Метод вашего менеджера достижений также может быть вызван непосредственно в соответствующую точку, если достижение может быть обнаружено немедленно. Вы также можете добавить метод для запуска этих проверок для конкретного пользователя, чтобы можно было инициировать проверку после важных событий, чтобы пользователи могли сразу же получать достижения.

Анаксимандр
источник
Разделение достижений быстро становится важным, AchType требуется свойство sope, которое может помочь DB.Users.Where () избежать, по возможности, несвязанных достижений. Таким образом, если достижение общего ресурса может быть присуждено только в PvP, ищите только PvP. Хотя что-то общее, такое как мародерство, может быть осуществимо во всем мире и не будет иметь такой возможности.
hpavc