I'm trying to do what I did hundred of times with cocos2d, but with cocos2d-x seems I have less luck.
If i do
CCsequence *squence = CCSequence::create(someAction1, someAction2, NULL);
the compiler says:
No matching function for call to 'create'
I've found this problem around the internet but without any solution. By the way, if I do a simple action like:
CCAction *action = CCMoveTo::create(5.0f, CCPointMake(0,0));
sprite->runAction(action);
the action is not even called, and the sprite is not nil (I've printed his size etc), printing info about that sprite it is the exact object it should be
Try this:
CCFiniteTimeAction *action = CCMoveTo::create(x, (y,z));
CCsequence *squence = CCSequence::create(action, NULL);
I think the error is because CCSequence expects CCFiniteTimeAction classes but you're declaring them as CCAction which makes the compiler think you're passing the wrong type, complaining that there is no create function that takes CCAction as parameters.
You can try like this
CCMoveBy *action = CCMoveBy::create(.5, CCPointMake(ball->getPositionX(), ball->getPositionY()+100));
CCMoveBy* action_back = (CCMoveBy*)action->reverse();
ball->runAction(CCSequence::create(action, action_back, NULL));
ball is sprite
Related
Okay, so I want my cat sprite to move up and down onClick of two (UP and DOWN) buttons.
I'm a beginner in cocos2d-x.
So, in mygame.h i have a global declaration of the sprite cat:
cocos2d::Sprite *cat;
In one function i create a new scene and add a cat in it.
cat = Sprite::create("cat.png");
cat->setScale(0.2);
cat->setPosition(0, 190);//(Director::getInstance()->getVisibleOrigin().x + 50, Director::getInstance()->getVisibleSize().height / 2);
layer->addChild(cat);
playscene->addChild(cat);
In another function(button callback) i have this code:
void HelloWorld::down(Object* pSender){
CCActionInterval* down = CCMoveBy::create(1.0f, Point(0.0, -20.0));
cat->runAction(down);
}
And everything's ok untill i press the up or down button.
It throws an error on the cat->runAction(down); line.
When i exemine the variable cat, it looks like I cant get to the position parameters. Its a memory read error..
In cocos2dx 3.0
you can write direct in runaction for any sprite.
spriteName->runAction(Sequence::create(MoveBy::create(1.0f,Point(398,565)),NULL));
It looks like you are mixing Cocos2D-X 2.x API's with Cocos2D-X 3.0 ones. I'm taking a stab in the dark guess and saying it looks like you're trying to use 3.0. You will need to change the following line:
CCActionInterval* down = CCMoveBy::create(1.0f, Point(0.0, -20.0));
To:
ActionInterval* down = MoveBy::create(1.0f, Point(0.0, -20.0));
I'm trying to schedule selectors with CCCallFunc but the selector isn't getting called.
This works:
[self launchCreature];
This does not:
id launchCreatureAction = [CCCallFunc actionWithTarget:self selector:#selector(launchCreature)];
[self runAction:launchCreatureAction];
launchCreature is defined in the parent class, and the CCCallFunc works when used in the parent class. Nothing is showing up in the debugger when I run the action; it just doesn't run the code. (It never hits the breakpoint I have defined at the first line of launchCreature.)
Am I missing about something about how to use CCCallFunc, or how self works in subclasses?
Edit: I misremembered how my code is set up. launchCreature and the code above are BOTH defined in the parent class. The difference between working and not working is that it worked in an instance of the parent class, but doesn't work in an instance of the subclass. This no longer seems to work in the parent class either. Sorry for the confusion.
It works for me. You could try making a call to [super launchCreature] in [self launchCreature] in the subclass and see if the break point is being hit.
Could someone help me, I am trying to access a CCLabelTTF that resides in a CCLayer subclass(GameLayer), but I want to access it from another Player class(also a CCLayer). I thought
[self getChildByTag: DEBUG_LABEL];
searches the scene and finds the object that matches it and returns a pointer to it, since all objects are stored in a tree data structure.
I was able to access the label through trial and error using the follwing code but would appreciate if someone could advise if I am not understanding the getChildByTag method or if there is a way of searching the scene for an object without using the code below.
CCLabelTTF *lbl = (CCLabelTTF *)[[[[CCDirector sharedDirector] runningScene] getChildByTag: GAME_LAYER_TAG] getChildByTag: DEBUG_LABEL_TAG];
Please advise.
getChildByTag only checks direct children of the parent CCNode calling it. It will not check children's children (grandchildren, if you will).
For example, if your node hierarchy looks like this:
MyCCLayer1->MyCCLayer2->MyCCSprite->MyCCLabel
Calling MyCCLayer1 only has direct access to MyCCLayer2 via the getChildByTag call. In turn, MyCCLayer2 could call getChildByTag to get MyCCSprite, and then MyCCSprite could call getChildByTag to get MyCCLabel.
I am using Cocos2d 2.1rc0.
I have this project that was working perfectly when I was not using CCSpriteBatchNode. Then I decided to use batch nodes to reduce draw calls and my problems started.
A lot of stuff is not working well. reorderChild is one. Another one is runAction and without runAction Cocos is useless.
This is an example of a method that works without batchNodes and do not work with it.
// move/rotate all objects
for (int i=0; i<[allObjects count]; i++) {
Card *object = [allObjects objectAtIndex:i];
[object stopAllActions];
CGPoint center = object.position;
center.x = center.x + 100;
center.y = center.y - 200;
CCMoveTo *moveAction = [CCMoveTo actionWithDuration:0.3f position:ccp(center.x, center.y)];
CCRotateTo *rotateAction = [CCRotateTo actionWithDuration:0.3 angle:0.0f];
CCSpawn *action = [CCSpawn actions:moveAction, rotateAction, nil];
[object runAction:[CCSequence actions: action,
[CCDelayTime actionWithDuration:0.1f],
nil]];
}
Exactly nothing happens.
I have tried to eliminate the CCSpanw and use runAction directly just with move and nothing works. If I use regular sprites, it works.
Objects in that array derive from a CCSprite based class.
Is there any workaround?
the solution is to cast the class to the object extracted from the array...
instead of
Card *object = [allObjects objectAtIndex:i];
this
Card *object = (Card *)[allObjects objectAtIndex:i];
After double-checking in a clean project that this isn't a weird side-effect of some kind, I have to say there's something fishy about your project. Hard to tell what, though.
What I did: create a sprite-batch, add a sprite to it, also store it in an array. In a scheduled method I'm receiving the sprite from the array (not casting) and run your action sequence posted above. It works fine, as expected.
The casting should not make any difference. Batched or non-batched sprite should not make any difference either.
If it does, something really weird is going on. After all the card object is the same with or without casting. If it were not actually running the runAction method, you'd be receiving an "unrecognized selector sent to instance" error. But that's not the case.
Try again without casting, after rebooting your device, your machine, cleaning the project in Xcode and rebuilding. Also test in debug and release configurations. I've had the weirdest issues that were gone after doing one of the above, and definitely all of the above. If that doesn't fix things, you can be sure it's a problem with the code (memory leak is my alltime favorite) or the project settings (ie uncommon compiler optimizations sometimes can have side-effects).
Step into the runAction method if it really doesn't run the action - I'm sure it will add the action to the action manager. Try with and without casting to see if there really is a different code path taken. I doubt it.
I'm using Cocos2d to write game for iPhone.
Here's the problem.
I have CCSprite and CCAction which is run on it.
CCSprite texture;
CCAction anim_action;
"Anim_action" is a CCRepeatForever action.
Now I want to check if this animation is running.
First I though I can use [isDone] function, but I think it doesn't work on CCRepatForever actions (I'm not sure - this opion is based on my tests)
So how to check if this animation is already running on my "texture"?
Maybe there is a way to get name of action which is running on texture at the moment?
It may be also useful!
There is a way to check if a specific action runs on your texture. Use:
CCAction *action = [texture getActionByTag:kAsignedActionTag];
where kAsignedActionTag is the tag assigned to the your animation.
anim_action.tag = kAsignedActionTag;
If your action is still running the getActionByTag method will not return nil.
I don't believe there's a way to directly tell if a CCRepeatForever action has completed since the isDone would make no sense, but there are some techniques you can use to essentially provide a callback to indicate if something is still running:
Override the step: method and call out to something that checks the interval - when it exceeds a threshold you can assume completion...kinda'
Wrap the inner action of the CCRepeatForever with a CCSequence. The first action of the sequence would be your repeated action and the second would be a CCCalFunc, again indicating that the action is still running
Subclass the CCRepeatForever and override the dealloc so you can fire a callback when the action is killed and released
You can easily use [isDone] while appling an effect
- (void)shakeThatThingOn: (BOOL)on { //you can return BOOL and get if the animation is working or not
if (on == YES){
id shaky2 = [CCShaky3D actionWithRange:3 shakeZ:NO grid:ccg(15,10) duration:5];
if (![shaky2 isDone])
[self runAction:[CCSequence actions:shaky2,[CCStopGrid action],nil]];
}
else {//this else is being called when you turn off animation (it's just 0.2s continuation after turning off - for better visual effect.
[self stopAllActions];
id shaky2 = [CCShaky3D actionWithRange:3 shakeZ:NO grid:ccg(15,10) duration:0.2];
[self runAction:[CCSequence actions:shaky2,[CCStopGrid action],nil]];
}}
and control it by simple BOOL if it's on or off.
I don't know if it's what you mean, but hope it'll help anyway.
If you know how many actions will be running on the sprite, or if the animation is the only action, then you can infer that the animation is running by checking the sprite's total number of running actions.
if ([texture numberOfRunningActions] > 0) //animation is running
or
if ([texture numberOfRunningActions] > someNumber) //if you had other actions running