Steamworks-dokumentaatio
Vaiheittaiset ohjeet: saavutukset

Johdanto

Tässä vaiheittaiset pikaohjeet, joilla voit integroida Steam-saavutuksia sovellukseesi alle kymmenessä minuutissa ja alle kymmenellä koodikantaasi integroidulla koodirivillä. Steamworks SDK -sovelluskehityspaketissa on erinomainen Spacewar-niminen esimerkkisovellus, jossa Steamin ominaisuudet ovat nähtävissä koko laajuudessaan. Sieltä kannattaa aloittaa Steamin kaikkien toimintojen tarkastelu. Selkeyden vuoksi tähän ohjeeseen on tiivistetty vain tarpeelliset Spacewarin, tilastojen ja saavutusten APIn tiedot, joita tarvitaan Steam-tilastoissa. Huomaa, että tilastojen ja saavutusten välillä on paljon päällekkäisyyttä. Jos integroit kummatkin sellaisenaan, ota huomioon, että monet kutsuista voidaan yhdistää.

Vaihe 1 – Pelin saavutusten määrittäminen

Saavutukset ovat sovelluskohtaisia, ja ne määritetään Saavutusten määrittäminen -sivulla Steamworks-sovellushallinnan taustajärjestelmässä. Alla on Steamworksin Spacewar-esimerkkipelin saavutusluettelo:
:
spacewar_achievements.png

Vaihe 2 – Saavutusten toiminta lyhyesti

Seuraava koodi on pelistä riippumaton, ja se voidaan lisätä peliin haluamallasi tavalla. Luokka on täysin toimiva sellaisenaan, mutta se voidaan helposti laajentaa vastaamaan muita tarpeita. Kaikki tämä koodi on otettu suoraan Spacewarin esimerkkitiedostoista: StatsAndAchievements.cpp/h.

Otsikkotiedosto

Ensin määritetään rakenne Steamin saavutustietojen säilyttämiseksi ja toimitetaan makro tämän tyyppisten objektien luomiseksi. Nämä tiedot ovat suoraan yhteydessä Saavutusten määrittäminen -sivun tietoihin.
#define _ACH_ID( id, name ) { id, #id, name, "", 0, 0 } struct Achievement_t { int m_eAchievementID; const char *m_pchAchievementID; char m_rgchName[128]; char m_rgchDescription[256]; bool m_bAchieved; int m_iIconImage; };

