Smoke effect for rocket in sprite kit - ios

I'm designing a game and in my game, rockets are launched. I've created an emitter, gotten it configured, and when my rocket is launched, it adds the emitter to the rocket. Problem is, the rocket is moving pretty fast and it appears that the particles follow the motion of the rocket - what I mean by that is, instead of the rocket leaving a "trail" of smoke behind it, the "smoke" looks the same as if the rocket weren't moving, I guess because it is a child of the rocket.
The only workaround I've thought to my problem is to:
-Create an ivar or property to hold the current position of the rocket and update this every frame
-When rocket is launched, add child of emitter to the scene, not to the rocket
-place it's position at the position of the rocket
-on update, follow the rocket
However, this seems extremely computationally expensive, to be checking to see if a rocket exists, getting it's position if it does, creating a new CGPoint for this position, and set the emitter position to this new point on every single frame. Also, it leaves very few options for having more than one rocket on the screen at the same time.
Any other, more elegant solutions?

You need to set the targetNode property of your emitter to the SKNode or SKScene that you want the smoke to stay on. That property sets the node that the emitter particles will be children of, that way when the rocket moves, the emitted particles stay in the same place.
NOTE: The emitter itself should still be a child of the rocket.
SKEmitterNode.targetNode docs

Related

volume-based physicsBodies being moved manually not contacting edge-based physicsBody

So in my Space Invaders game, all collisions were working perfectly until I added a physics body created from a edgeChainFromPath which is a single line to represent the ground (an SKShapeNode created from 2 points). Now my invader bombs (which move via SKAction) notify when they hit the ground but my invaders (moved in update() by manually updating their positions) do not. My ship missiles (also moved by SKAction) DO notify when contacting an invader.
Question : if a physicsBody is moved manually and comes into contact with another physicsBody, is didBeginContact not called? (All physics interactions - bitMasks, delegates etc - are set correctly). I'm thinking the answer is 'No it's not' because that's the only explanation and makes sense picturing how Sprite/Kit probably works. I.e. A contact occurs when the SK engine itself moves a node and realises that it's physicsBody is being drawn on top of another physicsBody.
Edit - just realised that I have other physicsBodies in my scene that are stationary and that the invaders DO collide with, so it's not an SKAction thing. The difference might be that the new node I've added is an edge-based body belonging to an SKShapeNode, rather than a volume-based body for a SKSPriteNode, but nothing in the documentation that I can find states that this shouldn't work.
New question : Do volume-based bodies being moved manually not collide with stationary edge-based bodies?
Ok - my bad. The invaders' physicsBodies had dynamic=false. Every other sprite was dynamic, so all other collisions were working. My new shape was an edge-based body which also are dynamic=false.
Made that one change and all is Ok. I need to update my checkPhysics() routine to test for this.
Edit: I really should have seen this earlier - checkPhysics() was not printing that invader notifies when contacting ground, which I just put down to a glitch that I'd fix later. Whereas checkPhysics() deliberately doesn't report on nodes with dynamic=false. I think that when I wrote the function, I assumed that you'd set dynamic=false deliberately to not be involved in collision/contact detection. I should change it to print a warning.

SceneKit: PhysicsWorld relative to body

I have a ship that everything is centered around and everything moves relative to it. It is a first person shooter. Right now when I fire, and the ship speeds up, it catches up to the bullets. I would like the physics world to move relative to the ship's speed so that the bullet is essentially unaffected by ship speed.
The physics engine is doing the right thing, but not the right thing for my game.
I have other elements that move relative to the ship as it moves, which move correctly now, so don't want make ship stationary and move everything else in world around it. I don't see a direct way to do this maybe there is an indirect way? Perhaps I can manually take over the positioning of the bullets. I would like to use the other parts of the physics engine for doing collisions etc so don't want to completely manually do it, but will if that is the only option.
Anyone else have any suggestions?
It sounds like your bullets are receiving air friction. This is controlled by the physics bodies "damping" property. A value of 1.0 will make it static without movement. A value of 0 will allow it to move continuously without ever stoping. The default value is 0.1 as per the Apple documents. Assign your node like so to remove the damping(air friction)...
yourNode.physicsBody.damping = 0

iOS SpriteKit - creating multiple "floors"

I am trying to create a game for iOS using XCode 5 which replicates this game www.xgenstudios.com/play/castle
Basically, you press on the enemy and throw him into the air, and upon hitting the ground, he dies. But the enemy can spawn at an array of different y values so the "floor" they hit, and die from, is different depending on where they were spawned.
I'm new to spritekit development but from what I understand, the best way to program this would be:
-Create each stickman as a custom stickman node
-Create the background as a scene
-Create an invisible physics body object to act as boundary for which if they fall onto it they die
Does anyone have any suggestions for how I could implement this? If the invisible boundary they hit is one place, they will always die in the same place.
One possible solution is to not use collision detection to solve this problem. You could instead check if any StickManNodes that where in a thrown state had passed their original position during didSimulatePhysics. You might then set the Y position exactly to the startY position and trigger your death animation.

