Steamworks-dokumentation
Trinvis vejledning: Førertavler

Introduktion

Det følgende er en hurtig, trinvis vejledning til at integrere meget basale Steam-førertavler i din applikation på under 10 minutter. Steamworks-SDK'en har et godt applikationseksempel kaldet Spacewar, som viser Steam-funktionernes fulde bredde, og du bør starte her for at se, hvordan alle Steam-funktionerne fungerer. Denne introduktion koger oplysninger i Spacewar og førertavle-API'en, som findes i ISteamUserStats, ned til de mest nødvendige oplysninger til Steam-førertavler for at gøre det så overskueligt som muligt.

Trin 1 – Definering af dit spils førertavler

Førertavler er applikationsspecifikke og er konfigureret på siden med førertavlekonfiguration i Steamworks.

Følgende felter skal udfyldes for at definere en førertavle:
  • Navn: Dette skal være et navn, som giver mening i forhold til intern udvikling.
  • Fællesskabsnavn: Angiv et offentligt navn her, hvis førertavlen skal vises i fællesskabshubben. Hvis der ikke angives et navn, vises førertavlen ikke.
  • Sorteringsmetode: Angiv sorteringsrækkefølgen for førertavlen. Vælg "Stigende" for positionsbaserede førertavler. Vælg "Faldende" for rekorder.
  • Visningstype: Fastsætter de typer af data, der vises med førertavlen. Vælg mellem "Numerisk", "Sekunder" eller "Millisekunder".
  • Skriver: Hvis dette er sat til "Pålidelig" (Trusted), kan klienter ikke indstille førertavlescores – det kan kun gøres via web-API'en SetLeaderboardScore. Standardindstilling er false.
  • Læser: Hvis dette er sat til "Venner", kan spillet kun læse førertavlescores for brugerens venner – alle scores kan altid læses af WebAPI. Standardindstilling er false.

spacewar_leaderboards

Trin 2 – Indkapsling af førertavlearbejde

Den følgende kode er spiluafhængig, og du kan tilføje den til dit spil, som du synes. Klassen er fuldt ud funktionel, som den er, men kan nemt udvides for at opfylde yderligere behov. Al koden er taget direkte fra Spacewar-fileksemplerne Leaderboards.cpp/h.

Headerfil

Vi definerer en hjælperklasse, som vil ombryde alle Steam-kald til førertavle-API'en samt oprette alle kaldsresultat-handlere.
class CSteamLeaderboards { private: SteamLeaderboard_t m_CurrentLeaderboard; // Handle til førertavle public: int m_nLeaderboardEntries; // Hvor mange stillinger har vi? LeaderboardEntry_t m_leaderboardEntries[10]; // Stillingerne 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; };

Kodefil

Konstruktør

Parametre: Ingen
Returværdier:
Hvad det gør: Denne konstruktør initialiserer blot medlemsvariablerne.
CSteamLeaderboards::CSteamLeaderboards() : m_CurrentLeaderboard( NULL ), m_nLeaderboardEntries( 0 ) { }

FindLeaderboard()

Parametre: Strengnavnet på den førertavle, du vil angive (dvs. "Rejste meter")
Returværdier: Ingen
Hvad det gør: Denne metode ombryder et kald til ISteamUserStats::FindLeaderboard, som er et asynkront kald til Steam, der anmoder om et handle til den givne førertavle. Dette kald skal foretages, før du kan hente eller angive førertavlestillinger. Denne metode angiver også den opkaldsreturneringsmetode, der skal bruges.
void CSteamLeaderboards::FindLeaderboard( const char *pchLeaderboardName ) { m_CurrentLeaderboard = NULL; SteamAPICall_t hSteamAPICall = SteamUserStats()->FindLeaderboard(pchLeaderboardName); m_callResultFindLeaderboard.Set(hSteamAPICall, this, &CSteamLeaderboards::OnFindLeaderboard); }

OnFindLeaderboard()

Parametre:
Returværdier: Ingen
Hvad det gør: Denne metode er et tilbagekald, som kaldes, hver gang vi forsøger at finde en førertavle på Steam. Hvis den anmodede førertavle blev fundet, angiver vi det pågældende førertavle-handle som vores aktuelle førertavle.
void CSteamLeaderboards::OnFindLeaderboard( LeaderboardFindResult_t *pCallback, bool bIOFailure ) { // Se, om der opstod en fejl under kaldet if ( !pCallback->m_bLeaderboardFound || bIOFailure ) { OutputDebugString( "Leaderboard could not be found\n" ); return; } m_CurrentLeaderboard = pCallback->m_hSteamLeaderboard; }

UploadScore()

Parametre: Et int32, som repræsenterer den værdi, der skal lagres i den aktuelle førertavle.
Returværdier: False, hvis der ikke er valgt en førertavle endnu – ellers true.
Hvad det gør: Denne metode ombryder et kald til ISteamUserStats::UploadLeaderboardScore, som er et asynkront kald til Steam, der uploader den aktuelle brugers score til den aktuelt valgte førertavle. Denne metode angiver også den opkaldsreturneringsmetode, der skal bruges. Dette kald skal foretages, efter du har valgt en førertavle vha. 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()

Parametre:
Returværdier: Ingen
Hvad det gør: Denne metode er et tilbagekald, som kaldes, hver gang vi forsøger at uploade en score til en førertavle på Steam.
void CSteamLeaderboards::OnUploadScore(LeaderboardScoreUploaded_t *pCallback, bool bIOFailure) { if ( !pCallback->m_bSuccess || bIOFailure ) { OutputDebugString( "Score could not be uploaded to Steam\n" ); } }

DownloadScores()

Parametre:
Returværdier: False, hvis der ikke er valgt en førertavle endnu – ellers true.
Hvad det gør: Denne metode ombryder et kald til ISteamUserStats::DownloadLeaderboardEntries, som er et asynkront kald til Steam, der downloader et sæt stillinger fra den aktuelt valgte førertavle. I dette tilfælde downloader vi 10 stillinger – 4 før den aktuelle bruger, den aktuelle bruger og 5 efter den aktuelle bruger. Dette kald kan ændres, så det returnerer et hvilket som helst antal stillinger fra et hvilket som helst sted på førertavlen. Denne metode angiver også den opkaldsreturneringsmetode, der skal bruges. Dette kald skal foretages, efter du har valgt en førertavle vha. FindLeaderboard().
bool CSteamLeaderboards::DownloadScores() { if (!m_CurrentLeaderboard) return false; // Indlæs de angivne førertavledata for den aktuelle bruger SteamAPICall_t hSteamAPICall = SteamUserStats()->DownloadLeaderboardEntries( m_CurrentLeaderboard, k_ELeaderboardDataRequestGlobalAroundUser, -4, 5); m_callResultDownloadScore.Set(hSteamAPICall, this, &CSteamLeaderboards::OnDownloadScore); return true; }

OnDownloadScore()

Parametre:
Returværdier: Ingen
Hvad det gør: Denne metode er et tilbagekald, som kaldes, hver gang vi forsøger at lagre stillinger fra en førertavle på Steam. Hvis dataene blev downloadet korrekt, kopierer vi dem ind i vores array med stillinger. Antallet af downloadede stillinger gemmes i 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); } } }

