cocos2d/cocos2d-x stopping particle system gracefully - cocos2d-iphone

Is there a way to stop a particle system gracefully -- ie. I call stop, and the particles dissipate naturally, no new particles are generated.

I use ParticleSystemQuad. So, to stop particles emitting, I set
particle->stopSystem();
particle->setAutoRemoveOnFinish(true);
It stops the particle emission and then, after disappearing last particle, auto removes particle system.

You can also set Visible false Or Remove from parant
ParticleSystemQuad *m_emitter=ParticleSystemQuad::create(ch);
m_emitter->setVisible(true);
this->addChild(m_emitter,50);
m_emitter->setPosition(100,100);
m_emitter->setVisible(false);
Or
m_emitter->runAction(Sequence::create(DelayTime::create(3.0),RemoveSelf::create(), NULL));

Related

OpenGL Precompute Vertices/Matrices for Particle System / Optimization

I have a particle system which I want to make as really fast as possible without any effects on the main display function, I basically placed all particles calculations on a separate infinite thread which I keep synchronized with WaitForEvent() (Windows), DataLock flags, etc.
I use glColorPointer, glNormalPointer, glVertexPointer etc to point to the buffered data on the GPU (glGenBuffers, glBufferData) and then glDrawElements to render them.
At the moment I don't have the code so I hope that won't be a problem but I'll try my best to get the infrastructure described:
Main [Init]
Create a pre-calc queue 30% in size of N particles and do sequential calculations (Thread 1 #2)
Thread 1
Wait for Calculate Event signal or if pre-calc queue is not full then continue
Loop through N particles and update position / velocity, storing it in pUpdate
If pre-calc queue is not full, add pUpdate to it
Main [Render]
glActiveTexture(TEXTURE0)
glCol/glNorm/glTex/glVertexPointer
If pre-calc is empty use the most recent pUpdate
OR use one of the pre-calc and delete
Store item in buffer using glBufferSubData()
DrawElements() to draw them
SwapBuffers
The problem is that the Render function uses about 50 pre-calc per second (which speeds up rendering while there are enough left) before 1 could even be added. In short order the pre-calc is empty so everything slows down and the program reverts to Main-Render #3
Any ideas?

Tile-based Movement and Animation

I am currently working on a demo, just to get to grips of how to make a game. It might turn into something in the future, but for now, it's just for learning.
My demo is, I guess, influenced by The Legend of Zelda. It has that top-down look that TLoZ has.
My sprite is a 32x32 pixel image, the demo runs at 60fps and I have already worked out how fast I want my sprite to animate using PyxelEdit. Each animation frame is being displayed every 170ms when my character walks. He moves 4 pixels every frame, so he is moving and animating at the speed I want him to.
The problem I have got is that I want my character to finish the animation loop when my key has been released and he won't. When I have released a movement key, he will sometimes stop on the wrong animation frame, like say his left or right foot is forward when I want him to be still. I'm just not sure how to do it. I've tried checking the animation count when the Event::KeyReleased event occurs and incrementing the animation count until it reaches a certain number so that it stops on say the number 1 so he's standing still, it just doesn't work.
I don't think this requires a look at my code, just need a general idea on how to go about making sure that when the a movement key is released, animate him until he is on frame 1 and move him a certain amount of pixels each time until he stops.
You could use a FSM so something along the lines of.
// Visual states of the character.
enum class State { WALKING, STANDING, ATTACK, };
State character_state = State::STANDING;
// Change on input (or other things like impact.)
if(input.up() || input.down() || input.left() || input.right)
character_state = State::WALKING;
else
character_state = State::STANDING;
// Render based on the current state.
switch(character_state)
{
case(State::WALKING):
render(cycle_walk_animation(frame_time));
break;
case(State::STANDING):
render(standing_still_frame());
break;
}
I've done this with 2D and 3D.
If I understand correctly, you need something like this:
// The game loop
while (game_running)
{
// ...
// Your code
// ...
// Advance the animation while moving, or if not, cycle through
// the animation frames until frame 1 is reached
if (keyPressed(somekey) || currentAnimationFrame != 1)
{
advanceAnimationFrame();
}
// ...
// Your code
// ...
}
Of course, this is not SFML code, but it should get the general idea across

Fire event when reach certain angle in revolute joint

I need to develop cannon game using box2d and cocos2dx. Cannon is divided into two parts
Base which is fixed in the ground and doesn't move.
b2WeldJointDef basePlatformWeldJointDef;
basePlatformWeldJointDef.Initialize(base->getBody(), weaponPlatform->getBody(),weaponPlatform->getBody()->GetWorldCenter());
basePlatformWeldJointDef.collideConnected = false;
basePlatformWeldJoint = m_world->CreateJoint(&basePlatformWeldJointDef);
Arm which is fixed in the base with a RevoluteJoint.
b2RevoluteJointDef armJointDef;
armJointDef.Initialize(base->getBody(), arm->getBody(), m_loader->pointsToMeters(ccp(armPosition.x-(arm->getContentSize().width*WeaponScale/4),armPosition.y)));
armJointDef.enableMotor = true;
armJointDef.enableLimit = true;
armJointDef.motorSpeed = 0;
armJointDef.lowerAngle = CC_DEGREES_TO_RADIANS(0);
armJointDef.upperAngle = CC_DEGREES_TO_RADIANS(0);
armJointDef.maxMotorTorque = 2;
armJointDef.collideConnected = false;
cannonRevoluteJoint = (b2RevoluteJoint*)m_world->CreateJoint(&armJointDef);
The cannon should calculate the angle that will fire to, and this is calculated correctly. Using the revolutJointObject->setLimits(lowerAngle, higherAngle) here i use the lowerAngle and the higherAngle both are the desired angle so the arm moves to desired angle directly without motion.
Then i needed to move the arm not just change its angle, so i set the lowerAngle and higherAngle with the old angle and desired angle depending which will be the lower and the which will the higher, and changed the motor speed of the RevoluteJoint
The problem is that i need a callback method which fires when the revolute joint reaches to a certain angle or when the motor speed reaches Zero assuming that when the arm reaches the limit angle will stop and the motor speed will be Zero.
I have searching in SO and i found This Solution which calculates the angle each step, this can be used but it needs more calculations that i feel lazy to do.
Does the callback method for notifying motor speed or certain angle has been reached exists ?
Schedule a function to check your conditions on each frame. When you don't need the checks any more - unschedule the selector, then reschedule when needed again.
As far as I know there are no callbacks for your exact task.
All a callback would do behind the scenes is check the angle each frame and then call the callback function when the joint angle is within a certain range.
There's no built in callbacks for this use case. You could make your own to hide what's going on, or you could just put the if statement in the update function. The performance of this will be fine.

Crash on Particle Effects

I try to add some particle effects at end of game. in device it worked fine. and in simulator it crashes. i attached the screenshot regarding crash.
it says getting image failed. My Particle str path is firework.plist
in debug its shows correct path.
but i got this error Get data from file(Images/FinishEffect/particleTexture.png) failed!
why its taking wrong path
check screnshot here :- http://postimg.org/image/k97ql9z59/
My code:-
CCParticleSystem *emitter;
char particleStr[64];
sprintf(particleStr,PARTICLE_EFFECT_FINISH_GAME_SCENE);
emitter = CCParticleSystemQuad::create(particleStr);
emitter->setScale(ScreenHelper::getTextureScale());
emitter->setPosition(ccp((m_StartPos.x*PTM_RATIO+RandomInt(-100,100))*ScreenHelper::getCameraZoom(),(m_StartPos.y*PTM_RATIO+RandomInt(-50,150))*ScreenHelper::getCameraZoom())); // setting emitter position
m_ccLayer->getParent()->addChild(emitter,10); // adding the emitter
In this line crash occurs only in simulator. emitter = CCParticleSystemQuad::create(particleStr);
If you check your Firework.plist file you will notice that it has textureFileName. It tells the particle engine which texture to use for your particles. Cocos requires this to work, because it doesn't "draw" the particles itself, it rather uses the provided texture and applies color to it - that's why it generally should be white, but color textures can be used to obtain different results.

C++ Projectile Trajectory

I am using OpenGL to create the 3D space.
I have a spaceship which can fire lasers.
Up until now I have had it so that the lasers will simply to deeper into the Z-axis once fired.
But I am attempting to make a proper aiming system with crosshairs so that you can aim and shoot in any direction, but I have not been successfull in trying to update the laser's path.
I have a directional vector based off the lasers end tip and start tip, which is gotten from the aiming.
How should I update the laser's X,Y,Z values (or vectors) properly so that it looks natural?
I think I see.
Let's say you start with the aiming direction as a 3D vector, call it "aimDir". Then in your update loop add all 3 (x, y and z) to the projectile "position". (OK, at the speed of light you wouldn't actually see any movement, but I think I see what you're going for here).
void OnUpdate( float deltaT )
{
// "move" the laser in the aiming direction, scaled by the amount of time elapsed
// since our last update (you probably want another scale factor here to control
// how "fast" the laser appears to move)
Vector3 deltaLaser = deltaT * aimDir; // calc 3d offset for this frame
laserEndpoint += deltaLaser; // add it to the end of the laser
}
then in the render routine draw the laser from the firing point to the new endpoint:
void OnRender()
{
glBegin(GL_LINES);
glVertex3f( gunPos.x, gunPos.Y, gunPos.z );
glVertex3f( laserEndPoint.x, laserEndPoint.y, laserEndPoint.z );
glEnd();
}
I'm taking some liberties because I don't know if you're using glut, sdl or what. But I'm sure you have at least an update function and a render function.
Warning, just drawing a line from the gun to the end of the laser might be disappointing visually, but it will be a critical reference for adding better effects (particle systems, bloom filter, etc.). A quick improvement might be to make the front of the laser (line) a bright color and the back black. And/or make multiple lines like a machine gun. Feel free to experiment ;-)
Also, if the source of the laser is directly in front of the viewer you will just see a dot! So you may want to cheat a bit and fire from just below or to the right of the viewer and then have in fire slightly up or in. Especially if you have one one each side (wing?) that appear to converge as in conventional machine guns.
Hope that's helpful.