子供向けの非常にシンプルな Cocos2d 教育ゲームの作成が完了しました。このゲームでは、ユーザーが文字または数字でバブルし、特定の文字またはアルファベットをポップするようにユーザーに指示する音声が表示されます。ほとんどの場合、ゲームは問題なく動作しますが、「Pop the Letter R」と表示されることがあります。そして、タッチしてポップしようとしても、ポップしません。これは 10% の確率で発生し、アプリをアプリ ストアに送信できません。どこが欠けているのかよくわかりません。
ランダムなアルファベットまたは数字を選択する方法:
以下のコードのオプションは、A から Z までのアルファベットで構成される NSMutableArray にすることができます。
-(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];
}
}