cocos2d复制sprites bug

时间:2011-11-24 11:39:56

标签: ios cocos2d-iphone sprite

我有一个使用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 个答案:

答案 0 :(得分:2)

我会说你的应用程序存在内存管理问题。由于您正在更改视图(我认为是CCScenes)并且复制仅在此之后发生,因此原始场景及其子项可能未完全取消分配并且现在再次显示,或者其某些精灵以某种方式进入新场景。

导致我做出这个假设的一个原因是这一行:

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

我假设objectosDicto属性设置为retain,否则你会遇到崩溃。这使得自动释放完全是多余的。这意味着您尚未完全接受Objective-C内存管理的工作原理。 QED,等等。

您可以执行一个简单的测试,即在HelloWorldLayer dealloc方法中设置断点。如果应用程序在切换视图时没有中断,则会泄漏整个图层。如果是这样的话,你应该为重复的精灵尝试相同的操作,并确保它们都被正确地解除分配。