文章目录
  1. 1. SpriteKit截屏
    1. 1.1. 方法一:
    2. 1.2. 方法二:
  2. 2. 使用Social.Framework分享游戏战绩
    1. 2.1. 使用UIActivityViewController
    2. 2.2. 使用SLComposeViewController

本文讲述在用SpriteKit制作iOS游戏的时候,如何让在用户在达到某种成就后分享自己的成就或分数,并附上一张游戏截屏,然后发到社交网络上

SpriteKit截屏

传统的截屏方法是用UIView的layer来读取渲染上下文,生成图片

1
2
3
4
5

UIGraphicsBeginImageContext(self.view.frame.size); //currentView 当前的view
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

viewImage就是获取的截图,如果要将图片存入相册,只需在后面调用

1
UIImageWriteToSavedPhotosAlbum(viewImage,nil,nil,nil);

而这一切都是基于UIKit的,在SpriteKit中,上面的方法是实效的,截屏的效果就是一张白色图片
但在苹果的官方文档中,明确提到了SKTexture的作用,最后一条是说可以将节点树渲染成纹理,可以应用于对游戏截屏。苹果还告诉了我们SKView的一个方法:textureFromNode:,该方法将以node包含的内容渲染成一个纹理,但是如何将SKTexture转换为UIView呢?我在workoverflow的一个提问中找到了答案:

方法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
- (UIImage*) imageWithView:(UIView *)view
{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0);

[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];

UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

return img;
}


- (UIImage*) imageFromNode:(SKNode*)node
{
SKTexture* tex = [self.scene.view textureFromNode:node];
SKView* view = [[SKView alloc]initWithFrame:CGRectMake(0, 0, tex.size.width, tex.size.height)];
SKScene* scene = [SKScene sceneWithSize:tex.size];
SKSpriteNode* sprite = [SKSpriteNode spriteNodeWithTexture:tex];
sprite.position = CGPointMake( CGRectGetMidX(view.frame), CGRectGetMidY(view.frame) );
[scene addChild:sprite];
[view presentScene:scene];

return [self imageWithView:view];
}
  1. get the SKTexture for your node using the current SKView
  2. make another SKView that is just big enough for your texture
  3. add a SKSpriteNode with the texture into your new scene, placing it in the middle
  4. render the view into a graphics context

方法二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-(UIImage *)imageFromNode:(SKNode *)node {
SKView *view = node.scene.view;
CGFloat scale = [UIScreen mainScreen].scale;
CGRect nodeFrame = [node calculateAccumulatedFrame];

// render SKView into UIImage
UIGraphicsBeginImageContextWithOptions(view.bounds.size, YES, 0.0);
[view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES];
UIImage *sceneSnapshot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

// crop to the requested node (making sure to flip the y-coordinate)
CGFloat originY = sceneSnapshot.size.height*scale - nodeFrame.origin.y*scale - nodeFrame.size.height*scale;
CGRect cropRect = CGRectMake(nodeFrame.origin.x * scale, originY, nodeFrame.size.width*scale, nodeFrame.size.height*scale);
CGImageRef croppedSnapshot = CGImageCreateWithImageInRect(sceneSnapshot.CGImage, cropRect);
UIImage *nodeSnapshot = [UIImage imageWithCGImage:croppedSnapshot];
CGImageRelease(croppedSnapshot);

return nodeSnapshot;
}

以上两个方法亲测好使!

使用Social.Framework分享游戏战绩

因为比较懒不想在各种第三方社交网站申请APP注册然后使用SDK等,有点复杂,所以暂时用了苹果自带的Social.Framework

首先推荐一个比较好的Demo,代码很容易读,容易上手

首先到target,Build Phases->link binary with libraries,添加social.framework,然后在要使用这个framework的文件头添加@import Social;

记得要到iphone或者simulator里设置好对应社交网络的账号,填上用户名密码登录上,不然找不到account,不能post。如果找不到新浪微博,把系统语言调到中文。如果没有预先设置好账号,social.framework在真机和simulator上表现会不同。

使用UIActivityViewController

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//某个SKScene中添加的代码
sharingImage = [self imageFromNode:self];//获取截屏图片
NSArray *activityItems;
if (sharingImage != nil) {
activityItems = @[sharingText, sharingImage];
} else {
activityItems = @[sharingText];
}

UIActivityViewController *activityController =
[[UIActivityViewController alloc] initWithActivityItems:activityItems
applicationActivities:nil];

[(UIViewController *)[self.view nextResponder] presentViewController:activityController
animated:YES completion:nil];

[self.view nextResponder]的作用是获取当前SKSceneUIViewController

如果想系统的学一下UIActivityViewController,建立看看这篇翻译自Mattt Thompson博文

使用SLComposeViewController

这个就相当于上面里介绍的单个分享service
目前支持的平台有以下这些:

1
2
3
4
5
SOCIAL_EXTERN NSString *const SLServiceTypeTwitter NS_AVAILABLE(10_8, 6_0);
SOCIAL_EXTERN NSString *const SLServiceTypeFacebook NS_AVAILABLE(10_8, 6_0);
SOCIAL_EXTERN NSString *const SLServiceTypeSinaWeibo NS_AVAILABLE(10_8, 6_0);
SOCIAL_EXTERN NSString *const SLServiceTypeTencentWeibo NS_AVAILABLE(10_9, 7_0);
SOCIAL_EXTERN NSString *const SLServiceTypeLinkedIn NS_AVAILABLE(10_9, NA);

先声明一个SLComposeViewController *slComposerSheet;,然后在需要添加分享逻辑的地方加入下面代码:(依然以微博为例子)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[slComposerSheet setCompletionHandler:^(SLComposeViewControllerResult result) {
NSLog(@"start completion block");
NSString *output;
switch (result) {
case SLComposeViewControllerResultCancelled:
output = @"Action Cancelled";
break;
case SLComposeViewControllerResultDone:
output = @"Post Successfull";
break;
default:
break;
}
if (result != SLComposeViewControllerResultCancelled)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Weibo Message" message:output delegate:nil cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
}
}];

if([SLComposeViewController isAvailableForServiceType:SLServiceTypeSinaWeibo])
{
slComposerSheet = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeSinaWeibo];
[slComposerSheet setInitialText:self.sharingText];
[slComposerSheet addImage:self.sharingImage];
[slComposerSheet addURL:[NSURL URLWithString:@"http://www.weibo.com/"]];
[self presentViewController:slComposerSheet animated:YES completion:nil];
}

这种方法我没试过,代码是照抄自前面提到的Demo

文章目录
  1. 1. SpriteKit截屏
    1. 1.1. 方法一:
    2. 1.2. 方法二:
  2. 2. 使用Social.Framework分享游戏战绩
    1. 2.1. 使用UIActivityViewController
    2. 2.2. 使用SLComposeViewController