利用URLSchemes功能通过邮件发送“游戏关卡”的解决方案(转)

来源:互联网 发布:mac进度条卡一半黑屏 编辑:程序博客网 时间:2024/06/03 21:59
        你是否想过为自己的游戏中加入“发送自定义游戏关卡“的功能呢?

如果你有自己的服务器的话当然可以实现,或是使用openfeint的挑战功能以及Gamecenter(这个木有试过)来实现。

但是这些方法总是有些麻烦…要么得有台服务器,要么得使用penfeint/gamecenter(有的用户可能并没有用这些功能)。

其实,使用URLSchemes可以很简单的实现”游戏关卡发送“的功能^_^

本问包括了以下的内容:

1.准备需要的Scene和类
2.JSON文件的读写
3.在游戏内发送邮件
4.使用URLSchemes发送和接收数据
5.总结

1.准备需要的Scene和类

为了保证项目简单易懂,我们首先准备了以下几个Scene:

a.MainMenu Scene: 主菜单,包含了一些跳转的菜单项

b.MyEditor Scene: 随机生成”游戏关卡“并同时保存至本地,也可以通过邮件发送给朋友

c.MySentLevel Scene: 显示所有”发送的关卡“,可以选择关卡进行加载显示内容

d.MyReceivedLevel Scene: 显示所有”通过邮件接收的关卡“,可以选择关卡进行加载显示内容

除了这些Scene以外我们还需要一个使用单件模式的”GameDataManage“类来保存一些数据和提供一些方法,这样我们就可以在项目的所有地方对其进行访问。

最后需要的,是一个与JSON中保存数据结构一一对应的”GameLevelData”类。

OK,准备工作完成,接下来就开始JSON的读写部分^_^

2.JSON文件的读写

写游戏的一个好习惯自然是把一些数据和代码分离出来,用配置文件来进行保存。你可以使用plist或是xml,不过本项目选择使用JSON。

当你的游戏数据结构比较简单的时候,JSON会是一个不错的选择,通过cocos2d自带的”TouchJson”三方库,可以帮助你很轻松的读写JSON文件。

本项目所使用的JSON文件结构:



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
29
30

{
    "PlayerName": "SuperSuRaccoon",
    "SpriteArray":
    [
        {
            "SpriteName": "Sprite1",
            "SpritePng": "raccoon.png",
            "SpriteScale": 1.2,
            "SpritePosition":
            [
                {
                    "XPos": 120,
                    "YPos": 150,
                }
            ]
        },
        {
            "SpriteName": "Sprite2",
            "SpritePng": "rabbit.png",
            "SpriteScale": 0.6,
            "SpritePosition":
            [
                {
                    "XPos": 300,
                    "YPos": 100,
                }
            ]
        }
    ]
}

结构比较简单,主要是一个用户名,以及保存了CCSprite各种属性的大小可变的”SpriteArray”。

2.1 读取JSON文件

读取JSON格式的文件非常简单:



1
2
3
4

NSString *testJsonFilePath = [[NSBundle mainBundle]pathForResource:@"test" ofType:@"json"];
NSData *testJsonFileData = [[NSFileManager defaultManager] contentsAtPath:testJsonFilePath];
CJSONDeserializer *jsonDeserializer = [CJSONDeserializer deserializer];
NSDictionary *testConfigDict = [jsonDeserializer deserializeAsDictionary:fileData error:nil];

首先把文件内容读入NSData,再使用CJSONDeserializer来将NSData转换为NSDictionary。

2.2 解析NSDictionary

NSDictionary中包含了我们所有的游戏数据信息,我们需要将其解析为我们的”GameLevelData”类对:

”GameLevelData“类:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

@interface SpriteData : CCNode {
   
