[英]XCode Cocos2d EXC_BAD_ACCESS error
我按照教程進行了一個小游戲。 游戲的工作方式如下,你控制一條特殊的魚; 敵人的魚類產生了周圍,目標是吃其他魚類。
我的問題是,我希望能夠以任何順序吃任何魚。 現在我只能吃最后產生的敵人魚。
當我嘗試以錯誤的順序吃魚時,它會因EXC_BAD_ACCESS code = 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;
}
我該怎么辦才能以任何順序吃魚? 我究竟做錯了什么?
您正在犯下令人發指的罪行,在迭代時從數組中刪除元素。
將代碼格式化得更好,並查看它:
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
這一事實向我建議(無論是通過預見還是你所遵循的教程),它都是為了正確地做到這一點。 但是有些事情出了問題。
考慮一下:
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
,將每一個添加到你已經吃掉到targetsToDelete
,並在完成迭代_targets
,然后單獨刪除它們。
你檢查命中的循環看起來非常奇怪。 為什么要向targetsToDelete添加項目? 我認為targetsToDelete的最終版本可能就是問題所在。 像這樣簡化循環,看看會發生什么(不是在Mac的前面): -
- (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];
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.