بازی های ذخیره شده را به بازی خود اضافه کنید

پس از منسوخ شدن رابط برنامه‌نویسی کاربردی ورود گوگل (Google Sign-In API)، ما در سال ۲۰۲۶ کیت توسعه نرم‌افزاری بازی‌ها نسخه ۱ (games v1 SDK) را حذف خواهیم کرد. پس از فوریه ۲۰۲۵، شما قادر به انتشار عناوینی که به تازگی با کیت توسعه نرم‌افزاری بازی‌ها نسخه ۱ (games v1 SDK) ادغام شده‌اند، در گوگل پلی نخواهید بود. توصیه می‌کنیم به جای آن از کیت توسعه نرم‌افزاری بازی‌ها نسخه ۲ (games v2 SDK) استفاده کنید.
در حالی که عناوین موجود با بازی‌های قبلی نسخه ۱ ادغام‌شده تا چند سال دیگر به کار خود ادامه می‌دهند، توصیه می‌شود از ژوئن ۲۰۲۵ به نسخه ۲ مهاجرت کنید .
این راهنما برای استفاده از SDK نسخه ۱ سرویس بازی‌های Play Games است. SDK مربوط به C++ برای سرویس بازی‌های Play Games نسخه ۲ هنوز در دسترس نیست.

این راهنما به شما نشان می‌دهد که چگونه داده‌های پیشرفت بازی یک بازیکن را با استفاده از سرویس بازی‌های ذخیره‌شده در یک برنامه C++ ذخیره و بارگذاری کنید. می‌توانید از این سرویس برای بارگذاری و ذخیره خودکار پیشرفت بازی بازیکن در هر نقطه‌ای از گیم‌پلی استفاده کنید. این سرویس همچنین می‌تواند بازیکنان را قادر سازد تا یک رابط کاربری را برای به‌روزرسانی یا بازیابی یک بازی ذخیره موجود یا ایجاد یک بازی جدید فعال کنند.

قبل از اینکه شروع کنی

اگر قبلاً این کار را نکرده‌اید، ممکن است مرور مفاهیم بازی بازی‌های ذخیره‌شده (Saved Games) برایتان مفید باشد.

قبل از شروع کدنویسی با استفاده از API بازی‌های ذخیره‌شده:

قالب‌های داده و سازگاری بین پلتفرمی

داده‌های بازی‌های ذخیره‌شده‌ای که در سرورهای گوگل ذخیره می‌کنید باید با فرمت std::vector<uint8_t> باشند. سرویس بازی‌های ذخیره‌شده، رمزگذاری داده‌های شما را برای سازگاری بین پلتفرمی انجام می‌دهد؛ برنامه‌های اندروید می‌توانند همین داده‌ها را به صورت آرایه‌ای از بایت‌ها و بدون هیچ مشکلی در سازگاری بین پلتفرمی بخوانند.

هنگام انتخاب فرمت داده برای داده‌های بازی‌های ذخیره‌شده خود، از استفاده از فرمت‌های خاص پلتفرم خودداری کنید. ما اکیداً توصیه می‌کنیم از فرمت داده‌ای مانند XML یا JSON استفاده کنید که پشتیبانی کتابخانه‌ای قوی در چندین پلتفرم دارد.

سرویس بازی‌های ذخیره‌شده را فعال کنید

قبل از اینکه بتوانید از سرویس بازی‌های ذخیره‌شده استفاده کنید، ابتدا باید دسترسی به آن را فعال کنید. برای انجام این کار، هنگام ایجاد سرویس با gpg::GameServices::Builder تابع EnableSnapshots() را فراخوانی کنید. این کار، حوزه‌های احراز هویت اضافی مورد نیاز بازی‌های ذخیره‌شده را در رویداد احراز هویت بعدی فعال می‌کند.

نمایش بازی‌های ذخیره شده

در بازی خود، می‌توانید گزینه‌ای را فراهم کنید که بازیکنان بتوانند بازی‌های ذخیره شده را ذخیره یا بازیابی کنند. وقتی بازیکنان این گزینه را انتخاب می‌کنند، بازی شما باید صفحه‌ای را نمایش دهد که اسلات‌های ذخیره موجود را نشان می‌دهد و به بازیکنان اجازه می‌دهد تا در یکی از این اسلات‌ها ذخیره یا بارگیری کنند، یا یک بازی ذخیره شده جدید ایجاد کنند. برای انجام این کار از روش زیر استفاده کنید:

  SnapshotManager::ShowSelectUIOperation(...)