Seuraavaksi määritetään aputoimintoluokka, joka paketoi kaikki Steam-tilastojen API-kutsut ja luo kaikki Steam-vastakutsut.
class CSteamAchievements { private: int64 m_iAppID; // Nykyinen AppID Achievement_t *m_pAchievements; // Saavutustiedot int m_iNumAchievements; // Saavutusten lukumäärä bool m_bInitialized; // Olemmeko kutsuneet pyyntöjen tilastoja ja saaneet takaisinkutsun? public: CSteamAchievements(Achievement_t *Achievements, int NumAchievements); ~CSteamAchievements(); bool RequestStats(); bool SetAchievement(const char* ID); STEAM_CALLBACK( CSteamAchievements, OnUserStatsReceived, UserStatsReceived_t, m_CallbackUserStatsReceived ); STEAM_CALLBACK( CSteamAchievements, OnUserStatsStored, UserStatsStored_t, m_CallbackUserStatsStored ); STEAM_CALLBACK( CSteamAchievements, OnAchievementStored, UserAchievementStored_t, m_CallbackAchievementStored ); };

Kooditiedosto

Konstruktori

Muuttujat – Konstruktori vie osoittimen saavutusten jonoon (an array) sarakkeen pituuden mukana. Pääpelin kooodin kohdalla käsitellään myöhemmin jonon muotoilua.
Palautukset – —
Toiminta – Konstruktori alustaa useita jäseniä ja poimii sovellustunnuksen, jota parhaillaan käytämme. Lisäksi se kytkee vastakutsumenetelmät käsittelemään Steamiin tehdyt, asynkroniset kutsut. Lopuksi se suorittaa alustavan RequestStats()-kutsun poimiakseen saavutukset ja tilastot nykyiselle käyttäjälle.
CSteamAchievements::CSteamAchievements(Achievement_t *Achievements, int NumAchievements): m_iAppID( 0 ), m_bInitialized( false ), m_CallbackUserStatsReceived( this, &CSteamAchievements::OnUserStatsReceived ), m_CallbackUserStatsStored( this, &CSteamAchievements::OnUserStatsStored ), m_CallbackAchievementStored( this, &CSteamAchievements::OnAchievementStored ) { m_iAppID = SteamUtils()->GetAppID(); m_pAchievements = Achievements; m_iNumAchievements = NumAchievements; RequestStats(); }

RequestStats() - tilastopyynnöt

Muuttujat – Ei mitään.
Palautukset – Muuttuja, joka osoittaa, onnistuiko kutsu vai ei. Jos kutsu epäonnistui, Steamia ei todennäköisesti ole alustettu. Varmista, että Steam-sovellus on auki, kun yrität suorittaa kutsun, ja että ennen sitä on suo#ritettu SteamAPI_Init-kutsu.
Toiminta – Menetelmä paketoi käytännössä ISteamUserStats::RequestCurrentStats -kutsun, joka on Steamille lähetettävä asynkroninen kutsu, jolla pyydetään nykyisen käyttäjän saavutuksia ja tilastoja. Kutsu on suoritettava, ennen kuin tilastoja tai saavutuksia voidaan määrittää. Konstruktorissa tehdään alkukutsu menetelmälle. Jos haluat tarkistaa päivitettyjä tilastoja tai saavutuksia, voit kutsua sitä aina uudelleen.
bool CSteamAchievements::RequestStats() { // Onko Steam ladattu? Jos ei, emme saa haettua tilastoja. if ( NULL == SteamUserStats() || NULL == SteamUser() ) { return false; } // Onko käyttäjä kirjautuneena sisään? Jos ei, emme saa haettua tilastoja. if ( !SteamUser()->BLoggedOn() ) { return false; } // Pyynnön käyttäjätilastot. return SteamUserStats()->RequestCurrentStats(); }

SetAchievement() - saavutusten määrittely

Muuttujat – Saavutuksen merkkijonotunniste, jonka haluat määrittää (esim. "ACH_WIN_ONE_GAME")
Palautukset – Muuttuja, joka osoittaa, onnistuiko kutsu vai ei. Jos kutsu epäonnistui, joko Steamia ei ole alustettu tai et ole vieläkään käsitellyt ensimmäisestä RequestStats-kutsusta saatua vastakutsua. Et voi määrittää saavutuksia, ennen kuin vastakutsu on saatu.
Toiminta – Menetelmässä määritetään annettu saavutus valmiiksi, ja lähetetään tulokset Steamiin. Tietyn saavutuksen voi määrittää useita kertoja, joten sinun ei tarvitse huolehtia, onko saavutuksia määritetty vai ei. Tämä on asynkroninen kutsu, joka käynnistää kaksi vastakutsua: OnUserStatsStored() ja OnAchievementStored().
bool CSteamAchievements::SetAchievement(const char* ID) { // Olemmeko saaneet takaisinkutsua vielä Steamiltä? if (m_bInitialized) { SteamUserStats()->SetAchievement(ID); return SteamUserStats()->StoreStats(); } // Jos emme ole, emme voi määrittää vielä saavutuksia. return false; }

OnUserStatsReceived() - vastaanotetut tilastot

Muuttujat – —
Palautukset – Ei mitään
Toiminta – Menetelmä on vastakutsu, jota kutsutaan aina, kun yrität pyytää tilastoja. Tilastoja ja saavutuksia pyydetään käyttämällä kutsua RequestStats(). Menetelmässä päivitetään jäsenmuuttuja m_pAchievements kuvastamaan viimeisimpiä, palautettuja Steamin tilasto- ja saavutustietoja.
void CSteamAchievements::OnUserStatsReceived( UserStatsReceived_t *pCallback ) { // Voimme saada muiden pelitilastojen takaisinkutsuja. Ohita ne! if ( m_iAppID == pCallback->m_nGameID ) { if ( k_EResultOK == pCallback->m_eResult ) { OutputDebugString("Received stats and achievements from Steam\n"); m_bInitialized = true; // Lataa saavutukset. for ( int iAch = 0; iAch < m_iNumAchievements; ++iAch ) { Achievement_t &ach = m_pAchievements[iAch]; SteamUserStats()->GetAchievement(ach.m_pchAchievementID, &ach.m_bAchieved); _snprintf( ach.m_rgchName, sizeof(ach.m_rgchName), "%s", SteamUserStats()->GetAchievementDisplayAttribute(ach.m_pchAchievementID, "name")); _snprintf( ach.m_rgchDescription, sizeof(ach.m_rgchDescription), "%s", SteamUserStats()->GetAchievementDisplayAttribute(ach.m_pchAchievementID, "desc")); } } else { char buffer[128]; _snprintf( buffer, 128, "RequestStats - failed, %d\n", pCallback->m_eResult ); OutputDebugString( buffer ); } } }

OnUserStatsStored() - tallennetuista käyttäjätilastoita

Muuttujat – —
Palautukset – Ei mitään
Toiminta – Menetelmä on vastakutsu, jota kutsutaan aina, kun yrität tallentaa tilastoja Steamiin.
void CSteamAchievements::OnUserStatsStored( UserStatsStored_t *pCallback ) { // Voimme saada muilta saapuvilta pelitilastoilta takaisinkutsuja. Hylkää ne. if ( m_iAppID == pCallback->m_nGameID ) { if ( k_EResultOK == pCallback->m_eResult ) { OutputDebugString( "Stored stats for Steam\n" ); } else { char buffer[128]; _snprintf( buffer, 128, "StatsStored - failed, %d\n", pCallback->m_eResult ); OutputDebugString( buffer ); } } }

OnAchievementStored() - tallennetuista saavutuksista

Muuttujat – —
Palautukset – Ei mitään
Toiminta – Menetelmä on vastakutsu, jota kutsutaan aina, kun saavutusten tallentaminen onnistui Steamissä.
void CSteamAchievements::OnAchievementStored( UserAchievementStored_t *pCallback ) { // Voimme muiden pelien saapuvien tilastojen takaisinkutsuja. Hylkää ne! if ( m_iAppID == pCallback->m_nGameID ) { OutputDebugString( "Stored Achievement for Steam\n" ); } }

Vaihe 3 – Peliisi integrointi

Seuraavassa on täydellinen luettelo koodipätkistä, jotka sinun on integroitava pelisi oikeisiin paikkoihin.

Määrittäjät ja globaalit muuttujat

Seuraavassa on luettelo muuttujista, joita tarvitaan pelikohtaisten saavutusten enum-vakion sekä avustajaobjektiosoittajan tekemisessä. Huomaa, että saavutukset tulee vastata Steamworksin hallintasivulla olevia saavutuksia.
... #include "steam_api.h" // Määrittelee saavutuksemme. enum EAchievements { ACH_WIN_ONE_GAME = 0, ACH_WIN_100_GAMES = 1, ACH_TRAVEL_FAR_ACCUM = 2, ACH_TRAVEL_FAR_SINGLE = 3, }; // Saavutusten jono, joka säilyttää tiedot saavutuksista ja niiden tilasta Achievement_t g_Achievements[] = { _ACH_ID( ACH_WIN_ONE_GAME, "Winner" ), _ACH_ID( ACH_WIN_100_GAMES, "Champion" ), _ACH_ID( ACH_TRAVEL_FAR_ACCUM, "Interstellar" ), _ACH_ID( ACH_TRAVEL_FAR_SINGLE, "Orbiter" ), }; // Saavutusobjektien yleiskäyttöoikeus CSteamAchievements* g_SteamAchievements = NULL; ...

Alustus

SteamAPI_Init-kutsu alustaa kaiken Steamissä. Sitä on kutsuttava ennen mitään muuta. Jos kutsu onnistuu, luomme avustajaobjektin antamalla sille saavutusjonon ja sen koon.
... // Alusta Steam. bool bRet = SteamAPI_Init(); // Luo saavutusten SteamAchievements-objekti, jos Steamin alustus onnistui. if (bRet) { g_SteamAchievements = new CSteamAchievements(g_Achievements, 4); } ...

Vastakutsujen käsittely

Kaikkien Steam-vastakutsujen varmistamiseksi meidän tulee säännöllisesti hakea uudet viestit. Sen voi tehdä lisäämällä kutsu pelisilmukkaan.
... SteamAPI_RunCallbacks();

Saavutusten käynnistäminen

Saavutuksen käynnistäminen on yhtä yksinkertaista kuin yksittäisen kutsun ohittaminen saavutuksen tunnuksella.
... if (g_SteamAchievements) g_SteamAchievements->SetAchievement("ACH_WIN_100_GAMES"); ...

Sammutus

Koodisi todennäköisesti sisältää jo SteamAPI_Shutdown-kutsun. Se sammuttaa Steamin, ja sitä on kutsuttava ennen sovelluksen lopettamista. Lopuksi poistamme tehdyn apuobjektin.
... // Sulje Steam SteamAPI_Shutdown(); // Poista SteamAchievements-objekti if (g_SteamAchievements) delete g_SteamAchievements; ...

Vaihe 4 – Testaus ja vianmääritys

Esimerkkikoodi tulostaa virheenkorjaustiedot debug-konsoliin, mikä voi auttaa ymmärtämään, mitkä kutsuista onnistuvat ja mitkä epäonnistuvat. Seuraavat ovat tyypillisiä virhesanomia ja korjauksia:

Tämän sovelluksen käynnistyminen epäonnistui, koska steam_api.dll-tiedostoa ei löytynyt. Sovelluksen uudelleenkäynnistäminen voi korjata ongelman.
Varmista, että steam_api.dll-tiedosto on samassa hakemistossa kuin suoritettava tiedosto.

[S_API FAIL] SteamAPI_Init() epäonnistui. Esiintymää ei löydy Steamistä eikä paikallisesta steamclient.dll-tiedostosta.
Sinulla ei todennäköisesti ole Steam-sovellus päällä. Käynnistä Steam ja kirjaudu sisään.

[S_API FAIL] SteamAPI_Init() epäonnistui. Sovellustunnusta ei löydy.
Sinulla ei todennäköisesti ole steam_appid.txt-tiedostoa oikeassa paikassa. Lisää se lähdekansioon ja varmista, että siinä on appID-numerosi.