我为孩子们做了一个非常简单的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];
}
}
答案 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];