1

我已经为孩子们制作了一个非常简单的 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; 

}

任何想法错误在哪里?

更新 1:

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

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

4 回答 4

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];

希望有帮助

于 2012-04-17T14:29:32.743 回答
1

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

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--;
        }

I wonder if there is a better way than using NSPredicate but for now it works fine and does not get duplicates.

于 2012-04-17T15:52:26.770 回答
0
The game works fine most of the time but sometimes the game says "Pop the Letter R".

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

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

如果有重复,则不会设置两个气泡。

于 2012-04-17T14:14:06.430 回答
0

它真的在这里……

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

需要是

[self.parent removeChild:self.sprite cleanup:YES];
于 2012-04-17T14:40:13.317 回答