マルチプレイヤー アクティビティのコード例
このトピックは、マルチプレイヤー アクティビティ クライアント API の基本的な使用方法を示すクイックスタート ガイドです。 このトピックでは、アクティビティの管理、招待の送信、最近遊んだプレイヤー リストへのプレイヤーの追加について説明します。
アクティビティ
アクティビティを設定する
タイトルでは、マルチプレイヤー エクスペリエンスを開始または参加したときに、アクティビティが作成される必要があります。 この操作を行うと、タイトルのシェルおよび他のプレイヤーの両方が、プレイヤーのアクティビティを確認でき、他のプレイヤーが進行中のゲームに参加できるようになります。 プレイヤーがタイトルのアクティビティに参加しようとしていて実行されていない場合、それはアクティブになり、接続文字列が渡されます。
タイトルは、プレーヤーの参加または離脱後にアクティビティを更新する必要があります。 これにより、他のプレイヤーにアクティビティのよりリッチなビューを提供し、アクティビティが満員になった場合には通知を行います。
アクティビティ フィールドの詳細については、「Activity contents (アクティビティのコンテンツ)」を参照してください。
アクティビティを設定するコード例は次のとおりです。 これは、アクティビティを作成する際にも、既存のアクティビティを更新する際にも適用されます。
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
HRESULT hr = XAsyncGetStatus(async, false);
};
XblMultiplayerActivityInfo info{};
info.connectionString = "dummyConnectionString";
info.joinRestriction = XblMultiplayerActivityJoinRestriction::Followed;
info.maxPlayers = 10;
info.currentPlayers = 1;
info.groupId = "dummyGroupId";
HRESULT hr = XblMultiplayerActivitySetActivityAsync(
xblContext,
&info,
false,
async.get()
);
if (SUCCEEDED(hr))
{
async.release();
}
詳細については、以下を参照してください。
- XAsyncBlock
- XAsyncGetStatus
- XblMultiplayerActivityInfo
- XblMultiplayerActivityJoinRestriction
- XblMultiplayerActivitySetActivityAsync
アクティビティの取得
タイトルで、他のユーザーのアクティビティを確認したい場合があります。 たとえばあるタイトルでは、プレイヤーのフレンドのゲーム内 UI を、彼らのアクティビティと並べて表示したい場合があるでしょう。
アクティビティを取得するコード例を以下に示します。
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
size_t resultSize{};
HRESULT hr = XblMultiplayerActivityGetActivityResultSize(async, &resultSize);
if (SUCCEEDED(hr))
{
std::vector<uint8_t> buffer(resultSize);
XblMultiplayerActivityInfo* activityInfo{};
size_t resultCount{};
hr = XblMultiplayerActivityGetActivityResult(async, buffer.size(), buffer.data(), &activityInfo, &resultCount, nullptr);
if (SUCCEEDED(hr))
{
// ...
}
}
};
HRESULT hr = XblMultiplayerActivityGetActivityAsync(
xblContext,
&xuid,
1,
async.get()
);
if (SUCCEEDED(hr))
{
async.release();
}
詳細については、以下を参照してください。
- XAsyncBlock
- XblMultiplayerActivityGetActivityResultSize
- XblMultiplayerActivityInfo
- XblMultiplayerActivityGetActivityResult
- XblMultiplayerActivityGetActivityAsync
アクティビティを削除する
プレイヤーがマルチプレイヤーのアクティビティを終了、または退出したとき、次のコードを使用してタイトルでアクティビティを削除します。
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
HRESULT hr = XAsyncGetStatus(async, false);
};
HRESULT hr = XblMultiplayerActivityDeleteActivityAsync(xblContext, async.get());
if (SUCCEEDED(hr))
{
async.release();
}
詳細については、以下を参照してください。
招待
UI なしで招待を送信する
プレイヤーは、1 人以上の他のプレイヤーに直接招待を送信することができます。 招待状を送信する前に、タイトルでアクティビティが設定されていることを確認する必要があります。 シェルは現在のアクティビティに基づいて招待を送信するため、こうすることでシェルとタイトル間の連続性を維持できます。
UI なしで招待を送信するには、XblMultiplayerActivitySetActivityAsync を使用してアクティビティを設定した後 (上記の例を参照)、タイトルは XblMultiplayerActivitySendInvitesAsync API を呼び出し、招待するプレイヤーの配列と現在のアクティビティで使用されているのと同じ接続文字列を渡す必要があります。
招待の内容については、「別のプレイヤーがマルチプレイヤー エクスペリエンスに参加するための要求を送信する」 を参照してください。
UI なしで招待を送信するコードの例を次に示します。
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
HRESULT hr = XAsyncGetStatus(async, false);
};
HRESULT hr = XblMultiplayerActivitySendInvitesAsync(
xblContext,
&xuid,
1,
true, // Setting false will send the invite to only players on the sender's platform.
"dummyConnectionString",
async.get()
);
if (SUCCEEDED(hr))
{
async.release();
}
詳細については、以下を参照してください。
UI を使用して招待を送信する
プレイヤーは、1 人以上の他のプレイヤーに直接招待を送信することができます。 招待状を送信する前に、タイトルでアクティビティが設定されていることを確認する必要があります。 シェルは現在のアクティビティに基づいて招待を送信するため、こうすることでシェルとタイトル間の連続性を維持できます。
UI を使用して招待を送信するには、XblMultiplayerActivitySetActivityAsync を使用してアクティビティを設定した後 (上記の例を参照)、タイトルは XGameUiShowMultiplayerActivityGameInviteAsync API を呼び出し、要求元のユーザーに渡す必要があります。 タイトルの現在のアクティビティを使用し、接続文字列と設定を使用してプレイヤーを招待します。
招待の内容については、「別のプレイヤーがマルチプレイヤー エクスペリエンスに参加するための要求を送信する」 を参照してください。
UI を使用して招待を送信するコードの例を次に示します。
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
HRESULT hr = XGameUiShowMultiplayerActivityGameInviteResult(async);
if (hrAsync == S_OK)
{
// Handle success
}
else
{
// Likely will only happen during development - usually indicates
// an invalid user was passed in or that there is no multiplayer activity set
}
};
HRESULT hr = XGameUiShowMultiplayerActivityGameInviteAsync(
async.get()
requestingUser
);
if (SUCCEEDED(hr))
{
async.release();
}
詳細については、以下を参照してください。
- XAsyncBlock
- XAsyncGetStatus
- XGameUiShowMultiplayerActivityGameInviteAsync
- XGameUiShowMultiplayerActivityGameInviteResult
招待を受け取る
プレイヤーが招待を受け入れたときに通知されるようにするために、タイトルは XGameInviteRegisterForEvent
を使用して招待通知に登録できます。 招待が受け入れられるたびに、登録したコールバックから形式設定された URI がタイトルに渡されるようになります。 この URI は、招待の送信者、受信者、および接続文字列を判別するために解析できます。 接続文字列は、タイトル固有であり、マルチプレイヤー アクティビティの作成時に設定されます。 マルチプレイヤー アクティビティ サービスを使用するタイトルの場合、URI の完全な形式は次の表のとおりです。
プラットフォーム | 形式 |
---|---|
Microsoft Game Development Kit (GDK) またはコンソールの Xbox One ソフトウェア開発キット (XDK) | ms-xbl-<titleId>://inviteAccept?invitedUser=<xuid>&sender=<xuid>&connectionString=<connectionString> |
Microsoft Game Development Kit (GDK) または PC のユニバーサル Windows プラットフォーム (UWP) | ms-xbl-multiplayer://inviteAccept?invitedUser=<xuid>&sender=<xuid>&connectionString=<connectionString> |
招待通知が不要になったときには、XGameInviteUnregisterForEvent
を使用してコールバックの登録を解除できます。
受け入れた招待の登録と処理のコード例を次に示します。
void CALLBACK MyXGameInviteEventCallback(
_In_opt_ void* context,
_In_ const char* inviteUri)
{
if (inviteUri != nullptr)
{
std::string uri{ inviteUri };
size_t invitedUserBegin = uri.find("invitedUser=");
size_t senderBegin = uri.find("sender=");
std::string invitedUser = uri.substr(invitedUserBegin, uri.find('&', invitedUserBegin) - invitedUserBegin);
std::string sender = uri.substr(senderBegin, uri.find('&', senderBegin) - senderBegin);
std::string connectionString = uri.substr(uri.find("connectionString="));
// ...
}
}
XTaskQueueRegistrationToken token = { 0 };
HRESULT hr = XGameInviteRegisterForEvent(
queue,
nullptr,
MyXGameInviteEventCallback,
&token
);
// ...
bool result = XGameInviteUnregisterForEvent(token, true);
詳細については、以下を参照してください。
最近遊んだプレイヤー
ユーザーの最近遊んだプレイヤー リストを更新するために、タイトルは現在のプレーヤーと意味のあるやり取りをした他のプレーヤーのリストを送信する必要があります。 リストは一方向です。つまり、各プレイヤーのクライアントが自身のリストを更新する責任を負っており、プレイヤーのリストは他のプレイヤーには影響しません。
たとえば、ゲーム前のロビーにプレーヤーのグループが一緒にいて、マッチングが行われたとします。 各プレイヤーは、マッチが始まると、ロビーにいる他のすべての xuids
と一緒に自分のリストを更新します。 新しいプレイヤーが参加した場合、個別に書き込めるようになっています。
注意
重要な相互作用を定義する条件を決定できます。 1 つのタイトルでは、ロビーに存在している可能性があります。 もう 1 つのタイトルでは、プレーヤーが他のプレーヤーを撃つこともあります。 3 番目のタイトルでは、単にもう 1 人のプレーヤーが画面に表示されているだけかもしれません。
対戦セッションが開始されるまでプレイヤーのチームが表示されないようにしたい場合は、互いのチームを表示したいタイミングが来るまで、プレイヤーのリストの表示を遅らせることができます。 クライアント側で、最近遊んだプレイヤーのリストをフラッシュするには、直ちに強制的にフラッシュする必要がある場合は XblMultiplayerActivityFlushRecentPlayersAsync
を呼び出すことができます。 それ以外の場合、最近遊んだプレイヤーのリストは 5 秒ごとに自動的にフラッシュされます。
最近遊んだプレイヤーのリストを更新し、更新をフラッシュするプログラムのコード例を以下に示します。
最近遊んだプレイヤーを更新する
XblMultiplayerActivityRecentPlayerUpdate update{ xuid };
HRESULT hr = XblMultiplayerActivityUpdateRecentPlayers(xblContext, &update, 1);
詳細については、以下を参照してください。
最近遊んだプレイヤーをフラッシュする
auto async = std::make_unique<XAsyncBlock>();
async->queue = queue;
async->callback = [](XAsyncBlock* async)
{
std::unique_ptr<XAsyncBlock> asyncBlockPtr{ async }; // Take ownership of XAsyncBlock.
HRESULT hr = XAsyncGetStatus(async, false);
};
HRESULT hr = XblMultiplayerActivityFlushRecentPlayersAsync(xblContext, async.get());
if (SUCCEEDED(hr))
{
async.release();
}
詳細については、以下を参照してください。