    NSString *spriteName;
    NSString *spritePng;
    CGPoint spritePosition;
    float spriteScale;
}
@property(nonatomic, retain) NSString *spriteName;
@property(nonatomic, retain) NSString *spritePng;
@property(nonatomic) CGPoint spritePosition;
@property(nonatomic) float spriteScale;
@end
@interface GameLevelData : CCNode {
    NSString *playerName;
    NSMutableArray *spriteArray;
}
@property(nonatomic, retain) NSString *playerName;
@property(nonatomic, retain) NSMutableArray *spriteArray;
@end

如何读取”playername“属性内容:



1
2

GameLevelData *glData = [[GameLevelData alloc] init];
glData.playerName = [testConfigDict objectForKey:@"PlayerName"];

很简单吧^_^

读取spriteArray的话就相对比较麻烦了:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

NSArray *spriteArray = [testConfigDict valueForKey:@"SpriteArray"];
for (NSDictionary *spriteInfo in spriteArray) {
    SpriteData *spData = [[SpriteData alloc] init];
    spData.spriteName = [spriteInfo objectForKey:@"SpriteName"];
    spData.spritePng = [spriteInfo objectForKey:@"SpritePng"];
    spData.spriteScale = [[spriteInfo objectForKey:@"SpriteScale"] floatValue];
               
    NSArray *spritePosArray = [spriteInfo valueForKey:@"SpritePosition"];
    for (NSDictionary *spritePosInfo in spritePosArray) {
       
        spData.spritePosition = ccp([[spritePosInfo objectForKey:@"XPos"] floatValue],
                                    [[spritePosInfo objectForKey:@"YPos"] floatValue]);
    }
   
    [glData.spriteArray addObject:spData];
}

搞定。

顺便把解析后的数据打印出来检查一下:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

-(void) printGameLeveDataInfo:(GameLevelData *)glData
{
    /*Debug Log*/
    CCLOG(@"/**************Game level data**************/");
    CCLOG(@"PlayerName: %@", glData.playerName);
   
    for (SpriteData *spData in glData.spriteArray) {
       
        CCLOG(@"SpriteName: %@", spData.spriteName);
        CCLOG(@"SpritePng: %@", spData.spritePng);
        CCLOG(@"SpritePng: %0.1f", spData.spriteScale);
        CCLOG(@"SpritePosition: %0.1f - %0.1f", spData.spritePosition.x, spData.spritePosition.y);
    }
    CCLOG(@"/*******************************************/");
    /*Debug Log*/  
}

控制台输出结果:



1
2
3
4
5
6
7
8
9
10
11

URLSchemesDemo[1012:207] /**************Game level data**************/
URLSchemesDemo[1012:207] PlayerName: SuperSuRaccoon
URLSchemesDemo[1012:207] SpriteName: Sprite1
URLSchemesDemo[1012:207] SpritePng: raccoon.png
URLSchemesDemo[1012:207] SpritePng: 1.2
URLSchemesDemo[1012:207] SpritePosition: 120.0 - 150.0
URLSchemesDemo[1012:207] SpriteName: Sprite2
URLSchemesDemo[1012:207] SpritePng: rabbit.png
URLSchemesDemo[1012:207] SpritePng: 0.6
URLSchemesDemo[1012:207] SpritePosition: 300.0 - 100.0
URLSchemesDemo[1012:207] /***********************************************/

好了, 现在我们已经成功的读取并解析了JSON文件。接下来就是保存JSON文件了。

2.3 JSON文件的保存

其实将NSData保存为JSON文件并不需要使用到TouchJson,只需要:



1

[jsonData writeToFile:filePath options:NSDataWritingAtomic error:nil];

就可以了。

但是我们需要使用TouchJson来将NSDictinnary转换为NSData:



1

jsonData = [[CJSONSerializer serializer] serializeObject:gameLevelDic error:nil];

NSDictionary中包含的数据必须与JSON的数据结构一一对应,其实就是我们读取解析JSON的一个逆操作:



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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

