我的Cocos2d游戏中的奇怪错误

时间:2012-04-17 14:05:40

标签: cocos2d-iphone

我为孩子们做了一个非常简单的Cocos2d教育游戏。游戏向用户显示带有字母或数字的气泡,并且语音告诉用户弹出特定的字母或字母。游戏大部分时间都可以正常运行,但有时游戏会说“Pop the Letter R”。然后当你尝试触摸并弹出时它不会弹出。这种情况发生在10%的时间,这使我无法将应用程序提交到应用商店。我不确定我在哪里失踪。

选择随机字母或数字的方法:

以下代码中的选项可以是NSMutableArray,其中包含从A到Z的字母。

-(void) populateRandomBubbles:(NSMutableArray *) options 
{
    int randomNumber;
    int randomBubbleColor; 
    NSString *option = @"";

    for(int i=0;i<self.gamePlaySettings.noOfBubblesToDisplay;i++) 
    {
        randomNumber = arc4random() % options.count; 
        randomBubbleColor = arc4random() % self.bubbleColors.count; 
        option = [options objectAtIndex:randomNumber];

        CGPoint point = [self getRandomPointOnScreen]; 

        // add first bubble 
        Bubble *bubble = [[Bubble alloc] initWithColor:[self getRandomBubbleColor]];
        bubble.delegate = self; 
        bubble.text = option; 
        bubble.soundFile = [[option stringByAppendingPathExtension:@"caf"] lowercaseString];
        bubble.sprite.position = point; 

        bubble.tag = [option characterAtIndex:0];

        [bubble setStringForLabel:bubble.text];

        if([self getChildByTag:bubble.tag] == nil)
        {
            if(  (int) (self.bubbles.count) < self.gamePlaySettings.noOfBubblesToDisplay)
            {
                [self.bubbles addObject:bubble];
            }
        }
        else 
        {
            i--;
        }
    }

    // set the randomly selected alphabet 

    randomNumber = arc4random() % self.bubbles.count; 

    Bubble *bubble = [self.bubbles objectAtIndex:randomNumber];
    bubble.isSelected = YES;

    // play sound 
    [self.environment playSoundByFileName:bubble.soundFile];

}

Bubble类定义如下:

@implementation Bubble

@synthesize soundFile,text,isSelected,color,label,delegate = _delegate;

-(id) initWithColor:(NSString *)bubbleFile
{
    self = [super init];
    self.sprite = [CCSprite spriteWithFile:bubbleFile];
    [self addChild:self.sprite];
    return self; 
}

-(void) pop
{

    CCParticleExplosion *explosion = [[CCParticleExplosion alloc] init];
    explosion.position = self.sprite.position;
    [explosion setAutoRemoveOnFinish:YES];
    [self.parent addChild:explosion];
    [self.parent removeChild:self cleanup:YES];

    Environment *environment = [[Environment alloc] init]; 
    [environment playPopSound];
}

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {

    if([self containsTouchLocation:touch]) 
    {   
        // if this is the correct bubble then pop the bubble 

        if(self.isSelected) 
        {

            [self pop];
            [_delegate onBubblePop:self];

        }
        return YES;
    }

    return NO; 
}

BaseNode定义如下:

@implementation BaseNode

@synthesize sprite;

-(void) onEnter
{
    [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
    [super onEnter];
}

-(void) onExit
{
    [[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
    [super onExit];
}

- (CGRect)rect
{
    CGSize s = [self.sprite.texture contentSize];
    return CGRectMake(-s.width / 2, -s.height / 2, s.width, s.height);
}

- (BOOL)containsTouchLocation:(UITouch *)touch
{
    BOOL isCollided = CGRectContainsPoint([self.sprite boundingBox], [self convertTouchToNodeSpace:touch]);

    return isCollided; 

}

任何有关bug的想法?

更新1:

以下代码也粘贴在原始文件中,确保没有重复项。它似乎工作正常,因为我从未遇到任何重复。

 if([self getChildByTag:bubble.tag] == nil)
        {
            if(  (int) (self.bubbles.count) < self.gamePlaySettings.noOfBubblesToDisplay)
            {
                [self.bubbles addObject:bubble];
            }
        }

4 个答案:

答案 0 :(得分:1)

尝试使用此选项以确保您没有任何重复

int length = [YOURBUBBLEARRAY count];
NSMutableArray *indexes = [[NSMutableArray alloc] initWithCapacity:length];
for (int i=0; i<length; i++) [indexes addObject:[NSNumber numberWithInt:i]];
NSMutableArray *shuffle = [[NSMutableArray alloc] initWithCapacity:length];
while ([indexes count])
{
    int index = rand()%[indexes count];
    [shuffle addObject:[YOURBUBBLEARRAY objectAtIndex:index]];
    [indexes removeObjectAtIndex:index];
}
[indexes release];

Bubble *bubble = [shuffle objectAtIndex:randomNumber];

希望有所帮助

答案 1 :(得分:1)

我可能已经解决了这个问题。我认为问题在于我从未进行过检查以确保bubbles集合中的对象是唯一的。更新后的代码如下:

NSArray *bubbleAlreadyInArray = [self.bubbles filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"tag == %d",bubble.tag]];


        if([self getChildByTag:bubble.tag] == nil)
        {
            if(  (int) (self.bubbles.count) < self.gamePlaySettings.noOfBubblesToDisplay)
            {
                // only add to the bubbles array if not already added!
                if(bubbleAlreadyInArray.count == 0)
                {
                [self.bubbles addObject:bubble];
                }
            }
        }
        else 
        {
            i--;
        }

我想知道是否有比使用NSPredicate更好的方法但是现在它工作正常并且没有重复。

答案 2 :(得分:0)

The game works fine most of the time but sometimes the game says "Pop the Letter R".

问题是......你弹出正确的字母吗?您的代码中没有任何内容可以避免使用重复项。屏幕上可能同时有两个r,按下其中一个不会触发另一个。

Bubble *bubble = [self.bubbles objectAtIndex:randomNumber];
如果有重复,

不会设置两个气泡。

答案 3 :(得分:0)

它实际上就在这里......

[self.parent removeChild:self cleanup:YES];

需要

[self.parent removeChild:self.sprite cleanup:YES];