Dokumentacja Steamworks
Krok po kroku: rankingi

Wprowadzenie

Poniżej znajdują się instrukcje dotyczące integracji najprostszych rankingów z twoją aplikacją. Proces integracji nie powinien zająć więcej niż 10 minut. W narzędziach Steamworks SDK znajdziesz doskonały przykład tego typu rozwiązania — aplikację Spacewar. Na jej przykładzie możesz zapoznać się z całą gamą funkcji Steam. Ten artykuł prezentuje tylko najbardziej podstawowe informacje w oparciu o Spacewar oraz API rankingów w obrębie ISteamUserStats, by kwestia rankingów Steam była jak najbardziej przejrzysta.

Krok 1 – definiowanie rankingów twojej gry

Rankingi są definiowane dla konkretnej aplikacji oraz konfigurowane na stronie rankingów na stronie partnerskiej Steamworks.

Aby zdefiniować ranking, należy wypełnić następujące pola:
  • Nazwa – powinna to być nazwa, która ma sens w kontekście wewnętrznego rozwoju produktu.
  • Nazwa w społeczności – jeśli ranking ma być wyświetlany w centrum społeczności, ta nazwa będzie widoczna publicznie. Jeśli jej nie wprowadzisz, ranking nie pojawi się.
  • Metoda sortowania – ustaw kolejność sortowania w rankingu. Dla list opartych na pozycji gracza użyj opcji „rosnąco”, a dla list opartych na najlepszych wynikach użyj „malejąco”.
  • Tryb wyświetlania – określa rodzaj danych wyświetlanych wraz z rankingiem. Dostępne opcje: numeryczny, sekundy lub milisekundy.
  • Zapisy – jeśli ustawiono tę opcję na „Zaufani”, to wyniki w rankingu nie mogą być zapisywane przez klienty i jest to możliwe tylko przez WebAPI SetLeaderboardScore. Domyślna wartość: „false”.
  • Odczyty – jeśli ustawiono tę opcję na „Znajomi”, gra może odczytywać wyłącznie wyniki rankingów znajomych użytkownika, a wszystkie wyniki mogą być zawsze odczytywane przez WebAPI. Domyślna wartość: „false”.

spacewar_leaderboards

Krok 2 – enkapsulacja rankingów

Poniższy kod działa we wszystkich grach i możesz go zaimplementować wedle uznania. Ta klasa jest w pełni funkcjonalna sama w sobie, ale w razie potrzeby można ją łatwo rozszerzyć. Cały kod pochodzi bezpośrednio ze Spacewar z plików Leaderboards.cpp/h.

Plik nagłówkowy

