cocos2d-xでスクリーンショットを撮影する方法。
ios標準の機能だと、こんな感じになる。
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
// キャプチャ画像を描画する対象を生成します。
UIGraphicsBeginImageContextWithOptions(window.bounds.size, NO, 0.0f);
CGContextRef context = UIGraphicsGetCurrentContext();
// Windowの現在の表示内容を1つずつ描画して行きます。
for (UIWindow *aWindow in [[UIApplication sharedApplication] windows]) {
[aWindow.layer renderInContext:context];
}
// 描画した内容をUIImageとして受け取ります。
UIImage *capturedImage = UIGraphicsGetImageFromCurrentImageContext();
// 描画を終了します。
UIGraphicsEndImageContext();
参考しかし、この方法だとcocos2d-xで描画している画面は映らない。(上記コードで言うと、[aWindow.layer renderInContext:context]; の部分)
cocos2d-xの3.2以降だと、便利な機能がついている。
cocos2d::utils::captureScreen() がそれで、
以下コード例。
#include "base/ccUtils.h"
cocos2d::utils::captureScreen([&](bool succeed, const std::string &filePath){
if (succeed) {
//成功時
}
else{
//失敗時
}
}, "screenshot.png");
captureScreenの第1引数が完了時に実行するラムダ式。第2引数がファイル名。
キャプチャーが取れるとラムダ式の中が呼び出される。
ラムダ式の第2引数のfilePathは、保存したファイルの完全な絶対パスが入っている。
このパスを使って、スプライトをゲーム中に表示したり、Twitterにシェアしたりすることができる。
スプライトの場合は、通常通り
Sprite::create(filePath);
とすればよい。
ただし、そのままだと2回目以降、スクリーンショット画像が変化しない(1回目のスクリーンショットが表示されてしまう)
これは、Sprite::create()の中で自動的にテクスチャがキャッシュされているからだ。
bool Sprite::initWithFile(const std::string& filename)
{
:
Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);
:
}
そこで、毎回テクスチャキャッシュを削除すればよい。
Director::getInstance()->getTextureCache()->removeTextureForKey(filePath);
上記コードをSprite::create()の前に実行すればOK。
TwitterやFacebookにシェアする場合、UIImageインスタンスを作成する。
UIImage* image = [UIImage imageWithContentsOfFile:[NSString stringWithUTF8String:filePath]];
アセットではなくファイルパスなので、以下の書き方ではUIImageを作成できないので注意。
UIImage* image = [UIImage imageNamed:[NSString stringWithUTF8String:filePath]];
総合すると、スクリーンショットを撮ってTwitterに投稿するのは以下のようなコードになる。
XXX.cpp
cocos2d::utils::captureScreen([&](bool succeed, const std::string &filePath){
if (succeed) {
Director::getInstance()->getTextureCache()->removeTextureForKey(filePath);
twitterShare("投稿するテキスト", filePath.c_str(), "");
}
else{
}
}, "screenshot.png");
YYY.mm
void twitterShare(const char *text, const char *imageName, const char *url, ShareCallback_t successCallback= nullptr, ShareCallback_t failureCallback= nullptr, ShareCallback_t cancelCallback= nullptr){
if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {
AppController *appController = [[UIApplication sharedApplication] delegate];
RootViewController *viewController = appController.viewController;
SLComposeViewController *composeViewController = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
if (text) {
[composeViewController setInitialText: [NSString stringWithUTF8String:text]];
}
if (url) {
[composeViewController addURL: [NSURL URLWithString:[NSString stringWithUTF8String:url]]];
}
if (imageName) {
UIImage* image = [UIImage imageNamed:[NSString stringWithUTF8String:imageName]];
if (!image) {
image = [UIImage imageWithContentsOfFile:[NSString stringWithUTF8String:imageName]];
}
if (image) {
[composeViewController addImage: image];
}
}
// 完了後のハンドラを設定する
[composeViewController setCompletionHandler:^(SLComposeViewControllerResult result) {
switch (result) {
case SLComposeViewControllerResultDone:
if (successCallback) {
successCallback();
}
break;
case SLComposeViewControllerResultCancelled:
if (cancelCallback) {
cancelCallback();
}
break;
default:
if (failureCallback) {
failureCallback();
}
break;
}
[viewController dismissViewControllerAnimated:YES completion: nil];
}];
// ポップアップを起動する
[viewController presentViewController:composeViewController animated:YES completion:nil];
}
}
PR