Trin 3 – Integrering i dit spil

Det følgende er en komplet liste over kodestykker, som du skal integrere på de relevante steder i dit spil.

Definitioner og globale variabler

Det følgende er en liste over include-data, som kræves for at bygge med Leaderboards-objektet, og en global pointer til vores hjælperobjekt.
... #include "steam_api.h" #include "SteamLeaderboards.h" // Global adgang til Leaderboards-objekt CSteamLeaderboards* g_SteamLeaderboards = NULL; ...

Initialisering

Kaldet til SteamAPI_Init initialiserer hele Steam og skal kaldes før noget andet. Hvis kaldet lykkes, opretter vi hjælperobjektet.
... // Initialiser Steam bool bRet = SteamAPI_Init(); // Opret SteamLeaderboards-objektet, hvis Steam blev initialiseret if (bRet) { g_SteamLeaderboards = new CSteamLeaderboards(); } ...

Behandling af tilbagekald

For at sikre, at vi behandler alle Steam-tilbagekald, skal vi jævnligt tjekke, om der er nye beskeder. Dette gøres ved at tilføje dette kald til spilløkken.
... SteamAPI_RunCallbacks(); ...

Nedlukning

Kaldet til SteamAPI_Shutdown er sikkert noget, du allerede har i din kode. Den lukker Steam ned og skal kaldes, før applikationen lukker. Til sidst sletter vi det hjælperobjekt, vi oprettede.
... // Luk Steam ned SteamAPI_Shutdown(); // Slet objektet SteamLeaderboards if (g_SteamLeaderboards) delete g_SteamLeaderboards; ...

Trin 4 – Testning og fejlfinding

Denne eksempelkode giver fejlfindingsinformation til fejlfindingskonsollen, som kan hjælpe dig med at forstå, hvilke kald der lykkes og mislykkes. Det følgende er nogle typiske fejlbeskeder og løsninger:

Denne applikation kunne ikke starte, fordi steam_api.dll ikke kunne findes. Geninstallering af applikationen løser muligvis dette problem.
Sørg for, at steam_api.dll er i samme mappe som den eksekverbare fil.

[S_API FAIL] SteamAPI_Init() failed; unable to locate a running instance of Steam, or a local steamclient.dll
Steam-klienten kører sandsynligvis ikke. Start Steam, og log på.

[S_API FAIL] SteamAPI_Init() mislykkedes. Intet app-ID fundet.
steam_appid.txt-filen er sandsynligvis ikke i den rigtige mappe. Placer den i kildemappen, og kontrollér, at den indeholder dit app-ID.