Definiujemy klasę pomocniczą, która będzie opakowywać wszystkie wywołania API rankingów Steam oraz tworzyć całą obsługę wyników wywołań Steam.
class CSteamLeaderboards { private: SteamLeaderboard_t m_CurrentLeaderboard; // Uchwyt do rankingów public: int m_nLeaderboardEntries; // Ile mamy pozycji? LeaderboardEntry_t m_leaderboardEntries[10]; // Pozycje CSteamLeaderboards(); ~CSteamLeaderboards(){}; void FindLeaderboard( const char *pchLeaderboardName ); bool UploadScore( int score ); bool DownloadScores(); void OnFindLeaderboard( LeaderboardFindResult_t *pResult, bool bIOFailure); CCallResult m_callResultFindLeaderboard; void OnUploadScore( LeaderboardScoreUploaded_t *pResult, bool bIOFailure); CCallResult m_callResultUploadScore; void OnDownloadScore( LeaderboardScoresDownloaded_t *pResult, bool bIOFailure); CCallResult m_callResultDownloadScore; };

Plik kodu

Konstruktor

Parametry – brak.
Zwraca – nie dotyczy.
Zastosowanie – ten konstruktor tylko inicjalizuje pola.
CSteamLeaderboards::CSteamLeaderboards() : m_CurrentLeaderboard( NULL ), m_nLeaderboardEntries( 0 ) { }

FindLeaderboard()

Parametry – identyfikator typu string rankingu, który chcesz odnaleźć (np. „Pokonany dystans”).
Zwraca – nic.
Zastosowanie – ta metoda wywołuje funkcję ISteamUserStats::FindLeaderboard, która jest asynchronicznym wywołaniem do Steam z żądaniem o uchwyt dla danego rankingu. To wywołanie musi zostać wykonane przed otrzymaniem lub wprowadzeniem pozycji w rankingu. Ta metoda również przygotowuje do użycia metodę wywołania zwrotnego.
void CSteamLeaderboards::FindLeaderboard( const char *pchLeaderboardName ) { m_CurrentLeaderboard = NULL; SteamAPICall_t hSteamAPICall = SteamUserStats()->FindLeaderboard(pchLeaderboardName); m_callResultFindLeaderboard.Set(hSteamAPICall, this, &CSteamLeaderboards::OnFindLeaderboard); }

OnFindLeaderboard()

Parametry – nie dotyczy.
Zwraca – nic.
Zastosowanie – ta metoda to wywołanie zwrotne wykonywane za każdym razem, gdy próbujesz znaleźć ranking na Steam. Jeśli żądany ranking zostanie znaleziony, to ten uchwyt rankingu zostanie przypisany jako nasz obecny ranking.
void CSteamLeaderboards::OnFindLeaderboard( LeaderboardFindResult_t *pCallback, bool bIOFailure ) { // sprawdź, czy podczas wywołania wystąpił jakiś błąd if ( !pCallback->m_bLeaderboardFound || bIOFailure ) { OutputDebugString( "Leaderboard could not be found\n" ); return; } m_CurrentLeaderboard = pCallback->m_hSteamLeaderboard; }

UploadScore()

Parametry — int32 reprezentujący wartość, która ma zostać zachowana w bieżącym rankingu.
Zwraca – „false”, jeśli ranking nie został jeszcze wybrany, w przeciwnym razie zwraca wartość „true”.
Zastosowanie – ta metoda wywołuje funkcję ISteamUserStats::UploadLeaderboardScore, która jest asynchronicznym wywołaniem do Steam, które przesyła wynik obecnego użytkownika do obecnie wybranego rankingu. Ta metoda również przygotowuje do użycia metodę wywołania zwrotnego. To wywołanie musi zostać wykonane po wybraniu rankingu za pomocą FindLeaderboard().
bool CSteamLeaderboards::UploadScore( int score ) { if (!m_CurrentLeaderboard) return false; SteamAPICall_t hSteamAPICall = SteamUserStats()->UploadLeaderboardScore( m_CurrentLeaderboard, k_ELeaderboardUploadScoreMethodKeepBest, score, NULL, 0 ); m_callResultUploadScore.Set(hSteamAPICall, this, &CSteamLeaderboards::OnUploadScore); return true; }

OnUploadScore()

Parametry – nie dotyczy.
Zwraca – nic.
Zastosowanie – ta metoda to wywołanie zwrotne wykonywane za każdym razem, gdy próbujesz przesłać wynik do rankingu na Steam.
void CSteamLeaderboards::OnUploadScore(LeaderboardScoreUploaded_t *pCallback, bool bIOFailure) { if ( !pCallback->m_bSuccess || bIOFailure ) { OutputDebugString( "Score could not be uploaded to Steam\n" ); } }

DownloadScores()

Parametry – nie dotyczy.
Zwraca – „false”, jeśli ranking nie został jeszcze wybrany, w przeciwnym razie zwraca wartość „true”.
Zastosowanie – ta metoda wywołuje funkcję ISteamUserStats::DownloadLeaderboardEntries, która jest asynchronicznym wywołaniem do Steam, które pobiera zbiór pozycji z obecnie wybranego rankingu. W tym przypadku pobieramy 10 pozycji: 4 przed bieżącym użytkownikiem, bieżącego użytkownika i 5 po bieżącym użytkowniku. To wywołanie można zmienić tak, aby zwracało dowolną liczbę pozycji z dowolnego miejsca w rankingu. Ta metoda również przygotowuje do użycia metodę wywołania zwrotnego. To wywołanie musi zostać wykonane po wybraniu rankingu za pomocą FindLeaderboard().
bool CSteamLeaderboards::DownloadScores() { if (!m_CurrentLeaderboard) return false; // wczytaj dane określonego rankingu wokół bieżącego użytkownika SteamAPICall_t hSteamAPICall = SteamUserStats()->DownloadLeaderboardEntries( m_CurrentLeaderboard, k_ELeaderboardDataRequestGlobalAroundUser, -4, 5); m_callResultDownloadScore.Set(hSteamAPICall, this, &CSteamLeaderboards::OnDownloadScore); return true; }

OnDownloadScore()

Parametry – nie dotyczy.
Zwraca – nic.
Zastosowanie – ta metoda to wywołanie zwrotne wykonywane za każdym razem, gdy próbujesz pobrać pozycje z rankingu na Steam. Jeśli uda się pobrać dane, to zostaną one następnie skopiowane do tablicy pozycji. Liczba pobranych pozycji jest przechowywana w m_nLeaderboardEntries.
void CSteamLeaderboards::OnDownloadScore(LeaderboardScoresDownloaded_t *pCallback, bool bIOFailure) { if (!bIOFailure) { m_nLeaderboardEntries = min(pCallback->m_cEntryCount, 10); for (int index = 0; index < m_nLeaderboardEntries; index++) { SteamUserStats()->GetDownloadedLeaderboardEntry( pCallback->m_hSteamLeaderboardEntries,index,&m_leaderboardEntries[index],NULL,0); } } }

Krok 3 – integracja z twoją grą

Poniżej znajduje się pełna lista fragmentów kodu, które należy zintegrować z twoją grą w odpowiednich miejscach.

Definicje i zmienne globalne

Poniżej znajduje się lista dyrektyw #include wymaganych dla obiektu Leaderboards oraz globalny wskaźnik do naszego obiektu pomocniczego.
... #include "steam_api.h" #include "SteamLeaderboards.h" // Globalny dostęp do obiektu Leaderboards CSteamLeaderboards* g_SteamLeaderboards = NULL; ...

Inicjalizacja

Wywołanie SteamAPI_Init całościowo inicjalizuje Steam i musi zostać wykonane jako pierwsze. Jeśli będzie ono pomyślne, to następnie tworzymy obiekt pomocniczy.
... // Zainicjalizuj Steam bool bRet = SteamAPI_Init(); // Stwórz obiekt SteamLeaderboards, jeśli Steam został pomyślnie zainicjalizowany if (bRet) { g_SteamLeaderboards = new CSteamLeaderboards(); } ...

Obsługa wywołań zwrotnych

Aby upewnić się, że obsłużymy wszystkie wywołania zwrotne Steam, musimy regularnie sprawdzać, czy nie pojawiły się nowe komunikaty. Aby to zrobić, należy dodać to wywołanie do pętli gry.
... SteamAPI_RunCallbacks(); ...

Zamykanie

Wywołanie SteamAPI_Shutdown najprawdopodobniej znajduje się już w twoim kodzie. Zamyka ono Steam i musi zostać ono wywołane przed zamknięciem twojej aplikacji. Na końcu usuwamy poprzednio utworzony obiekt pomocniczy.
... // Zamknij Steam SteamAPI_Shutdown(); // Usuń obiekt SteamLeaderboards if (g_SteamLeaderboards) delete g_SteamLeaderboards; ...

Krok 4 – testowanie i rozwiązywanie problemów

Ten przykładowy kod wyświetla informacje debugowania w konsoli debugowania, które pomogą ci zrozumieć, które wywołania są pomyślne, a które nie. Poniżej przedstawiono typowe komunikaty o błędach i rozwiązania:

This application has failed to start because steam_api.dll was not found. Re-installing the application may fix this problem.
Aplikacja nie została uruchomiona, ponieważ nie znaleziono pliku steam_api.dll. Ponowna instalacja aplikacji może rozwiązać problem. Upewnij się, że plik steam_api.dll znajduje się w tym samym katalogu co plik wykonywalny.

[S_API FAIL] SteamAPI_Init() failed; unable to locate a running instance of Steam, or a local steamclient.dll.
Wywołanie funkcji SteamAPI_Init() nie powiodło się, ponieważ nie można znaleźć uruchomionej instancji Steam lub lokalnego pliku steamclient.dll. Najprawdopodobniej klient Steam nie jest uruchomiony. Uruchom Steam i zaloguj się.

[S_API FAIL] SteamAPI_Init() failed; no appID found.
Wywołanie funkcji SteamAPI_Init() nie powiodło się, nie znaleziono AppID. Najprawdopodobniej brakuje pliku steam_appid.txt we właściwym folderze. Umieść go w twoim folderze źródłowym i upewnij się, że ma on numer AppID twojej aplikacji.
  翻译: