2012-11-17 3 views
0

튜토리얼을 따라 약간의 게임을 만들었습니다. 게임은 다음과 같이 작동합니다. 특수 물고기를 컨트롤합니다. 적의 물고기가 주위에 생기고 목표는 다른 물고기를 먹는 것입니다.XCode Cocos2d EXC_BAD_ACCESS 오류

내 문제는 모든 물고기를 어떤 순서로 먹어도되고 싶다는 것입니다. 지금은 마지막에 산란 된 적 물고기 만 먹을 수 있습니다.

물고기를 잘못 주문하면 EXC_BAD_ACCESS 코드 = 1 오류로 작동이 중단됩니다.

몇 시간 동안 고치려했지만 시도 할 수 없었습니다.

여기 내 코드입니다 :

@implementation HelloWorldLayer 
NSMutableArray *_targets; 
bool ScheduleVerification=NO; 
NSMutableArray *ArraySides; 

-(id) init 
{ 
// always call "super" init 
// Apple recommends to re-assign "self" with the "super's" return value 
if((self=[super init])) { 
    CGSize winSize = [[CCDirector sharedDirector] winSize]; 
    player = [CCSprite spriteWithFile:@"Fish1.png" 
              rect:CGRectMake(0, 0, 15, 15)]; 
    NSLog(@"//Init//"); 
    _targets=[[NSMutableArray alloc] init]; 
    [self schedule:@selector(update:)]; 
    [self schedule:@selector(tracks:) interval:1]; 
    self.isTouchEnabled = YES; 
    CCSprite *background = [CCSprite spriteWithFile:@"UnderwaterBackground.png"]; 
    background.position = ccp(winSize.width/2, winSize.height/2); 
    CGSize BBox=[background boundingBox].size; 
    [background setScaleX:(winSize.width)/BBox.width]; 
[background setScaleY:(winSize.height)/BBox.height]; 
    player.position = ccp(winSize.width/2, winSize.height/2); 
    [self addChild:background]; 
    [self addChild:player]; 
} 
return self; 
} 
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 
NSLog(@"CB1"); 
UITouch *touch=[touches anyObject]; 
CGPoint location=[touch locationInView:[touch view]]; 
location=[[CCDirector sharedDirector]convertToGL:location]; 
if (location.x<player.position.x){[player setFlipX:YES];} 
if (location.x>=player.position.x){[player setFlipX:NO];} 

[player runAction:[CCSequence actions: 
       [CCMoveTo actionWithDuration:1.5 position:location], 
       nil]]; 
} 
-(void)spriteMoveFinished:(id)sender { 
    NSLog(@"CLEANUP"); 
CCSprite *sprite = (CCSprite *)sender; 


    [_targets removeObject:sprite]; 
    [self removeChild:sprite cleanup:YES]; 

} 
-(void)addTarget { 
NSLog(@"//addTarget//"); 
CCSprite *target = [CCSprite spriteWithFile:@"BadFish1.png" 
             rect:CGRectMake(0, 0, 15, 15)]; 

// Determine where to spawn the target along the Y axis 
CGSize winSize = [[CCDirector sharedDirector] winSize]; 
int minY = target.contentSize.height/2; 
int maxY = winSize.height - target.contentSize.height/2; 
int rangeY = maxY - minY; 
int actualY = (arc4random() % rangeY) + minY; 
target.tag = 1; 
[_targets addObject:target]; 

int ranSides=arc4random()%2; 

int actualSide=winSize.width; 
if (ranSides==0){actualSide=0;} 

target.position = ccp(actualSide, actualY); 
[self addChild:target]; 
NSLog(@"TARGET %@",target); 


// Create the actions 
id actionMove = [CCMoveTo actionWithDuration:15 
            position:ccp(winSize.width, actualY)]; 
if (ranSides==1){actionMove = [CCMoveTo actionWithDuration:15 
                position:ccp(0, actualY)]; 
    [target setFlipX:YES]; 

} 

id actionMoveDone = [CCCallFuncN actionWithTarget:self 
             selector:@selector(spriteMoveFinished:)]; 
[target runAction:[CCSequence actions:actionMove, actionMoveDone, nil]]; 

} 
-(void)gameLogic:(ccTime)dt { 
NSLog(@"CB2"); 
[self addTarget]; 
ScheduleVerification=NO; 

} 

-(void)tracks:(ccTime)dt { 
NSLog(@"CB3"); 
int FishInterval=arc4random()%7+3; 
// [self cleanup]; 

if (ScheduleVerification==NO){[self schedule:@selector(gameLogic:) interval:1 repeat:0 delay: FishInterval];} 
ScheduleVerification=YES; 
} 

- (void)update:(ccTime)dt { 

// NSMutableArray *playerToDelete = [[NSMutableArray alloc] init]; 
//NSMutableArray *targetsToDelete = [[NSMutableArray alloc] init]; 
    CGRect playerRect = CGRectMake(
             player.position.x - (player.contentSize.width/2), 
             player.position.y - (player.contentSize.height/2), 
             player.contentSize.width, 
             player.contentSize.height); 

       for (CCSprite *target in _targets) { 
     CGRect targetRect = CGRectMake(
             target.position.x - (target.contentSize.width/2), 
             target.position.y - (target.contentSize.height/2), 
             target.contentSize.width, 
             target.contentSize.height); 

     if (CGRectIntersectsRect(targetRect, playerRect)) { 
     [_targets removeObject:target];[self removeChild:target cleanup:YES]; 
// [targetsToDelete addObject:target]; 
     } 
     } 
} 
- (void) dealloc 
{ 
NSLog(@"DEALLOC"); 
[_targets release]; 
_targets = nil; 
[super dealloc]; 
} 

과 .H 파일에

:

@interface HelloWorldLayer : CCLayerColor 
{ 
CCSprite *player; 

} 

내가 어떤 순서로 물고기를 먹을 수 있도록 어떻게해야합니까? 내가 도대체 ​​뭘 잘못하고있는 겁니까?

답변

2

당신은 당신이 그것을 반복하면서 배열에서 요소를 제거하는 가증스러운 범죄를 저지르고있다.

형식 코드 조금 더 나은, 그리고 그것을보고 :

for (CCSprite *target in _targets) { 
    CGRect targetRect = CGRectMake(
     target.position.x - (target.contentSize.width/2), 
     target.position.y - (target.contentSize.height/2), 
     target.contentSize.width, 
     target.contentSize.height); 
    if (CGRectIntersectsRect(targetRect, playerRect)) { 
     [targetsToDelete addObject:target]; 
    } 
    if (targetsToDelete.count > 0) { 
     NSLog(@"Target Deleted"); 
     NSLog(@"targets %@",_targets); 
     NSLog(@"target %@",target); 
     [_targets removeObject:target]; 
     [self removeChild:target cleanup:YES]; 
    } 
} 
당신이 targetsToDelete을 가지고 있다는 사실은 (중 사전의 고려 또는 그 다음 튜토리얼에 의해), 그것은 할 의도 나에게 제안

이걸 제대로. 그러나 두 가지 일이 잘못되었습니다. 당신은 다음 indivudually 제거,

for (CCSprite *target in _targets) { 
    CGRect targetRect = CGRectMake(
     target.position.x - (target.contentSize.width/2), 
     target.position.y - (target.contentSize.height/2), 
     target.contentSize.width, 
     target.contentSize.height); 
    if (CGRectIntersectsRect(targetRect, playerRect)) { 
     [targetsToDelete addObject:target]; 
    } 
} 

for(CCSprite* target in targetsToDelete) { 
    NSLog(@"Target Deleted"); 
    NSLog(@"targets %@",_targets); 
    NSLog(@"target %@",target); 
    [_targets removeObject:target]; 
    [self removeChild:target cleanup:YES]; 
} 

[targetsToDelete removeAllObjects]; 

이제 _targets를 통해 실행, 당신은 _targets을 반복 완료 후 각이 한 당신이 targetsToDelete에 먹은 및 을 추가

이것이 고려하십시오.

+0

고마워요! 나는 그것을 몰랐다, 지금 큰 일을하고있다! – JMC17

+0

문제 없습니다. 데려 갈 교훈은, 더 간결한 코드는 디버그하기가 훨씬 쉽다는 것입니다. :) –

0

히트를 확인하는 루프가 매우 특이한 것처럼 보입니다. 왜 targetsToDelete에 항목을 추가하고 있습니까? targetsToDelete의 최종 릴리스가 문제 일 수 있다고 생각합니다. 이 같은 루프를 단순화하고 (미주리에 있지 맥의 앞에) 어떻게되는지 : -

- (void)update:(ccTime)dt { 
// NSMutableArray *playerToDelete = [[NSMutableArray alloc] init]; 
NSMutableArray *targetsToDelete = [[NSMutableArray alloc] init]; 
    CGRect playerRect = CGRectMake(
             player.position.x - (player.contentSize.width/2), 
             player.position.y - (player.contentSize.height/2), 
             player.contentSize.width, 
             player.contentSize.height); 

       for (CCSprite *target in _targets) { 
     CGRect targetRect = CGRectMake(
             target.position.x - (target.contentSize.width/2), 
             target.position.y - (target.contentSize.height/2), 
             target.contentSize.width, 
             target.contentSize.height); 

     if (CGRectIntersectsRect(targetRect, playerRect)) { 



       // [targetsToDelete addObject:target]; 
        NSLog(@"Target Deleted"); 
        NSLog(@"targets %@",_targets); 
        NSLog(@"target %@",target); 

        [_targets removeObject:target];[self removeChild:target cleanup:YES]; 

       } 

} 
+0

아니요. 불행히도 아무 것도 바뀌지 않았습니다. 그것은 깨끗하지만 나는 마지막으로 산란되지 않은 물고기를 먹을 때 여전히 충돌합니다. – JMC17

+0

스택 트레이스를 게시하면 어떤 라인이 충돌합니까? – IrishDubGuy

관련 문제