Cocos2d EXC_BAD_ACCESS [英] Cocos2d EXC_BAD_ACCESS
问题描述
我是新的cocos2d,突然得到这个EXC_BAD_ACCESS,
我做了一个新的获奖菜单,我得到错误
我认为错误是因为我调用一个释放的对象,但我不释放任何东西?
我的调试控制台没有错误,这是奇怪的
这里是我的Level_1.m
//
// Level_1.m
// iPadGame
//
// 1/25/12创建我的名字。
//版权所有2012 __MyCompanyName__。版权所有。
//
#importLevel_1.h
#importHelloWorldLayer.h
CCSprite * player;
CCSprite * enemy;
CCSprite * enemy2;
CCSprite * enemy3;
CCSprite * star;
CCSprite * star2;
CCSprite * star3;
CCSprite * bg;
CCSprite * toolBar;
CCLabelTTF * youWin;
bool movePlayer;
@implementation Level_1
@synthesize score;
+(CCScene *)scene {
//'scene'是一个自动释放对象。
CCScene * scene = [CCScene node];
//'layer'是一个autorelease对象。
Level_1 * layer = [Level_1 node];
//将图层作为子级添加到场景
[scene addChild:layer];
//返回场景
return scene;
}
- (void)setUpWinMenu {
[CCMenuItemFont setFontName:@Marker Felt];
[CCMenuItemFont setFontSize:75];
CCMenuItem * MainMenu = [CCMenuItemFont itemFromString:@Main Menutarget:self selector:@selector(gotoMainMenu)];
CCMenu * WinMenu = [CCMenu menuWithItems:MainMenu,nil];
[self addChild:WinMenu];
MainMenu.position = ccp(400,500);
}
//在init你需要初始化你的实例
- (id)init
{
//总是调用super init
// Apple建议为self重新分配super返回值
if((self = [super init]))
{
self.isTouchEnabled = YES;
scoreNumber = 10;
bg = [CCSprite spriteWithFile:@metal_background.jpeg];
bg.position = ccp(512,384);
[self addChild:bg];
toolBar = [CCSprite spriteWithFile:@ToolBar.png];
toolBar.position = ccp(512,-30);
[self addChild:toolBar];
score = [CCLabelAtlas labelWithString:@0123456789charMapFile:@ScoreFinal.pngitemWidth:50 itemHeight:75 startCharMap:'。'];
[self addChild:score];
score.position = ccp(-100,15);
CCLabelTTF * scoreLabel = [CCLabelTTF labelWithString:@Score:fontName:@Marker FeltfontSize:45];
scoreLabel.position = ccp(score.position.x + 275,score.position.y + 40);
scoreLabel.color = ccc3(0,0,0);
[self addChild:scoreLabel];
star = [CCSprite spriteWithFile:@Star.png];
star.position = ccp(400,600);
[self addChild:star];
star2 = [CCSprite spriteWithFile:@Star.png];
star2.position = ccp(600,600);
star3 = [CCSprite spriteWithFile:@Star.png];
star3.position = ccp(200,600);
player = [CCSprite spriteWithFile:@ball.png];
player.position = ccp(500,300);
[self addChild:player];
enemy = [CCSprite spriteWithFile:@SpaceShip.png];
enemy.position = ccp(150,600);
[self addChild:enemy];
enemy2 = [CCSprite spriteWithFile:@SpaceShip.png];
enemy2.position = ccp(250,600);
[self addChild:enemy2];
enemy3 = [CCSprite spriteWithFile:@SpaceShip.png];
enemy3.position = ccp(350,600);
[self addChild:enemy3];
[self schedule:@selector(enemyMove)interval:0.01];
[self schedule:@selector(collisionDetection)interval:0.01];
[self schedule:@selector(getStar)interval:0.01];
NSString * string = [NSString stringWithFormat:@Score:%i,(int)scoreNumber];
[score setString:string];
x = 15;
x2 = 15;
x3 = 15;
y = 15;
Bx = 10;
By = 10;
movePlayer = FALSE;
CCRepeatForever * repeat = [CCRepeatForever actionWithAction:[CCRotateBy actionWithDuration:2 angle:360]];
[star runAction:repeat];
star.visible = 1;
}
return self;
}
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
CGRect playerRect = CGRectMake(player.position.x - (player.contentSize.width / 2),
player.position.y - (player.contentSize.height / 2),
player.contentSize.width,
player.contentSize.height);
CGRect Tlocation = CGRectMake(location.x,location.y,10,10);
NSLog(@Touch Bean);
if(CGRectIntersectsRect(Tlocation,playerRect)){
player.position = location;
movePlayer = TRUE;
}
}
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch * myTouch = [touches anyObject];
CGPoint point = [myTouch locationInView:[myTouch view]];
point = [[CCDirector sharedDirector] convertToGL:point];
if(movePlayer == TRUE){
player.position = point;
if(player.position.y< 110){
player.position = ccp(player.position.x,111);
}
}
}
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@Touch ended);
movePlayer = FALSE;
}
- (void)enemyMove {
enemy.position = ccp(enemy.position.x + x,enemy.position.y);
enemy2.position = ccp(enemy2.position.x - x2,enemy2.position.y);
enemy3.position = ccp(enemy3.position.x + x3,enemy3.position.y);
if(enemy.position.x> 1024 || enemy.position.x< 0){
x = -x;
}
if(enemy2.position.x> 1024 || enemy2.position.x< 0){
x2 = -x2;
}
if(enemy3.position.x> 1024 || enemy3.position.x< 0){
x3 = -x3;
}
if(enemy.position.y> 768 || enemy.position.y< 120){
y = -y;
}
}
- (void)collisionDetection {
if(CGRectIntersectsRect(player.boundingBox,enemy.boundingBox)){
[self schedule:@selector(collisionAlert)];
}
if(CGRectIntersectsRect(player.boundingBox,enemy2.boundingBox)){
[self schedule:@selector(collisionAlert)];
}
if(CGRectIntersectsRect(player.boundingBox,enemy3.boundingBox)){
[self schedule:@selector(collisionAlert)];
}
}
- (void)getStar {
if(CGRectIntersectsRect(player.boundingBox,star.boundingBox)){
NSLog(@Got Star!);
scoreNumber + = 100;
NSString * string = [NSString stringWithFormat:@Score:%i,(int)scoreNumber];
[score setString:string];
[self addChild:star2];
if(star.visible == 1){
}
}
if(CGRectIntersectsRect(player.boundingBox,star2.boundingBox)){
NSLog(@Got Star!);
scoreNumber + = 100;
NSString * string = [NSString stringWithFormat:@Score:%i,(int)scoreNumber];
[score setString:string];
[self addChild:star3];
}
if(CGRectIntersectsRect(player.boundingBox,star3.boundingBox)){
youWin = [CCLabelTTF labelWithString:@You WinfontName:@Marker FeltfontSize:75];
youWin.position = ccp(500,400);
[self addChild:youWin];
[self setUpWinMenu];
NSLog(@Got Star!);
scoreNumber + = 100;
NSString * string = [NSString stringWithFormat:@Score:%i,(int)scoreNumber];
[score setString:string];
player.position = ccp(player.position.x - 10,player.position.y - 20);
[self unschedule:@selector(enemyMove)];
[self unschedule:@selector(collisionAlert)];
[self unschedule:@selector(getStar)];
}
return;
}
- (void)collisionAlert {
player.position = ccp(player.position.x - 10,player.position.y - 20);
[self unschedule:@selector(enemyMove)];
UIAlertView * dialog = [[UIAlertView alloc] init];
[dialog setDelegate:self];
[dialog setTitle:@Fail];
[dialog setMessage:@你是失败!
[dialog addButtonWithTitle:@Goto Main Menu];
[dialog addButtonWithTitle:@Retry!];
[dialog addButtonWithTitle:@不要按此按钮];
[dialog show];
[dialog release];
[self unschedule:@selector(collisionAlert)];
}
- (void)alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex == 0){
[CCDirector sharedDirector] replaceScene: [CCTransitionFlipAngular transitionWithDuration:1 scene:[HelloWorldLayer node]]];
}
if(buttonIndex == 1){
[[CCDirector sharedDirector] replaceScene:[Level_1 node]];
}
if(buttonIndex == 2){
[self schedule:@selector(noting)]; $ CC $ b}
}
- (void)gotoMainMenu {
[[CCDirector sharedDirector] replaceScene:[CCTransitionJumpZoom transitionWithDuration:1 scene:[HelloWorldLayer node]];
}
@end
所有这些对象: $ b $ b
CCSprite * player;
CCSprite * enemy;
CCSprite * enemy2;
CCSprite * enemy3;
CCSprite * star;
CCSprite * star2;
CCSprite * star3;
CCSprite * bg;
CCSprite * toolBar;正在使用autorelease方法分配
,例如 CCSprite spriteWithFile:
然后,当你访问这些对象在其他方法,像你在 ccTouchesBegan:withEvent:
它们已经释放,你得到 EXC_BAD_ACCESS
你可以做一件事来解决它,是调用 spriteWithFile:
方法后跟一个retain调用,如
toolBar = [[CCSprite spriteWithFile:@ToolBar.png] retain ];但不要忘记释放你的Level_1的类 dealloc上的保留对象。
<
(我没有在你的类中实现) - (void)dealloc {
[toolBar release];
[super dealloc]
}
I am new to cocos2d and suddenly got this EXC_BAD_ACCESS,
I made a new winning menu and i got the error
I think the error is because i called a released object, but i dont release anything?
My Debug Console had no error, which is strange
here is my Level_1.m
//
// Level_1.m
// iPadGame
//
// Created by My Name on 1/25/12.
// Copyright 2012 __MyCompanyName__. All rights reserved.
//
#import "Level_1.h"
#import "HelloWorldLayer.h"
CCSprite *player;
CCSprite *enemy;
CCSprite *enemy2;
CCSprite *enemy3;
CCSprite *star;
CCSprite *star2;
CCSprite *star3;
CCSprite *bg;
CCSprite *toolBar;
CCLabelTTF *youWin;
bool movePlayer;
@implementation Level_1
@synthesize score;
+(CCScene *) scene {
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
Level_1 *layer = [Level_1 node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
-(void) setUpWinMenu {
[CCMenuItemFont setFontName:@"Marker Felt"];
[CCMenuItemFont setFontSize:75];
CCMenuItem *MainMenu = [CCMenuItemFont itemFromString:@"Main Menu" target:self selector:@selector(gotoMainMenu)];
CCMenu *WinMenu = [CCMenu menuWithItems:MainMenu, nil];
[self addChild:WinMenu];
MainMenu.position = ccp(400,500);
}
// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init]))
{
self.isTouchEnabled = YES;
scoreNumber = 10;
bg = [CCSprite spriteWithFile:@"metal_background.jpeg"];
bg.position = ccp(512,384);
[self addChild:bg];
toolBar = [CCSprite spriteWithFile:@"ToolBar.png"];
toolBar.position = ccp(512,-30);
[self addChild:toolBar];
score = [CCLabelAtlas labelWithString:@"0123456789" charMapFile:@"ScoreFinal.png" itemWidth:50 itemHeight:75 startCharMap:'.'];
[self addChild:score];
score.position = ccp (-100,15);
CCLabelTTF *scoreLabel = [CCLabelTTF labelWithString:@"Score:" fontName:@"Marker Felt" fontSize:45];
scoreLabel.position = ccp(score.position.x + 275,score.position.y + 40);
scoreLabel.color = ccc3(0, 0, 0);
[self addChild:scoreLabel];
star = [CCSprite spriteWithFile:@"Star.png"];
star.position = ccp(400,600);
[self addChild:star];
star2 = [CCSprite spriteWithFile:@"Star.png"];
star2.position = ccp(600,600);
star3 = [CCSprite spriteWithFile:@"Star.png"];
star3.position = ccp(200,600);
player = [CCSprite spriteWithFile:@"ball.png"];
player.position = ccp(500,300);
[self addChild:player];
enemy = [CCSprite spriteWithFile:@"SpaceShip.png"];
enemy.position = ccp(150,600);
[self addChild:enemy];
enemy2 = [CCSprite spriteWithFile:@"SpaceShip.png"];
enemy2.position = ccp(250,600);
[self addChild:enemy2];
enemy3 = [CCSprite spriteWithFile:@"SpaceShip.png"];
enemy3.position = ccp(350,600);
[self addChild:enemy3];
[self schedule:@selector(enemyMove) interval:0.01];
[self schedule:@selector(collisionDetection) interval:0.01];
[self schedule:@selector(getStar) interval:0.01];
NSString *string = [NSString stringWithFormat:@"Score: %i", (int)scoreNumber];
[score setString:string];
x = 15;
x2 = 15;
x3 = 15;
y = 15;
Bx = 10;
By = 10;
movePlayer = FALSE;
CCRepeatForever *repeat = [CCRepeatForever actionWithAction: [CCRotateBy actionWithDuration:2 angle:360]];
[star runAction:repeat];
star.visible = 1;
}
return self;
}
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch* myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView: [myTouch view]];
location = [[CCDirector sharedDirector]convertToGL:location];
CGRect playerRect = CGRectMake(player.position.x - (player.contentSize.width/2),
player.position.y - (player.contentSize.height/2),
player.contentSize.width,
player.contentSize.height);
CGRect Tlocation = CGRectMake(location.x, location.y, 10, 10);
NSLog(@"Touch Began");
if (CGRectIntersectsRect (Tlocation, playerRect)) {
player.position = location;
movePlayer = TRUE;
}
}
-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *myTouch = [touches anyObject];
CGPoint point = [myTouch locationInView:[myTouch view]];
point = [[CCDirector sharedDirector] convertToGL:point];
if (movePlayer == TRUE) {
player.position = point;
if (player.position.y < 110) {
player.position = ccp(player.position.x, 111);
}
}
}
-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(@"Touch ended");
movePlayer = FALSE;
}
-(void) enemyMove {
enemy.position = ccp(enemy.position.x + x, enemy.position.y);
enemy2.position = ccp(enemy2.position.x - x2, enemy2.position.y);
enemy3.position = ccp(enemy3.position.x + x3, enemy3.position.y);
if (enemy.position.x > 1024 || enemy.position.x < 0) {
x = -x;
}
if (enemy2.position.x > 1024 || enemy2.position.x < 0) {
x2 = -x2;
}
if (enemy3.position.x > 1024 || enemy3.position.x < 0) {
x3 = -x3;
}
if (enemy.position.y > 768 || enemy.position.y < 120) {
y = -y;
}
}
-(void) collisionDetection {
if (CGRectIntersectsRect(player.boundingBox, enemy.boundingBox)) {
[self schedule:@selector(collisionAlert)];
}
if (CGRectIntersectsRect(player.boundingBox, enemy2.boundingBox)) {
[self schedule:@selector(collisionAlert)];
}
if (CGRectIntersectsRect(player.boundingBox, enemy3.boundingBox)) {
[self schedule:@selector(collisionAlert)];
}
}
-(void) getStar {
if (CGRectIntersectsRect(player.boundingBox, star.boundingBox)) {
NSLog(@"Got Star!");
scoreNumber += 100;
NSString *string = [NSString stringWithFormat:@"Score: %i", (int)scoreNumber];
[score setString:string];
[self addChild:star2];
if (star.visible == 1) {
}
}
if (CGRectIntersectsRect(player.boundingBox, star2.boundingBox)) {
NSLog(@"Got Star!");
scoreNumber += 100;
NSString *string = [NSString stringWithFormat:@"Score: %i", (int)scoreNumber];
[score setString:string];
[self addChild:star3];
}
if (CGRectIntersectsRect(player.boundingBox, star3.boundingBox)) {
youWin = [CCLabelTTF labelWithString:@"You Win" fontName:@"Marker Felt" fontSize:75];
youWin.position = ccp(500,400);
[self addChild:youWin];
[self setUpWinMenu];
NSLog(@"Got Star!");
scoreNumber += 100;
NSString *string = [NSString stringWithFormat:@"Score: %i", (int)scoreNumber];
[score setString:string];
player.position = ccp(player.position.x - 10, player.position.y - 20);
[self unschedule:@selector(enemyMove)];
[self unschedule:@selector(collisionAlert)];
[self unschedule:@selector(getStar)];
}
return;
}
-(void) collisionAlert {
player.position = ccp(player.position.x - 10, player.position.y - 20);
[self unschedule:@selector(enemyMove)];
UIAlertView* dialog = [[UIAlertView alloc] init];
[dialog setDelegate:self];
[dialog setTitle:@"Fail"];
[dialog setMessage:@"You are a Failure!"];
[dialog addButtonWithTitle:@"Goto Main Menu"];
[dialog addButtonWithTitle:@"Retry!"];
[dialog addButtonWithTitle:@"Dont push this button"];
[dialog show];
[dialog release];
[self unschedule:@selector(collisionAlert)];
}
-(void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex == 0) {
[[CCDirector sharedDirector] replaceScene:[CCTransitionFlipAngular transitionWithDuration:1 scene:[HelloWorldLayer node]]];
}
if (buttonIndex == 1) {
[[CCDirector sharedDirector] replaceScene:[Level_1 node]];
}
if (buttonIndex == 2) {
[self schedule:@selector(noting)];
}
}
-(void) gotoMainMenu {
[[CCDirector sharedDirector] replaceScene:[CCTransitionJumpZoom transitionWithDuration:1 scene:[HelloWorldLayer node]]];
}
@end
im not finished completely but there maybe a few empty methods but im sure thats not whats causing the problem
解决方案 All this objects:
CCSprite *player;
CCSprite *enemy;
CCSprite *enemy2;
CCSprite *enemy3;
CCSprite *star;
CCSprite *star2;
CCSprite *star3;
CCSprite *bg;
CCSprite *toolBar;
are being allocated with autorelease methods, such as CCSprite spriteWithFile:
and then, when you access these objects in other methods, like you do at ccTouchesBegan: withEvent:
they are already deallocated, and you get the EXC_BAD_ACCESS
One thing you can do to fix it, is to call the spriteWithFile:
method followed by a retain call, like
toolBar = [[CCSprite spriteWithFile:@"ToolBar.png"] retain];
But don't forget to release the retained objects on your Level_1's class dealloc
(which I didn't see implemented in your class)
-(void) dealloc {
[toolBar release];
[super dealloc]
}
这篇关于Cocos2d EXC_BAD_ACCESS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!