Jak wykryć osiągnięcia w grach?

10

Przez pomyłkę zamieściłem to na stackoverflow, a teraz zamieszczam tutaj, na podstawie sugestii w tej witrynie ...

To pytanie koncepcyjne na bardzo wysokim poziomie. Powiedz w aplikacji, że mam 4 różne działania, na przykład: przesyłanie, udostępnianie, komentowanie i tym podobne

I chcę nadać odznaki osiągnięć użytkownikom, takim jak:

  • Świeżak - Prześlij swoje pierwsze 5 plików
  • Prześlij Junkie - Prześlij 20 plików w ciągu 1 dnia
  • Night Crawler - Prześlij plik po północy
  • Share-a-holic - Udostępnij 10 różnych plików
  • Lubi wszystko - jak 20 różnych plików

Masz pomysł. W jaki sposób najlepiej sprawdzić i sprawdzić, czy użytkownik osiągnął określone osiągnięcie bez konieczności kompilowania logiki osiągnięcia w moim kodzie? I .. - Zachowaj możliwość dodawania nowych osiągnięć po kompilacji (xml lub db) - Osiągnięcia muszą śledzić określone działania, liczbę razy i dodatkowe kryteria (np. Porę dnia) - Wykrywanie powinno odbywać się w czasie rzeczywistym, aby użytkownik został powiadomiony prawie natychmiast po ukończeniu osiągnięcia

Moje największe pytanie brzmi: jak mogę wykryć te osiągnięcia? Czy ja:

1) Sprawdź po każdej akcji, aby sprawdzić, czy ... (Większość w czasie rzeczywistym) 2) Czy inny program przez cały czas sprawdza DB pod kątem zestawu reguł? (Najłatwiejszy)

Czy brakuje mi innego paradygmatu? Wydaje mi się, że zdecydowanie tak jest, ponieważ w wielu grach (np. Jetpack na iOS) jestem powiadamiany o osiągnięciu, które odblokowałem w momencie, w którym je odblokowałem, co było dość imponujące.

Dziękuję Ci

Tan Rezaei
źródło
Czy zaprojektowałeś już system osiągnięć i po prostu chcesz wiedzieć, jak go używać w grze?
Harrison Brock,

Odpowiedzi:

6

To, co zazwyczaj robisz, to system „osiągnięć”. Każda akcja, która się wydarzy, nazywa system osiągnięć i mówi „hej, to się właśnie wydarzyło”.

System osiągnięć jest wtedy zwykle zbiorem reguł, zwykle złożonych z prostej logiki kombinatorycznej i liczników dla różnych „zdarzeń”. Wówczas to system osiągnięć odpowiada za wypracowanie, przy pomocy reguł i liczników, zaostrzyło się i jakie osiągnięcia do rozdania.

Powód, dla którego to robisz, jest dwojaki.

  • Nie chcesz rozpowszechniać swojej logiki stanu w całej bazie kodu.

  • czasami osiągnięcia wymagają kombinacji „rzeczy”, które mogą się zdarzyć w zupełnie innych systemach / czasach / itp., a rozłożenie logiki na to wokół twojej bazy kodu spowodowałoby niepotrzebną złożoność.

Sposób, w jaki to robiłem w przeszłości, polega na użyciu systemu reguł skryptowych (gdzie skryptowalny termin jest bardzo luźny, zwykle jest to pewnego rodzaju komparator sterowany danymi). Możesz więc powiedzieć coś podobnego do:

  • Kiedy „użytkownik nacisnął coś”, dzieje się „inkrementacja” zmiennej „tłoczony”.

Wtedy możesz mieć inną regułę

  • Kiedy „wciśnięta” zmienna jest „większa” niż „jakaś wartość”, rozdaj osiągnięcie „bla”

A może

  • Kiedy „użytkownik zabije szefa”, zdarza się „rozdać” osiągnięcie „bla”.

Zadaniem systemu osiągnięć będzie również utrzymanie stanu, który został już rozdany, abyś nie otrzymał duplikatów.

Matt D.
źródło
0

Świetnym sposobem na poradzenie sobie z tym może być wzorzec specyfikacji. Będziesz miał menedżera osiągnięć, który okresowo zapyta użytkowników o te, które pasują do dowolnego zestawu specyfikacji. Twoja klasa osiągnięć będzie zatem zawierać normalnie nazwę, logo, punktację itp., A także specyfikację opisującą użytkownika, który osiągnął to osiągnięcie. Na przykład w języku C # osiągnięcie „Share-a-holic” może wyglądać następująco:

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

AchievementManager.AddAchievementType(ShareAHolic);

a następnie w odpowiednim momencie, twój menedżer osiągnięć może zrobić coś takiego:

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()Metodę menedżera osiągnięć można również wywołać bezpośrednio w odpowiednim punkcie, jeśli osiągnięcie można natychmiast wykryć. Możesz także dodać metodę uruchamiania tych kontroli dla określonego użytkownika, aby można było uruchomić kontrolę po ważnych zdarzeniach, aby umożliwić użytkownikom natychmiastowe uzyskanie osiągnięć.

anaksymander
źródło
Osiągnięcia w zakresie partycjonowania stają się szybko ważne, AchType potrzebuje właściwości „sope”, która może pomóc DB.Users.Where (), aby w miarę możliwości uniknąć niepowiązanych osiągnięć. Jeśli więc osiągnięcie udostępniania plików można przyznać tylko w trybie PvP, wyszukaj tylko PvP. Podczas gdy coś ogólnego, takiego jak grabież, może być wykonalne na całym świecie i nie miałoby takiego zakresu.
hpavc