How would I build pool-cues / simplified pinball-style plungers with SpriteKit?

I'm working on a game in which the user should be able to trigger 'rods' that come out from the edge of the screen to displace elements on screen (balls). These projectiles roughly resemble pool-cues. Or perhaps pinball plungers, except that they start from the 'loaded' position (mostly offscreen), and when triggered, they eject out, then quickly retreat.
I'm unclear how I should build these with Sprite Kit.
The game uses the PhysicsEngine, and the onscreen balls should be effected both by gravity AND they should be displaced when they collide with the rods. However the rods should neither be effected by gravity, not displaced when they collide with the balls -- they should simply retreat regardless of whether they've made contact with the balls.
I realize I can set the affectedByGravity property for the rods. However because they will still displace slightly when they collide with the balls. How can I 'fix' or 'peg' them in place? Do I need to use an SKPhysicsSlidingJoint? If so, has anyone encountered any examples online? Is there a simpler way to do this?
A related physics engine, Box2D distinguishes static, kinematic, and dynamic bodies.
Kinematic bodies can move and will collide with other objects, but they are themselves not affected by dynamic bodies or forces like gravity. Thus, consider setting rod.dynamic = NO; but animate it with actions. See also here in the reference for SKPhysicsBody.

Box2D / cocos2d animation to a point with rotation

I'm pretty new to Box2D and cocos2d. I'm trying to do something which I thought would be pretty simple, but it is turning out to be more difficult than I had expected and I cannot find a working answer anywhere.
Basically, I want to move a b2body and rotate it to a certain point with animation.
I can get it to the correct position and rotation with:
targetBody->SetTransform(b2Vec2(10.0f,1.0f),10);
But I have no idea how to animate it there over time. I tried using cocos2d animation on the sprite used for the body, but that doesn't do anything. Any ideas?
There are a couple of ways you could do this.
You could use SetTransform every time step to update the position of the body gradually over time, in effect performing the animation yourself. The drawback with this method is that the body is 'teleporting' to the new position rather than moving, so it has no momentum, which means you can get odd results if it hits anything along the way. Still, if you know it will not hit anything or does not need to react to a collision this would be ok.
The other way is to SetLinearVelocity and SetAngularVelocity to give the body proper movement. This will keep the results of a collision realistic, and you don't need to keep updating anything every timestep. On the other hand, you will need to detect when the body has arrived at the desired position and then set the velocities back to zero, otherwise it will just keep moving. For dynamic bodies you will also need to counter gravity somehow, either by setting the gravity scale of the body to zero, or by applying an upwards force to balance gravity, or by changing the body type to kinematic during the move.
In general, you use Box2D to simulate the physical behavior of objects in relation to each other. The rules of mechanics implemented by Box2D dictate how your cocos2d CCSprites move if you continuously update the translation and rotation of your sprites according to their corresponding Box2d b2Body. You will have some kind of repeatedly invoked tick: method in which you step your Box2d world along in time, and in which you update your sprite positions according to simulation results of Box2d.
This pattern corresponds to b2Bodys of type b2_dynamicBody. Physical laws dictate the motion of the body in this case, and your sprites will follow these simulation results. This is why setting a conflicting position of a sprite by means of a CCAction or even directly will be undone almost instantaneously with the next tick:.
Solution 1: kinematic body type
However, there do exist other modes for a b2Body, and one of these is b2_kinematicBody in which the translation is no longer governed by the world but by the velocities or angular speeds you dictate through setters. So it would be one solution to work with body type b2_kinematicBody as in:
b2BodyDef bdef;
bdef.type = b2_kinematicBody;
With this you would manipulate the velocity and angular speed of a b2Body explicitly. In this case, Box2d is still responsible for moving bodies around, but according the velocities you dictate, and without any force effects of collision or gravity applied to this particular body. Also with this strategy, your CCSprites will follow b2Bodys. Setting conflicting positions for your sprites directly or by applying a CCAction would not make sense for the same reason as described above.
Solution 2: decouple sprites from Box2d
An alternative way to animating sprites would be to fully decouple those sprites from Box2d. In this case, you would simply not have any b2Body that governs the position of the sprite you are going to animate. Now, in this case, only you will dictate the position and rotation of your CCSprite, i.e. directly either through its position property or by applying a CCAction.

Resources