Ошибка дублирования спрайтов cocos2d - PullRequest
0 голосов
/ 24 ноября 2011

у меня есть приложение, использующее cocos2d, Я перемещаю некоторые спрайты и получаю анимацию при прикосновении, она работает нормально, пока я не загружу другой вид и не вернусь снова, затем, когда я перемещаю спрайты, некоторые случайные спрайты дублируются при перемещении,

Обратите внимание на кнопку, которая переходит в другой вид,

sketchButtonTapped

Вот часть кода,

 enum {  
easySprite =   0x0000000a,
mediumSprite = 0x0000000b,
hardSprite =   0x0000000c,
backButton =   0x0000000d,
magneticSprite = 0x0000000e,
magneticSprite2 = 0x0000000f
 };

@implementation HelloWorldLayer
@synthesize objetosDicto = _objetosDicto;
@synthesize bgMainScene = _bgMainScene;

+(CCScene *) scene
{
CCScene *scene = [CCScene node];

HelloWorldLayer *layer = [HelloWorldLayer node];

[scene addChild: layer];

return scene;
 }
-(id) init
{

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

    self.objetosDicto = [[[NSMutableDictionary alloc] init] autorelease];


    self.bgMainScene = [CCSprite spriteWithFile:@"bgnd.png"];//Background

    self.bgMainScene.anchorPoint = CGPointMake(0, 0);
    [self addChild:self.bgMainScene];

    isTouchEnabled_ = YES;

    CCMenuItem *starMenuItem = [CCMenuItemImage 
                                itemFromNormalImage:@"boton1.png" selectedImage:@"boton1Selected.png" 
                                target:self selector:@selector(starButtonTapped:)];

    starMenuItem.position = ccp(49, 299);
    CCMenu *starMenu = [CCMenu menuWithItems:starMenuItem, nil];
    starMenu.position = CGPointZero;
    [self addChild:starMenu];

    //secondo boton
    CCMenuItem *sketchV = [CCMenuItemImage itemFromNormalImage:@"sketchBoton.png" selectedImage:@"sketchBoton.png" target:self selector:@selector(sketchButtonTapped:)];

    sketchV.position = ccp(457, 160);
    CCMenu *sketchMenu = [CCMenu menuWithItems:sketchV, nil];
    sketchMenu.position = CGPointZero;
    [self addChild:sketchMenu];




    //first sprite
    TSprite *ez = [TSprite spriteWithFile:@"butonA.png"]; //lets create a TSprite, named EZ, and the file is Easy.png.
    [ez SetCanTrack:YES];//The sprite can be tracked.

    [self addChild: ez z:2 tag:easySprite]; //lets add a tag to the sprite, in order to identify it later RED
    ez.position = ccp(290,300);//position of the sprite
    [TSprite track:ez];//and lets add this sprite to the tracked array.


    //second sprite
    TSprite *med = [TSprite spriteWithFile:@"butonB.png"]; //blue
    [med SetCanTrack:YES];
    [self addChild: med z:1 tag:mediumSprite];
    med.position=ccp(299,230);
    [TSprite track:med];

    [self.objetosDicto setObject:@"299"forKey:@"hardX"]; //poner a salvar en finish toches??
    [self.objetosDicto setObject:@"160" forKey:@"hardY"]; //poner a salvar en finish toches?? 79

    //third sprite
    TSprite *har = [TSprite spriteWithFile:@"butonC.png"]; //GREEN
    [har SetCanTrack:YES];
    [self addChild: har z:3 tag:hardSprite];
    [har setPosition:ccp(299,160)];
    [TSprite track:har];

    //magnetic sprite
    TSprite *mag = [TSprite spriteWithFile:@"magnetic.png"];
    [mag SetCanTrack:YES]; //usar no! para ver que pasa!
    [self addChild:mag z:1 tag:magneticSprite];
    [mag setPosition:ccp(299, 180)];
    [TSprite track:mag];

    TSprite *mag2 = [TSprite spriteWithFile:@"magnetic.png"];
    [mag2 SetCanTrack:YES]; //usar no! para ver que pasa!
    [self addChild:mag2 z:1 tag:magneticSprite2];
    [mag2 setPosition:ccp(299, 140)];
    [TSprite track:mag2];


    [self getChildByTag:magneticSprite].visible = NO; //ojo, para aparece desaparece!
    [self getChildByTag:magneticSprite2].visible = NO; //ojo, para aparece desaparece!


}
return self;
 }


