Secara singkat
Gunakan pencapaian untuk mengapresiasi pemain yang mencapai titik pencapaian tertentu atau karena melakukan interaksi tertentu dengan game-mu.Tingkat integrasi
10 menit dan tidak lebih dari 10 baris kode. Integrasi SDK Steamworks dibutuhkan.Pendahuluan
Pencapaian bisa digunakan sebagai cara untuk mendorong dan menghargai interaksi dan pencapaian pemain dalam game-mu. Biasanya diberikan untuk menandai jumlah kill, jarak yang ditempuh, peti yang dibuka, atau tindakan umum lainnya dalam game-mu. Dan ini juga bisa digunakan untuk membantu pemainmu menemukan berbagai cara dalam memainkan game-mu. Ketika dibuka, pencapaian ini akan muncul di sudut jendela pemain dan di halaman pencapaian pemain tersebut.
Ringkasan Teknis
Berikut ini adalah panduan lengkap untuk mengintegrasikan Pencapaian Steam yang paling dasar ke aplikasi dalam waktu kurang dari 10 menit dan mengintegrasikan kurang dari 10 baris kode ke kode dasarmu.
SDK Steamworks hadir dengan contoh aplikasi yang sangat bagus, yaitu
Spacewar, yang menunjukkan beragamnya pilihan fitur Steam dan seharusnya menjadi tempat pertamamu untuk melihat kerja seluruh fitur Steam. Tutorial ini merangkum informasi yang ditemukan di Spacewar dan API Statistik dan Pencapaian, sehingga hanya menyajikan informasi yang diperlukan untuk memahami cara kerja Statistik Steam. Harap diingat bahwa ada banyak tumpang tindih antara statistik dan pencapaian, sehingga jika kamu mengintegrasikan keduanya, banyak panggilan yang akan terkonsolidasi.
Langkah 1 - Mendefinisikan Pencapaian game-mu
Pencapaian bersifat khusus untuk aplikasi dan diatur di halaman
Konfigurasi Pencapaian di backend Admin Aplikasi Steamworks. Berikut adalah daftar pencapaian dari aplikasi Spacewar di Steamworks:
Langkah Ke-2 - Mengenkapsulasi kerja Pencapaian
Kode berikut bisa diterapkan pada game apa pun dan bisa ditambahkan ke game-mu sesuai kebutuhan. Kelasnya berfungsi penuh tanpa harus diubah, tapi bisa diekstensi untuk memenuhi kebutuhan lebih lanjut. Semua kode ini diambil langsung dari file Spacewar
StatsAndAchievements.cpp/h
.
File Tajuk
Kita mulai dengan mendefinisikan stuktur untuk menyimpan data pencapaian yang kita terima dari Steam dan menyediakan makro untuk membuat objek jenis ini. Data ini memetakan langsung apa yang ditemukan di halaman
Konfigurasi Pencapaian.
#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;
};
Kemudian, definisikan kelas helper yang akan membungkus panggilan API Statistik Steam, dan akan membuat semua
callback Steam.
class CSteamAchievements
{
private:
int64 m_iAppID; // Our current AppID
Achievement_t *m_pAchievements; // Data Pencapaian
int m_iNumAchievements; // Jumlah Pencapaian
bool m_bInitialized; // Sudahkah kamu memanggil statistik Permintaan dan menerima callback?
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 );
};
File Kode
Konstruktor
Parameter - Konstruktor menyertakan penunjuk ke array pencapaian beserta panjang array. Format array ini tercakup dalam kode utama game di bawah ini.
Hasil - N/A
Fungsi - Konstruktor menginisialisasi sejumlah anggota sambil mengambil AppID yang sedang kita gunakan. Metode callback juga disertakan untuk memproses panggilan asinkron ke Steam. Terakhir, panggilan awal ke
RequestStats()
dilakukan untuk mengambil statistik dan pencapaian pengguna saat ini.
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()
Parameter - Tidak ada
Hasil - nilai boolean menunjukkan apakah panggilan berhasil atau gagal. Jika panggilan gagal, maka kemungkinan besar Steam tidak diinisialisasi. Pastikan Steam Client terbuka ketika melakukan panggilan ini dan bahwa
SteamAPI_Init telah dipanggil sebelumnya.
Fungsi - Metode ini pada dasarnya membungkus panggilan
ISteamUserStats::RequestCurrentStats yang merupakan panggilan asinkron ke Steam untuk meminta statistik dan pencapaian dari pemain saat ini. Panggilan ini harus dibuat sebelum kamu mengatur statistik dan pencapaian. Panggilan awal untuk metode ini dibuat di konstruktor. Kamu bisa memanggilnya lagi kapan pun setelahnya jika kamu ingin melihat pembaruan statistik atau pencapaian.
bool CSteamAchievements::RequestStats()
{
// Apakah Steam dimuat? Kita tidak bisa mendapatkan statistik jika tidak.
if ( NULL == SteamUserStats() || NULL == SteamUser() )
{
return false;
}
// Apakah pengguna login? Kita tidak bisa mendapatkan statistik jika tidak.
if ( !SteamUser()->BLoggedOn() )
{
return false;
}
// Meminta statistik pengguna.
return SteamUserStats()->RequestCurrentStats();
}
SetAchievement()
Parameter - Pengidenfikasi string dari Pencapaian yang ingin kamu atur (cth. "ACH_WIN_ONE_GAME")
Hasil - nilai boolean menunjukkan apakah panggilan berhasil atau gagal. Jika panggilan gagal, maka ini bisa disebabkan karena Steam belum diinisialisasi atau belum memproses callback dari panggilan awal ke
RequestStats
. Kamu tidak bisa mengatur pencapaian apa pun hingga callback sudah diterima.
Fungsi - Metode ini mengatur pencapaian tertentu untuk dicapai dan mengirim hasilnya ke Steam. Kamu bisa menetapkan pencapaian beberapa kali, jadi kamu tidak perlu khawatir untuk menetapkan hanya pencapaian yang belum kamu atur. Ini adalah panggilan asinkron yang akan memicu dua callback:
OnUserStatsStored()
dan
OnAchievementStored()
.
bool CSteamAchievements::SetAchievement(const char* ID)
{
// Apakah kamu sudah menerima callback dari Steam?
if (m_bInitialized)
{
SteamUserStats()->SetAchievement(ID);
return SteamUserStats()->StoreStats();
}
// Pencapaian tidak dapat diatur jika belum
return false;
}
OnUserStatsReceived()
Parameter - N/A
Hasil - Tidak ada
Fungsi - Metode ini adalah callback yang dipanggil kapan saja kamu mencoba meminta statistik. Statistik dan pencapaian diminta menggunakan
RequestStats()
. Metode ini memperbarui variabel anggota m_pAchievements untuk mencerminkan data statistik dan pencapaian yang paling terkini yang didapatkan dari Steam.
void CSteamAchievements::OnUserStatsReceived( UserStatsReceived_t *pCallback )
{
// kita mungkin akan mendapatkan callback untuk statistik game lain yang datang, abaikanlah
if ( m_iAppID == pCallback->m_nGameID )
{
if ( k_EResultOK == pCallback->m_eResult )
{
OutputDebugString("Received stats and achievements from Steam\n");
m_bInitialized = true;
// load achievements
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()
Parameter - N/A
Hasil - Tidak ada
Fungsi - Metode ini adalah callback yang dipanggil kapan saja kamu mencoba untuk menyimpan statistik di Steam.
void CSteamAchievements::OnUserStatsStored( UserStatsStored_t *pCallback )
{
// kita mungkin akan mendapatkan callback untuk statistik game lain yang datang, abaikanlah
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()
Parameter - N/A
Hasil - Tidak ada
Fungsi - Metode ini adalah callback yang dipanggil kapan saja Pencapaian berhasil disimpan di Steam.
void CSteamAchievements::OnAchievementStored( UserAchievementStored_t *pCallback )
{
// we may get callbacks for other games' stats arriving, ignore them
if ( m_iAppID == pCallback->m_nGameID )
{
OutputDebugString( "Stored Achievement for Steam\n" );
}
}
Langkah Ke-3 - Mengintegrasikan ke game-mu
Berikut adalah daftar lengkap cuplikan kode yang harus kamu integrasikan ke game-mu di lokasi yang sesuai.
Definisi dan Global
Berikut ini adalah daftar pernyataan penyertaan yang dibutuhkan untuk membuat Pencapaian, penghitungan dari pencapaian khusus game kita, dan penunjuk global ke objek helper kita. Pastikan bahwa pencapaiannya sesuai dengan yang ada di halaman Admin di Steamworks.
...
#include "steam_api.h"
// Mendefinisikan pencapaian kita
enum EAchievements
{
ACH_WIN_ONE_GAME = 0,
ACH_WIN_100_GAMES = 1,
ACH_TRAVEL_FAR_ACCUM = 2,
ACH_TRAVEL_FAR_SINGLE = 3,
};
// Array Pencapaian akan menyimpan data tentang pencapaian dan statusnya
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" ),
};
// Akses global ke objek Pencapaian
CSteamAchievements* g_SteamAchievements = NULL;
...
Inisialisasi
Panggilan ke
SteamAPI_Init menginisialisasi keseluruhan Steam dan harus dipanggil sebelum yang lainnya. Jika panggilannya berhasil, buat objek helper dengan meneruskan array pencapaian dan ukuran array.
...
// Menginisialisasi Steam
bool bRet = SteamAPI_Init();
// Buat objek Pencapaian Steam jika Steam berhasil diinisialisasi
if (bRet)
{
g_SteamAchievements = new CSteamAchievements(g_Achievements, 4);
}
...
Memproses Callback
Untuk memastikan bahwa kita sudah memproses semua callback Steam, kita harus mengirimkan pesan baru secara teratur. Ini dicapai dengan menambahkan panggilan ini ke loop game.
...
SteamAPI_RunCallbacks();
...
Memicu Pencapaian
Untuk memicu pencapaian, hanya diperlukan satu panggilan yang meneruskan pengidentifikasi pencapaian.
...
if (g_SteamAchievements)
g_SteamAchievements->SetAchievement("ACH_WIN_100_GAMES");
...
Mematikan
Panggilan ke
SteamAPI_Shutdown adalah sesuatu yang mungkin sudah ada di kodemu. Ini akan menutup Steam dan harus dipanggil sebelum aplikasimu tertutup. Terakhir, hapus objek helper yang kita buat.
...
// Matikan Steam
SteamAPI_Shutdown();
// Hapus objek SteamAchievments
if (g_SteamAchievements)
delete g_SteamAchievements;
...
Langkah 4 - Pengujian dan Troubleshoot
Untuk mengatur atau menghapus pencapaian tanpa menambahkan kode ke game-mu, kamu bisa menggunakan konsol Steam Client. Jalankan dengan steam.exe -console, kemudian:
- achievement_clear <appid> <achievement name>
- reset_all_stats <appid>