//save all the level info into a Big Dic
NSMutableDictionary *gameLevelDic = [[NSMutableDictionary alloc] init];
[gameLevelDic setValue:@"sxc" forKey:@"PlayerName"];
NSMutableArray *spriteArray = [[NSMutableArray alloc] init];
   
//random num of sprites to generate
numOfSprites = 1 + CCRANDOM_0_1() * 10;
   
for (int i = 0; i < numOfSprites; i++) {
       
    //pick raccoon or rabbit
    NSString *spriteFile = @"";
    if (CCRANDOM_0_1() > 0.5f) {
       
        spriteFile = @"raccoon.png";
    }
    else {
       
        spriteFile = @"rabbit.png";
    }
    CCSprite *sprite = [CCSprite spriteWithFile:spriteFile];
    sprite.scale = 0.1 + CCRANDOM_0_1() * 1;
    sprite.position = ccp(20 + CCRANDOM_0_1() * 400, 20 + CCRANDOM_0_1() * 300);
    sprite.tag = i;
   
    [self addChild:sprite];
   
    //Position info
    NSMutableDictionary *positionDic = [[NSMutableDictionary alloc] init];
    [positionDic setValue:[NSNumber numberWithFloat:sprite.position.x] forKey:@"XPos"];
    [positionDic setValue:[NSNumber numberWithFloat:sprite.position.y] forKey:@"YPos"];
   
    //Sprite info
    NSMutableDictionary *spriteDic = [[NSMutableDictionary alloc] init];
    [spriteDic setValue:spriteFile forKey:@"SpriteName"];
    [spriteDic setValue:spriteFile forKey:@"SpritePng"];
    [spriteDic setValue:[NSNumber numberWithFloat:sprite.scale] forKey:@"SpriteScale"];
   
    NSMutableArray *posArray = [[NSMutableArray alloc] init];
    [posArray addObject:positionDic];
    [spriteDic setValue:posArray forKey:@"SpritePosition"];
   
    [spriteArray addObject:spriteDic];
}
[gameLevelDic setValue:spriteArray forKey:@"SpriteArray"];

这样我们就可以把NSDictioany转换为NSData并写入JSON文件了。

PS: 这里保存好的JSON文件在格式上有一点小问题,文件中没有换行符和缩进,所以看起来比较麻烦,当然你可以自己写一段程序来解决这个问题。

接下来,我们就要在游戏中,通过邮件来发送我们的”游戏关卡“内容了^_^

我会在第二部分完成后把整个项目的源代码下载地址发布出来^_^

项目截图:

利用URLSchemes功能通过邮件发送“游戏关卡”的解决方案(转) - ♂苹果 - 眼睛想旅行
  
利用URLSchemes功能通过邮件发送“游戏关卡”的解决方案(转) - ♂苹果 - 眼睛想旅行
  
利用URLSchemes功能通过邮件发送“游戏关卡”的解决方案(转) - ♂苹果 - 眼睛想旅行
 
  
利用URLSchemes功能通过邮件发送“游戏关卡”的解决方案(转) - ♂苹果 - 眼睛想旅行
 
  
利用URLSchemes功能通过邮件发送“游戏关卡”的解决方案(转) - ♂苹果 - 眼睛想旅行
  
利用URLSchemes功能通过邮件发送“游戏关卡”的解决方案(转) - ♂苹果 - 眼睛想旅行
  
利用URLSchemes功能通过邮件发送“游戏关卡”的解决方案(转) - ♂苹果 - 眼睛想旅行
  
利用URLSchemes功能通过邮件发送“游戏关卡”的解决方案(转) - ♂苹果 - 眼睛想旅行
 

☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆

If you feel all the stuffs in this site helped you a lot and you would buy me a beer :)

转自:http://www.supersuraccoon-cocos2d.com/zh/2011/09/25/part-1-a-solution-to-using-urlschemes-to-send-game-level-through-e-mail/


我有一个QQ群,学开发的,可以一起学习:195949812
阅读全文
0 0
原创粉丝点击