Obje-c Conversion Help?

Hi,

I have been trying to convert this cocos2d tutorial, http://www.raywenderlich.com/352/how-to-make-a-simple-iphone-game-with-cocos2d-tutorial , to C++, so I can learn how to use this sweet Cocos2d Game Engine, but I am having trouble with using the NSMutableArray Class.

In Obj-C it says to do this,

In the header file
NSMutableArray **targets;
NSMutableArray **projectiles;

then this in the Init call:
*targets = init];
*projectiles = [[NSMutableArray alloc] init];

This is in the dealloc call:
[*targets release];
*targets = nil;
[*projectiles release];
*projectiles = nil;

This in same game logic:
target.tag = 1;
[targets addObject:target];
target.tag = 2;
;
This in a callback after an action is done:
if { // target
;
} else if { // projectile
;
}
This is how I converted it:
In My class:
NSMutableArray<CCSprite
>targets;
NSMutableArray<CCSprite
> *projectiles;
I don’t have the init call, is there one, or is the constructor good enough?
In the game logic:
target~~>setTag;
targets.addObject;
projectile~~>setTag;
*projectiles.addObject(projectile);

My destructor:
*targets.removeAllObjects;
*targets = NULL;

*projectiles.removeAllObjects;
*projectiles = NULL;

In the callback after an action is done:

if(sprite->getTag() 1)
{
targets.removeObject(sprite);
}
else
{
projectiles.removeObject(sprite);
}

The code crashes in the removeObject at:
if (*iter pObject)

Am I not converting this correctly, NSMutableArray is new to me, since I don’t know Obj-C that well?

Any help will be greatly appreciated.

Thanks in advance.

NSMutableArray is written based on std::vector.
It very important that you mustn’t add or remove elements in the traversal of std::vector, or it will crash.
Instead, in the first traversal, you can add the elements to delete into a new vector. Then in the second traversal of this new vector, delete the elements of your target vector.

The update function in Cocos2dSimpleGame/HelloWorldScene.cpp translated just like this

void HelloWorld::update(ccTime dt)
{
    NSMutableArray *projectilesToDelete = new NSMutableArray;
    NSMutableArray::NSMutableArrayIterator it, jt;

    for (it = _projectiles->begin(); it != _projectiles->end(); it++)
    {
        CCSprite *projectile = *it;

        CGRect projectileRect = CGRectMake(projectile->getPosition().x - (projectile->getContentSize().width/2),
                        projectile->getPosition().y - (projectile->getContentSize().height/2),
                        projectile->getContentSize().width,
                        projectile->getContentSize().height);

        NSMutableArray *targetsToDelete = new NSMutableArray;

        for (jt = _targets->begin(); jt != _targets->end(); jt++)
        {
            CCSprite *target = *jt;

            CGRect targetRect = CGRectMake(target->getPosition().x - (target->getContentSize().width/2),
                            target->getPosition().y - (target->getContentSize().height/2),
                            target->getContentSize().width,
                            target->getContentSize().height);

            if (CGRect::CGRectIntersectsRect(projectileRect, targetRect))
            {
                targetsToDelete->addObject(target);
            }
        }


        for (jt = targetsToDelete->begin(); jt != targetsToDelete->end(); jt++)
        {
            CCSprite *target = *jt;

            _targets->removeObject(target);
            this->removeChild(target, true);
            _projectilesDestroyed++;

            if (_projectilesDestroyed > 30)
            {
                GameOverScene *gameOverScene = GameOverScene::node();
                gameOverScene->getLayer()->getLabel()->setString("You Win!");
                CCDirector::sharedDirector()->replaceScene(gameOverScene);
            }
        }

        if (targetsToDelete->count() > 0)
        {
            projectilesToDelete->addObject(projectile);
        }
        targetsToDelete->release();
    }

    for (it = projectilesToDelete->begin(); it != projectilesToDelete->end(); it++)
    {
        CCSprite* projectile = *it;

        _projectiles->removeObject(projectile);
        this->removeChild(projectile, true);
    }
    projectilesToDelete->release();
}

In fact, I have translated Cocos2dSimpleGame to c++, the most of game logic is done.
But it can only run on uphone by now. I would like to publish after make it multi-platform, on iphone & android. It takes more work to do.
Please give me your email address, I would send this semi-finished Cocos2dSimple sources to you.

Thanks for the help. I see what you mean by traversing through one vector list and deleting off the other vector list. My e-mail address is bumbastard-at-yahoo-dot-com

Again thanks for the help

I have sent email to you.
The cocosDenshion for iphone-cpp haven’t ready yet. So I still can’t port this game onto cocos2d-iphone-cpp completely.

ps. I modify the email addr in your post, to prevent junks

@Walzer

Thanks for the e-mail with your cpp conversion code in it. It turned out that I wasn’t converting the setup of the actions correctly.

I had for adding a target:

// Create the actions
CCIntervalAction actionMove;
actionMove = CCMoveTo::actionWithDuration.width/2, actualY));
CCCallFuncN
actionMoveDone;
actionMoveDone = CCCallFuncN::actionWithTarget(target, callfuncN_selector(HelloWorld::spriteMoveFinished));
target~~>runAction);
You had this for adding a target:
CCFiniteTimeAction actionMove = CCMoveTo::actionWithDurationactualDuration, ccp.width/2, actualY));
CCFiniteTimeAction
actionMoveDone = CCCallFuncN::actionWithTarget);
target~~>runAction(CCSequence::actions(actionMove, actionMoveDone, NULL));

Mine would crash in the spriteMoveFinished callback on the target, when I called sprite->removeObject(target).

The call stack pointed at the end() call in the NSMutableArray class

Since I am new to cocos2d, I’m not sure what the big difference in code between mine and your version of setting up the actions and why it would cause such a crash.

Again thanks for the help. My demo isn’t crashing more :slight_smile:

I guess your crash may similar to this commit https://github.com/cocos2d/cocos2d-x/commit/fc588f58eb61784103a316194ceff5ef8833b961
It’s tiny differences between the declaration of actionMove & actionMoveDone, which will cause the c++ “polymorphism” works.
Hope this will help you to find the reason of crash.

Again thanks for the help.

So I moved onto Ray Wenderlich’s third cocos2d tutorial and I’m stuck on converting this class to C++ using the cocos2d-x

@implementation WeakAndFastMonster

+ (id)monster {

    WeakAndFastMonster *monster = nil;
    if ((monster = [[[super alloc] initWithFile:@"Target.png"] autorelease])) {
        monster.hp = 1;
        monster.minMoveDuration = 3;
        monster.maxMoveDuration = 5;
    }
    return monster;

}

@end

How do I convert this line:
if ((monster = [[[super alloc] initWithFile:@“Target.png”] autorelease]))

Thanks again, if you would like to e-mail me again, its bumbastard-at-yahoo-dot-com

I don’t know the father of WeakAndFastMonster. But it may
be write like this:

if (monster = new WeakAndFastMonster())
{
    monster = monster->initWithFile("Target.png");
    monster->autorelease();

    ....
}

Thanks that helped. I got it working.

Thanks again

For NSMutableArray<CCSprite*> _targets I get an error that ISO C++ forbids declaration of NSMutableArray with no type.
Any thoughts ?

Change the prefix, CCMutableArray<CCSprite*> must be OK