- (void)sketchButtonTapped:(id)sender {
NSLog(@"hundio");
CCTransitionRotoZoom *transition = [CCTransitionSlideInR transitionWithDuration:1.0 scene:  [SketchViewController scene]];


// Tell the director to run the transition

[[CCDirector sharedDirector] replaceScene:transition];

[tablaMenuBloq setHidden:YES];
}//sketchButtonTapped

 - (void)registerWithTouchDispatcher {
 [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];
 } 


-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{

 CGPoint location = [self convertTouchToNodeSpace:touch];

NSLog(@"locacion %f %f",location.x, location.y);


if([TSprite SomethingWasTouched:location]){     
    NSArray * mySprites = [TSprite allMySprites];
    NSUInteger i, count = [mySprites count];

    for (i = 0; i < count; i++) {
        TSprite * obj = (TSprite *)[mySprites objectAtIndex:i];

        if (CGRectContainsPoint([obj rect], location) && [obj GetCanTrack]) { 
             [obj setPosition :ccp(location.x,location.y)];//position of the spritesssss
             [self getChildByTag:magneticSprite]

            if([obj tag] == easySprite){



            }


        }
    }
}


    return TRUE;
 }
 -(void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event { 


CGPoint location = [self convertTouchToNodeSpace:touch];

 if([TSprite SomethingWasTouched:location]){        
    NSArray * mySprites = [TSprite allMySprites];
    NSUInteger i, count = [mySprites count];

    for (i = 0; i < count; i++) {
        TSprite * obj = (TSprite *)[mySprites objectAtIndex:i];

        if (CGRectContainsPoint([obj rect], location) && [obj GetCanTrack]) { 
            // code here is only executed if obj has been touched

            [obj setPosition :ccp(location.x,location.y)];//position of the spritesssss


            [self reorderChild:obj z:3]; //send layer to z front!!


            int s = [[self.objetosDicto objectForKey:@"hardY"]intValue];

            if ((location.y) < s+50) //79

            {
                [self getChildByTag:magneticSprite].visible = YES; //ojo, para aparece desaparece!
                [self getChildByTag:magneticSprite2].visible = NO; //ojo, para aparece desaparece!


                if ((location.y) < s-20)
                {
                    [self getChildByTag:magneticSprite].visible = NO; //ojo, para aparece desaparece!

                    [self getChildByTag:magneticSprite2].visible = YES; //ojo, para aparece desaparece!

                }



            }

            if ((location.y) > s+50) //79
            {
                [self getChildByTag:magneticSprite].visible = NO; //ojo, para aparece desaparece!

            }
            if ((location.y) < s-65) //79
            {
                [self getChildByTag:magneticSprite2].visible = NO; //ojo, para aparece desaparece!

            }


        }


                 }
}



 }

 -(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {



CGPoint location = [self convertTouchToNodeSpace:touch];


if([TSprite SomethingWasTouched:location]){     
    NSArray * mySprites = [TSprite allMySprites];
    NSUInteger i, count = [mySprites count];

    for (i = 0; i < count; i++) {
        TSprite * obj = (TSprite *)[mySprites objectAtIndex:i];

        if (CGRectContainsPoint([obj rect], location) && [obj GetCanTrack]) { 
            // code here is only executed if obj has been touched


            [ obj runAction:[CCMoveTo actionWithDuration:0.3 position:ccp(299, 190)]];


            if([obj tag] == easySprite){



            }


        }
    }
}


 }

  - (void) dealloc
 {

[_bgMainScene release];
[_objetosDicto release];

[super dealloc];
}
 @end

Я также использую класс TSSprite, чтобы отслеживать спрайты, но не думаете, что это создаст проблему?

1 Ответ

2 голосов
/ 24 ноября 2011

Я бы сказал, что у вашего приложения есть проблема с управлением памятью. Поскольку вы меняете представления (я полагаю, CCScenes), и дублирование происходит только после этого, исходная сцена и ее дочерние элементы, вероятно, не были полностью освобождены и теперь снова отображаются, или некоторые из ее спрайтов каким-то образом попадают в новую сцену.

Одна из вещей, которая заставляет меня сделать это предположение, это строка:

self.objetosDicto = [[[NSMutableDictionary alloc] init] autorelease];

Я предполагаю, что свойство objectosDicto установлено на сохранение, иначе вы столкнетесь с ошибками. Это делает аутрелиз полностью лишним. Это означает, что вы не полностью поняли, как работает управление памятью Objective-C. QED , род.

Есть один простой тест, который вы можете сделать, это установить точку останова в методе dealloc HelloWorldLayer. Если приложение не ломается при переключении представлений, вы пропускаете весь слой. Если это произойдет, вы должны попробовать то же самое для спрайтов, которые дублируются, и убедитесь, что они тоже все освобождены должным образом.

...