رابط کاربری انتخاب بازی‌های ذخیره‌شده به بازیکنان اجازه می‌دهد تا یک بازی ذخیره‌شده جدید ایجاد کنند، جزئیات مربوط به بازی‌های ذخیره‌شده موجود را مشاهده کنند و بازی‌های ذخیره‌شده قبلی را بارگذاری کنند.

  SnapshotManager::SnapshotSelectUIResponse response;
  if (IsSuccess(response.status)) {
  if (response.data.Valid()) {
    LogI("Description: %s", response.data.Description().c_str());
    LogI("FileName %s", response.data.FileName().c_str());
    //Opening the snapshot data
    
  } else {
    LogI("Creating new snapshot");
    
  }
} else {
  LogI("ShowSelectUIOperation returns an error %d", response.status);
}

مثال زیر نحوه نمایش رابط کاربری پیش‌فرض بازی‌های ذخیره‌شده و مدیریت انتخاب رابط کاربری بازیکن را نشان می‌دهد:

  service_->Snapshots().ShowSelectUIOperation(
  ALLOW_CREATE_SNAPSHOT,
  ALLOW_DELETE_SNAPSHOT,
  MAX_SNAPSHOTS,
  SNAPSHOT_UI_TITLE,
  [this](gpg::SnapshotManager::SnapshotSelectUIResponse const & response) {
  
      }

اگر در مثال بالا، ALLOW_CREATE_SNAPSHOT true باشد و MAX_SNAPSHOTS بیشتر از تعداد واقعی snapshotهایی باشد که کاربر در حال حاضر ایجاد کرده است، رابط کاربری پیش‌فرض Snapshot به جای انتخاب یک بازی موجود، دکمه‌ای برای ایجاد یک بازی ذخیره جدید در اختیار بازیکنان قرار می‌دهد. (هنگام نمایش، دکمه در پایین رابط کاربری قرار دارد.) وقتی بازیکنی روی این دکمه کلیک می‌کند، پاسخ SnapshotSelectUIResponse معتبر است اما هیچ داده‌ای ندارد.

بازی‌های ذخیره شده را باز کنید و بخوانید

برای دسترسی به یک بازی ذخیره شده و خواندن یا تغییر محتویات آن، ابتدا شیء SnapshotMetadata که نمایانگر آن بازی ذخیره شده است را باز کنید. سپس، متد SnapshotManager::Read*() را فراخوانی کنید.

مثال زیر نحوه باز کردن یک بازی ذخیره شده را نشان می‌دهد:

  LogI("Opening file");
  service_->Snapshots()
  .Open(current_snapshot_.FileName(),
               gpg::SnapshotConflictPolicy::BASE_WINS,
        [this](gpg::SnapshotManager::OpenResponse const & response) {
           LogI("Reading file");
           gpg::SnapshotManager::ReadResponse responseRead =
           service_->Snapshots().ReadBlocking(response.data);
          
        }

تشخیص و حل تعارضات داده‌ها

وقتی یک شیء SnapshotMetadata را باز می‌کنید، سرویس بازی‌های ذخیره‌شده تشخیص می‌دهد که آیا یک بازی ذخیره‌شده‌ی متناقض وجود دارد یا خیر. ممکن است زمانی که بازی ذخیره‌شده‌ی ذخیره‌شده روی دستگاه محلی بازیکن با نسخه راه دور ذخیره‌شده در سرورهای گوگل همگام‌سازی نشده باشد، تداخل داده‌ها رخ دهد.

سیاست تداخلی که هنگام باز کردن یک بازی ذخیره شده مشخص می‌کنید، به سرویس بازی‌های ذخیره شده می‌گوید که چگونه به طور خودکار تداخل داده‌ها را حل کند. این سیاست می‌تواند یکی از موارد زیر باشد:

سیاست تعارض توضیحات
SnapshotConflictPolicy::MANUAL نشان می‌دهد که سرویس بازی‌های ذخیره‌شده نباید هیچ اقدامی برای حل مشکل انجام دهد. در عوض، بازی شما یک ادغام سفارشی انجام خواهد داد.
SnapshotConflictPolicy::LONGEST_PLAYTIME نشان می‌دهد که سرویس بازی‌های ذخیره‌شده باید بازی ذخیره‌شده‌ای را انتخاب کند که بیشترین مقدار زمان بازی را داشته باشد.
SnapshotConflictPolicy::BASE_WINS نشان می‌دهد که سرویس بازی‌های ذخیره‌شده باید بازی ذخیره‌شده‌ی پایه را انتخاب کند.
SnapshotConflictPolicy::REMOTE_WINS نشان می‌دهد که سرویس بازی‌های ذخیره‌شده باید بازی ذخیره‌شده‌ی از راه دور را انتخاب کند. نسخه از راه دور، نسخه‌ای از بازی ذخیره‌شده است که در یکی از دستگاه‌های بازیکن شناسایی شده و دارای مهر زمانی جدیدتری نسبت به نسخه پایه است.

اگر سیاست تداخلی غیر از GPGSnapshotConflictPolicyManual تعیین کرده باشید، سرویس بازی‌های ذخیره‌شده، بازی ذخیره‌شده را ادغام کرده و نسخه به‌روزرسانی‌شده را از طریق مقدار SnapshotManager::OpenResponse حاصل برمی‌گرداند. بازی شما می‌تواند بازی ذخیره‌شده را باز کند، در آن بنویسد، سپس متد SnapshotManager::Commit(...) را برای ارسال بازی ذخیره‌شده به سرورهای گوگل فراخوانی کند.

انجام ادغام سفارشی

اگر SnapshotConflictPolicy::MANUAL به عنوان سیاست تداخل مشخص کرده باشید، بازی شما باید قبل از انجام عملیات خواندن یا نوشتن بیشتر روی بازی ذخیره شده، هرگونه تداخل داده‌ای شناسایی شده را برطرف کند.

در این حالت، هنگامی که یک تداخل داده‌ای تشخیص داده می‌شود، سرویس پارامترهای زیر را از طریق SnapshotManager::OpenResponse برمی‌گرداند:

  • یک conflict_id برای شناسایی منحصر به فرد این تداخل (شما هنگام اعمال نسخه نهایی بازی ذخیره شده از این مقدار استفاده خواهید کرد)؛
  • نسخه پایه متناقض بازی ذخیره شده؛ و،
  • نسخهٔ از راه دورِ متناقضِ بازی ذخیره‌شده.

بازی شما باید تصمیم بگیرد که چه داده‌هایی را ذخیره کند، سپس متد SnapshotManager::ResolveConflictBlocking() را برای ارسال/تحویل نسخه نهایی به سرورهای گوگل فراخوانی کند.

    //Resolve conflict
    gpg::SnapshotManager::OpenResponse resolveResponse =
        manager.ResolveConflictBlocking(openResponse.conflict_base, metadata_change,
                                  openResponse.conflict_id);

بازی‌های ذخیره شده را بنویسید

برای نوشتن یک بازی ذخیره شده، ابتدا شیء SnapshotMetadata که نمایانگر آن بازی ذخیره شده است را باز کنید، هرگونه تداخل داده‌ای که شناسایی شده است را برطرف کنید، سپس متد SnapshotManager::Commit() را برای اعمال تغییرات بازی ذخیره شده خود فراخوانی کنید.

مثال زیر نشان می‌دهد که چگونه می‌توانید یک تغییر ایجاد کنید و یک بازی ذخیره شده را ثبت کنید.

  1. ابتدا، اسنپ‌شاتی که می‌خواهیم ویرایش کنیم را باز کنید و با انتخاب پایه، مطمئن شوید که همه تداخل‌ها برطرف شده‌اند.

    service_->Snapshots().Open(
          file_name,
          gpg::SnapshotConflictPolicy::BASE_WINS,
          [this](gpg::SnapshotManager::OpenResponse const &response) {
            if (IsSuccess(response.status)) {
              // metadata : gpg::SnapshotMetadata
              metadata = response.data;
            } else {
              // Handle snapshot open error here
            }
          });
    
  2. در مرحله بعد، یک تغییر بازی ذخیره شده ایجاد کنید که شامل داده‌های تصویری مورد استفاده برای تصویر جلد باشد:

    gpg::SnapshotMetadataChange::Builder builder;
    gpg::SnapshotMetadataChange metadata_change =
        builder.SetDescription("CollectAllTheStar savedata")
                 .SetCoverImageFromPngData(pngData).Create();
    
  3. در نهایت، تغییرات ذخیره شده بازی را اعمال کنید.

    gpg::SnapshotManager::CommitResponse commitResponse =
        service_->Snapshots().CommitBlocking(metadata, metadata_change, SetupSnapshotData());
    

    پارامتر data شامل تمام داده‌های ذخیره شده بازی است که شما ذخیره می‌کنید. این تغییر همچنین شامل فراداده‌های اضافی بازی ذخیره شده، مانند زمان بازی و توضیحی برای بازی ذخیره شده است.

اگر عملیات کامیت با موفقیت انجام شود، بازیکنان می‌توانند بازی ذخیره شده را در رابط کاربری انتخاب بازی‌های ذخیره شده مشاهده کنند.