Проект Cocos2d падает при вызове метода в Init: - PullRequest
0 голосов
/ 17 июля 2011

Я пытаюсь поэкспериментировать с cocos2d, создав простую карточную игру. Я не новичок в разработке под iOS, но я очень новичок в движке cocos2d. У меня есть 2 пользовательских класса:

Класс карты: .h

#import <Foundation/Foundation.h>
#import "cocos2d.h"

@interface Card : NSObject {
CCSprite *faceSprite;
NSString *suit;
NSUInteger value;
float priority;
}

@property (nonatomic, retain) CCSprite *faceSprite;
@property (nonatomic, readonly) NSString *suit;
@property (nonatomic, readonly) NSUInteger value;
@property (nonatomic, assign) float priority;

- (id)initWithSprite:(CCSprite *)paramSprite suit:(NSString *)paramSuit andValue:(NSUInteger)paramValue;

@end

.m

#import "Card.h"

@implementation Card
@synthesize faceSprite, suit, value, priority;

- (id)init
{
self = [self initWithSprite:nil suit:nil andValue:nil];
if (self) {
    // Initialization code here.
}

return self;
}

-(id)initWithSprite:(CCSprite *)paramSprite suit:(NSString *)paramSuit andValue:(NSUInteger)paramValue {
if ((self = [super init])) {
    faceSprite = paramSprite;
    suit = paramSuit;
    value = paramValue;
}

return  self;
}

@end

И класс Deck: .h

#import <Foundation/Foundation.h>
#import "Card.h"

@interface Deck : NSObject {
NSMutableArray *cardsArray;
}
@property (nonatomic, retain) NSMutableArray *cardsArray;

-(void)shuffle;
-(Card *)drawTopCard;

@end

.m

- (id)init
{
if ((self = [super init])) {
    cardsArray = [[NSMutableArray alloc] init];
    for (NSInteger suit = 1; suit < 5; suit++) {
        NSString *suitString;
        switch (suit) {
            case 1:
                suitString = @"h";
                break;
            case 2:
                suitString = @"d";
                break;
            case 3:
                suitString = @"s";
                break;
            case 4:
                suitString = @"c";
                break;
        }
        for (NSInteger i = 3; i < 14; i++) {
            CCSprite *cardImage = [CCSprite spriteWithFile:[NSString stringWithFormat:@"%d%@.gif",i, suitString]];
            Card *card = [[Card alloc] initWithSprite:cardImage suit:suitString andValue:i];
            [cardsArray addObject:card];
        }

    }
}

return self;
}

-(void)shuffle {
int timesToShuffle = 1;
while (++timesToShuffle < 4) {
    for (int i = 0; i < [cardsArray count]; i++) {
        int cardToSwap = arc4random() % [cardsArray count];
        [cardsArray exchangeObjectAtIndex:i withObjectAtIndex:cardToSwap];
    }
}

}

-(Card *)drawTopCard {
Card *cardDrawn = [[cardsArray objectAtIndex:0] retain];
//[cardsArray removeObjectAtIndex:0];
return cardDrawn;
}

@end

Когда я пытаюсь сделать следующее в моей основной сцене, я получаю ошибку EXC_BAD_ACCESS внутри CCScheduler.m в обновлении: (ccTime) метод

-(id) init
{
if( (self=[super init])) {

    deck = [[Deck alloc] init];
    [deck shuffle];
    [self schedule:@selector(drawAndShowCard) interval:3.0];

}
return self;
}

-(void)drawAndShowCard {
// ask director the the window size
CGSize size = [[CCDirector sharedDirector] winSize];

// position the label on the center of the screen
Card *card = [deck drawTopCard];
CCSprite *cardSprite = (CCSprite *)card.faceSprite;
cardSprite.position =  ccp( size.width /2 , size.height/2 );

[self addChild:cardSprite];
}

Странно, что если я переместу init и колоду размещения колоды в методе drawCardAndShow, он больше не падает, однако это не подходящее место для этого по ЯВНЫМ причинам, поскольку я не хочу каждый раз совершенно новую колоду Я рисую карту ...

любая помощь?

Ответы [ 2 ]

2 голосов
/ 17 июля 2011

Я вижу одну серьезную проблему, но у вас есть несколько проблем с вашим кодом.

Если у вас есть строки в качестве свойств, вы должны объявить их как копию, в вашем случае это будет присвоить:

@property (nonatomic, readonly) NSString *suit;

Если вы хотите объявить свойство только для чтения, вы можете еще раз объявить свойство внутри вашего .m, чтобы сделать его доступным для внутренней записи:

@interface Card() 
@property (nonatomic, copy)
NSString *suit; 
@end

Вы должны использовать нотацию self. для свойствсообщайте другим о своем намерении при доступе к ivar и при доступе к свойству.

Вы получили утечку памяти здесь:

Card *card = [[Card alloc] initWithSprite:cardImage suit:suitString andValue:i];
            [cardsArray addObject:card];
-->missing [card release]

Это здесь не нужно

@interface Deck : NSObject {
NSMutableArray *cardsArray;
}
@property (nonatomic, retain) NSMutableArray *cardsArray;

Вы можете опустить ivar, просто убедитесь, что вы не выделяете / init без авто-релиза.

Если вы настаиваете на переименовании ivar по крайней мере на _cardsArray, а затем

@synthesize cardsArray=_cardsArray

так что вы можете различить два.В одном случае вам нужно явно указать сохранение, в другом вы используете метод установки / получения.

hth

1 голос
/ 17 июля 2011

вы должны установить колоду как свойство

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...