Cocos2d-x : stop Previous action - cocos2d-x

how to stop the previous action in Cococs2d-x
my sprite have continous animation in init method
and recently i launched move action
i want to stop that move action only
that repeat animation still to be there only.

For action we can set Tag using setTag method. When you don't want that action remove that using CCNode method "removeActionByTag"

Hi bit late to the party.
Another solution is to call stopAction(currentAction) before calling runAction(newAction). This enables you to stop currentActionSave before you start newAction. You will need to store the currentAction somehow, probably a member var, so you can later call stopAction(currentAction).
Heres a code example:
Dog.h
#include "cocos2d.h"
class Dog : public cocos2d::Sprite
{
public:
....
private:
....
bool OnTouchEnded(cocos2d::Touch* touch, cocos2d::Event* /*event*/)
cocos2d::Action* m_currentAction = nullptr;
};
Dog.cpp
#include "Dog.h"
....
bool Dog::OnTouchEnded(cocos2d::Touch* touch, cocos2d::Event* /*event*/)
{
using namespace cocos2d;
....
MoveTo* moveTo = MoveTo::create(time, pos);
if (m_currentAction)
{
stopAction(m_currentAction);
}
m_currentAction = runAction(moveTo);
return true;
}
Hope this helps someone.

Related

what does particleEmitter.start() method do in particle emitter class?

whether I put start() method or not my particle emitter runs the same way, So what is the use of start() method.
If you look at the source code of ParticleEffect class and then look at the start method, you will see this -
public void start () {
for (int i = 0, n = emitters.size; i < n; i++)
emitters.get(i).start();
}
Basically, this means it is going through all the emitters and calling ParticleEmitter#start method.
Now let's look into the start method of ParticleEmitter.
public void start () {
firstUpdate = true;
allowCompletion = false;
restart();
}
Basically from the method, you can see that its setting the firstUpdate boolean to true which means "this is the first update" i.e. we will be doing something for the first time (look into the source code to see where the boolean is used)
The next line, it is setting allowCompletion to false which means, if the emitter was already in progress, don't let it complete (Check source code to see where the boolean is used)
The final call is to restart() which is self-explanatory (restarting this emitter if it was already running.)
I hope that helped.

libgdx - wait to complete an action of an actor

