PopStar - Elimination

  • MoseHas
    Likes 0

    Problem Description

    Hi there.

    I have succeeded eliminating single brick by clicking it. Now I want to try mass elimination about same color bricks nearby.

    My pseudocode is:

    	...
    	auto listener(onTouchBegan)
    	...
    }
    
    bool onTouchBegan(Touch* touch, Event *event)
    {
    	find the coordinates(x,y) where I clicked
    	eliminate(x,y);
    	return true;
    }
    
    void eliminate(x,y)
    {
    	middleBrick=brick(x,y);
    	if(upperBrick's color==middleBrick's color)
    		eliminate(upperBrick.x,upperBrick.y);
    	if(lowerBrick's color==middleBrick's color)
    		eliminate(lowerBrick.x,lowerBrick.y);
    	if(leftBrick's color==middleBrick's color)
    		eliminate(leftBrick.x,leftBrick.y);
    	if(rightBrick's color==middleBrick's color)
    		eliminate(rightBrick.x,rightBrick.y);
    
    	remove(middleBrick);
    }

    It looks simple and workable, but there are some questions.

     

    1. Now I use vector to store the bricks and give them an individual tag so that I can remove them by tag. But if I need to decide whether the brick nearby has the same color as the middle one, I do not know how to do it. Can I assign the  color attribution to a vector object? Or perhaps I should create a new class and store color, tag, etc for every brick? I have tried this->getChildByTag()->getName() comparison but it did not work. Maybe it is wrong comparison? 

    2. SIGSEGV happened. I believe it is because when it tried to traverse up/down/left/right, the brick has been removed and then comparison failed. Is there any good method that I can easily avoid these mistakes?

    Thank you very much!


  • MoseHas
    Likes 0

    I tried to create a new class for the bricks, but I failed to create Sprites.

    	std::vector<Brick*> _vMySprites;
    	_vMySprites.reserve(100); // allocate 100 memory area for brick sprites
    	Brick* brick = new Brick;
    	
    	int i, j;
    	srand(time(NULL));
    	
    	for (i = 0; i <ROW_NUMBER; i++)
    	{
    		for (j = 0; j <COLUMN_NUMBER; j++)
    		{
    			int random = rand() % 5;
    			
    			switch (random)
    			{
    			case 0:
    				brick->brickSprite = Sprite::create("stars/blue.png");
    				brick->bColor = BLUE;
    				CCLOG("BLUE");
    				break;
    			case 1:
    				brick->brickSprite = Sprite::create("stars/green.png");
    				brick->bColor = GREEN;
    				CCLOG("GREEN");
    				break;
    			case 2:
    				brick->brickSprite = Sprite::create("stars/purple.png");
    				brick->bColor = PURPLE;
    				CCLOG("PURPLE");
    				break;
    			case 3:
    				brick->brickSprite = Sprite::create("stars/red.png");
    				brick->bColor = RED;
    				CCLOG("RED");
    				break;
    			case 4:
    				brick->brickSprite = Sprite::create("stars/yellow.png");
    				brick->bColor = YELLOW;
    				CCLOG("YELLOW");
    				break;
    			default:
    				break;
    			}
    			brick->coosX = j;
    			brick->coosY = i;
    			
    			float XForSetPosition = visibleSize.width / 2 + origin.x - ((4.5 - j) * brick->getContentSize().width);
    			float YForSetPosition = brick->getContentSize().height * (i + 0.5) + origin.y + 100;
    			brick->setPosition(cocos2d::Point(XForSetPosition, YForSetPosition));
    			brick->setTag(i * 10 + j);
    
    			_vMySprites.push_back(brick); // add our sprite to vector for storage.
    
    			addChild(brick, 1);
    		}
    	}

    The error message is:

    Run-Time Check Failure #3 - The variable 'brick' is being used without being initialized.

    Still thinking.


  • Sonar Systems admin
    Likes 0

    Try getting rid of 

    	_vMySprites.reserve(100); // allocate 100 memory area for brick sprites
    
     

    This reply has been verified.
  • MoseHas
    Likes 0

    When I checked the usage of vector, they said that although vector is a dynamic array, we should still assign its capacity due to the overheading.

    I remember my professor has told me the same thing. 

     

    I feel I give up my own algorithm a little bit. I found someone else’s code on GitHub and I am studying it now.

    Lots of Lambda expression drive me crazy!

  • Sonar Systems admin
    Likes 0

    OK, keep us informed


    This reply has been verified.
  • MoseHas
    Likes 0

    Seems that I have discovered the reason.

    It is about retain() , autoRelease(), and release().

    The document said if we new a sprite instead of create() one. we should autorelease().

    CCSprite* CCSprite::create(const char *pszFileName)    
    {    
        CCSprite *pobSprite = new CCSprite();    
        if (pobSprite && pobSprite->initWithFile(pszFileName))    
        {    
            pobSprite->autorelease();    
            return pobSprite;    
        }    
        CC_SAFE_DELETE(pobSprite);    
        return NULL;    
    }   

    create() will new a sprite and call autorelease() automatically. Therefore, if we do not autorelease, cocos2d will not retain() it and detect the unused sprite. Then release its memory. That is why it crashed.


    This reply has been verified.
  • Sonar Systems admin
    Likes 0

    Is it working?

Login to reply