本地高分报告/显示

时间:2012-02-04 18:30:59

标签: iphone objective-c ios xcode cocos2d-iphone

请有人推荐我参考教程或帮助我解决这个问题。我希望在游戏结束时显示高分和其他游戏统计数据但我似乎没有取得进展尽管看了教程和尝试的东西。我似乎不明白如何使用NSUserdefaults来实现这一目标。

我的代码如下:

Gameplaylayer.mm

- (id)initWithHUDLayer:(HUDLayer *)hudLayer {
    if ((self = [super init])) 
    {
        score = 0;
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSDictionary *defaultArray = [NSDictionary dictionaryWithObject:[NSArray arrayWithObjects:[NSNumber numberWithInt:0],
                                                                        [NSNumber numberWithInt:0],
                                                                        [NSNumber numberWithInt:0],
                                                                        [NSNumber numberWithInt:0],
                                                                        [NSNumber numberWithInt:0],
                                                                        nil]
                                                                forKey:@"Scores"];
        [defaults registerDefaults:defaultArray];
        [defaults synchronize];
    }

    return self;
}


-(void)gameOver:(id)sender{

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    NSMutableArray *HighScores = [NSMutableArray arrayWithArray:[defaults arrayForKey:@"Scores"]];

    for (unsigned int i = 0; i < [HighScores count]; i++)
    {
        if (dist >= [[HighScores objectAtIndex:i] intValue])
        {
            [HighScores insertObject:[NSNumber numberWithInt:dist] atIndex:i];
            [HighScores removeLastObject];

            [defaults setObject:HighScores forKey:@"Scores"];
            [defaults synchronize];

            NSLog(@"Saved new high score of %i", dist);
            break;
        }
    }
}

-(void)update:(ccTime)dt {

    CGSize winSize = [CCDirector sharedDirector].winSize;

    score += (int)delta;
    dist = score - 18;

    if (!gameOver ) 
    {
        if (!lives)
        {
            gameOver = true;
            [self gameOver];    
        }
    }
}

我的游戏层如下

-(id)init {
    self = [super init];
    if (self != nil) 
    {
        self.isTouchEnabled = YES;

        CGSize windowSize = [CCDirector sharedDirector].winSize;

        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

        NSArray *HighScores = [defaults arrayForKey:@"Scores"];

        CLabelTTF *title = [CCLabelTTF labelWithString:@"high scores" fontName:@"Courier" fontSize:32.0];

        [title setPosition:ccp(screenSize.width / 2, screenSize.height - title.contentSize.height)];

        [self addChild:title];

        NSMutableString *scoresString = [NSMutableString stringWithString:@""];

        for (unsigned int i = 0; i < [HighScores count]; i++)
        {
            [scoresString appendFormat:@"%i. %i\n", i + 1, [[HighScores objectAtIndex:i] intValue]];
        }

        CCLOG(@"scores saved %i", dist);

        CCLabelTTF *scoresLabel = [CCLabelTTF labelWithString:scoresString dimensions:CGSizeMake(screenSize.width, screenSize.height / 3) alignment:CCTextAlignmentCenter fontName:@"Courier" fontSize:40.0];

        [scoresLabel setPosition:ccp(screenSize.width / 2, screenSize.height / 2)];

        scoresLabel.color = ccc3(0, 0, 0);
        [self addChild:scoresLabel z:9];
    }
    return self;
}

2 个答案:

答案 0 :(得分:0)

您的代码存在许多问题,其中一些问题只是违反惯例,但它们共同使您的程序难以理解。我无法理解它。您没有使用评论,也没有告诉我们,究竟什么不起作用。

例如,您可以考虑遵循以下规则:将实例变量以小写字母开头,为类保留大写的名称。提供误导性名称通常是一个坏主意,例如调用NSDictinoary“defaultArray”。此外,尝试更谨慎地使用空行来构造代码以提高可读性。

话虽如此,这就是你设置默认值的方式:

[[NSUserDefaults standardUserDefaults] setValue:scoreArray 
                                         forKey:@"Score"];

我知道如何检索分数。

至于你的更新程序,考虑通常不是一个好主意修改迭代的数组(在你的特定情况下,它仍然可以工作,但不能保证)。此外,不需要将整个数组存储在循环中。一旦你构建了完整的新高分数组,就可以保存它。

否则您的代码正常运行,对吧?

答案 1 :(得分:0)

很难理解你的代码,请看下面这个小例子。

好的,假设你有GameController单例,其中声明了scores可变数组,并且该单例中的currentScore也显示当前玩家的分数,那就节省了新分数。

-(void) saveScores {

    GameController * controller = [GameController sharedController];

    for(int i=0; i<5;i++)
    {
        if([[[controller.scores objectAtIndex:i] objectForKey:@"score"] intValue] == controller.finalscore)
        {
            break;
        }
        if([[[controller.scores objectAtIndex:i] objectForKey:@"score"] intValue] < controller.finalscore) {
            for(int j=5;j>i+1;j--) 
            {
                [controller.scores replaceObjectAtIndex:j-1 withObject:[controller.scores objectAtIndex:j-2]];
            }

            NSMutableDictionary *newEntry = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:controller.finalscore],@"score",@"Local player",@"name", nil];
            [controller.scores replaceObjectAtIndex:i withObject:newEntry];
            break;
        }
    }
    controller.currentScore=0;

    [[NSUserDefaults standardUserDefaults] setObject:controller.scores forKey:@"OurScores"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

您可以看到,我们正在NSUserDefaults中保存更新的分数。所以,在我们的游戏开始时,我们应该加载它们。我将此代码添加到GameController init方法:

- (void) loadScores {
    if([[NSUserDefaults standardUserDefaults] objectForKey:@"OurScores"] == nil) 
    {
        NSMutableDictionary *empty = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:0],@"score",@"empty",@"name", nil];
        for(int i=0;i<5;i++)
            [scores addObject:empty];
    } 
    else 
    {
        NSLog(@"Loading scores");
        scores = [[NSUserDefaults standardUserDefaults] objectForKey:@"OurScores"];
    }
}

这就是我们如何使用cocos2d显示这些分数:

-(void) drawScores {
    for(int i=0; i<5; i++)
    {
        CCLabelTTF* score = [CCLabelTTF labelWithString:
                             [NSString stringWithFormat:@"%@",[[controller.scores objectAtIndex:i] objectForKey:@"name"]] fontName:@"Marker Felt" fontSize:30];
        score.anchorPoint=ccp(0,0);
        score.position = ccp(115, 180-i*35);

        CCLabelTTF* score2 = [CCLabelTTF labelWithString:
                              [NSString stringWithFormat:@"%d",[[[controller.scores objectAtIndex:i] objectForKey:@"score"] intValue] ] fontName:@"Marker Felt" fontSize:35];
        score2.anchorPoint=ccp(0,0);
        score2.position = ccp(280, 180-i*35);

        score.color=currentClr;
        score2.color=currentClr;

        [self addChild: score z:3 tag:i];
        [self addChild: score2 z:3 tag:i+15];
    }
}