My problem is I want an actor to do an action (in this case a fade) and just after the end of the action, switch to the game screen. But the action is finished not complete, but quickly changed the game screen.
I want to wait to complete this action before changing the screen .. And in general, I wonder how I can make waiting instructions in the game, because it is sometimes good to want to allow some time before anything happens.
myActor.addAction(Actions.fadeIn(2));
setScreen(AnotherScreen);
Use the static imports for actions, way easier.
import static com.badlogic.gdx.scenes.scene2d.actions.Actions.*;
Actor.addAction(sequence(fadeOut(2f), run(new Runnable() {
public void run () {
System.out.println("Action complete!");
}
});
Put the code you want to run in the runnable.
For more info,
https://github.com/libgdx/libgdx/wiki/Scene2d#actions
What you have to do is create an Action subclass and override Action#act where you will call setScreen(AnotherScreen);.
Then, use Actions#sequence to wrap both actions into a single SequenceAction object.
Action switchScreenAction = new Action(){
#Override
public boolean act(float delta){
setScreen(AnotherScreen);
return true;
}
};
myActor.addAction(Actions.sequence(
Actions.fadeIn(2)
, switchScreenAction
));
For more info, check out: https://github.com/libgdx/libgdx/wiki/Scene2d#complex-actions

update function of Component not called anymore

The update function of Component is not called anymore in Cocos2dx v3 while it was called fine in v2.x
I noticed the CCScheduler is completely different in both versions and that Node::update in v2 is called from CCScheduler::update function but in v3 it is called from Scene::update - which is never called.
Anybody have an idea what is the best way to migrate this from v2 to v3.
My code is as follows
In game scene
layerMoveLeft = ParallaxNode::create();
layerMoveLeft->addComponent(new MoveLeft() );
this->addChild(layerMoveLeft);
In MoveLeft class -
class MoveLeft : public Component
...
void MoveLeft::onEnter()
{
log("- MoveLeft::onEnter");
}
void MoveLeft::update(float delta) {
log("- MoveLeft::update");
}
The update function in v3 is never called
in V 3+ you can call update method on Node class using ScheduleUpdate() function call.
virtual void update(float dt);
I don't know why you want Component class in V 3.0
Make the following changes and i hope that it will work.
MoveLeft.h
void update(float delta);
MoveLeft.cpp
this->scheduleUpdate();
You can add the above code anywhere you want in the class (preferably in the init() method)
Now create the function as you did before:
void MoveLeft::update(float delta) {
log("- MoveLeft::update");
}
P.S: I haven't used it with Component, i have used it with Layer.
class Quizzes: public cocos2d::Layer{
public:
virtual bool init();
}
in V 3+, you can add code above to class parent of component.
this->scheduleUpdate();

cocos2d-x-3.0 draw vs onDraw

I'm using cocos2d-x v3.0 and in some test project I'm doing some custom drawing by overriding Node's draw method, but in the DrawPrimitives example provided they do something like this:
void DrawPrimitivesTest::draw()
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(DrawPrimitivesTest::onDraw, this);
Director::getInstance()->getRenderer()->addCommand(&_customCommand);
}
void DrawPrimitivesTest::onDraw()
{
// drawing code here, why?
}
From reading the header and source files it seems like this may be some way of sending render commands straight to the renderer, is that correct?
Should I be using this method to do custom drawing? What's the difference between draw an onDraw?
EDIT:
As #Pedro Soares mentioned, since Cocos2D-X 3.0 you can't override draw() anymore. you have to use draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) instead.
There is sample on cocos2d-x RC0 package that shows how to use the DrawPrimitives on top of other layers.
On your Layer .h add the following:
private:
void onDrawPrimitives(const kmMat4 &transform, bool transformUpdated);
CustomCommand _customCommand;
Now in the cpp of the Layer, override the layer draw method and include the onDrawPrimitives method:
void MyLayer::onDrawPrimitives(const kmMat4 &transform, bool transformUpdated)
{
kmGLPushMatrix();
kmGLLoadMatrix(&transform);
//add your primitive drawing code here
DrawPrimitives::drawLine(ccp(0,0), ccp(100, 100));
}
void MyLayer::draw(Renderer *renderer, const kmMat4& transform, bool transformUpdated)
{
_customCommand.init(_globalZOrder);
_customCommand.func = CC_CALLBACK_0(MyLayer::onDrawPrimitives, this, transform, transformUpdated);
renderer->addCommand(&_customCommand);
}
In future, cocos2d-x 3.x renderer will be multithreaded with command pool.
draw method called by visit method, to create new command. When command is performed by command pool, onDraw is called. At this moment, commands are performed in single thread, but in overloaded onDraw method you should assume, that it will be called in another thread to simplify future migration.
I use draw method for debugDraw Like this It may be helpful
void HelloWorld::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
Layer::draw(renderer, transform, flags);
Director* director = Director::getInstance();
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION );
director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
world->DrawDebugData();
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}
The draw() expression should be the same as the base class function.
The draw method of Node for cocos 3.3rc is:
virtual void draw(Renderer *renderer, const Mat4& transform, uint32_t flags);

function new or public static main

I am new to Haxe and probably this is a pretty basic question, which I can't really find an answer.
I see three ways to call main class:
1) use main()
//Entry point
public static main():void{
//do something...
}
2) use constructor new()
//Constructor
public function new(){
// init
}
3) use both main() and new()
static function main()
{
Lib.window.onload = function(e) new Main();
}
public function new()
{
//init
}
Is there a guideline or best practice to which one to use?
Thanks
Addressing all 3:
static function main() {} is the correct entry point. No matter which target, Haxe always begins execution at main().
The new() constructor isn't called automatically, if you want your main app to execute as an object rather than from a static function, you have to explicitly create the object: static function main() { new Main(); }
Some people prefer to keep their code in an object, rather than in static functions, which is where your 3rd example comes from. I usually do, and that's what you show in your 3rd example.
A few extra points:
The steps things are executed is explained here, basic summary:
All types/classes are registered
Boot.__init() runs platform specific initializations
Classes which have static function __init__() initialization methods are initialized
Static variables are intiailzed
Your main() function is executed
If you compile a class without a -main Main argument, but with the class path/name as an argument (eg haxe my.pack.MyClass) and with no public static function main(), the class is compiled, but it is not run automatically. This can be useful if you are creating a library or something similar - your class is there, but it needs to be called explicitly by some other Javascript etc.
In Javascript, the Haxe code starts running as soon as it is loaded, possibly before the DOM is ready. That is why it is a good idea to do:
static function main() {
js.Lib.window.onload = function(e) { runMyApp(); }
}
As you did in your example, this is a good idea if you want your code to run after the DOM is ready. Whether on load you call another static function, or instantiate a new MyApp() and run your app from there, that is up to you.