SKSpriteKit how to control Impulse or Force speed? - ios

Hi guys i want to apply slow motion in upward direction,
what i am confused, when i applyimpulse
[self.physicsBody applyImpulse:CGVectorMake(0, 60)];
it does applyimpulse with required speed as it measure from its velocity mass and other physics things
what i need to applyImpulse but with controlling speed of impluse that is applied on object on which impulse is being applied.
i tried to set even self.speed but got no success,
how one can achieve desired impluse or Force on an sprite with controlling over speed.
are there some properties that should i set for the SKSpriteNode before applying Impulse,
or some thing else?
Any suggestion or thoughts will be appreciated
Thanks

The speed property of SKNode is to do with SKActions, however the speed property of SKPhysicsWorld is what you probably want to tweak to achieve physics in slow motion.
It says the following in the documentation about the speed property of SKPhysicsWorld
The default value is 1.0, which means the simulation runs at normal speed. A value other than the default changes the rate at which time passes in the physics simulation. For example, a speed value of 2.0 indicates that time in the physics simulation passes twice as fast as the scene’s simulation time. A value of 0.0 pauses the physics simulation.
Access it from within your SKScene subclass like this-
self.physicsWorld.speed = 0.5; // half speed (slow motion)

All forces are applied as actual physics forces on physics bodies.
The resulting movement of the body that had the force applied to it depends on not just the magnitude and direction of the force but also the size and density (i.e. mass) of the body the force is being applied to and where on the body the force is applied.
I'm not entirely sure what you mean when you say you need "controlling speed of impulse" though.
Maybe what you need is not to use forces at all but to move the node manually.
You could use an action [SKAction moveByX:y:] or update the position in the update method. This way you can control the speed of the movement exactly.

Related

SpriteKit - how do I apply a constant velocity and change on touch - swift

How do I make my player move left/right at a constant speed until the user touches the screen again, which will then make the player change direction right/left and run that way at a constant speed etc..
I have tried looking at other answers but can't figure out a working answer.
I've set linearDamping to 0 already.
There are two basic ways to apply velocity.
One is by applying forces to physics bodies, or giving them velocities.
Two is positional transformations, usually done with SKActions.
They're not compatible.
Since you're using physics, you need to either apply force or set a velocity.
I think you should probably take the time to read this entire page:
https://developer.apple.com/documentation/spritekit/skphysicsbody
Here's the setting velocity cherry from it:
First, you can control a physics body’s velocity directly, by setting
its velocity and angularVelocity properties. As with many other
properties, you often set these properties once when the physics body
is first created and then let the physics simulation adjust them as
necessary.
And here's the outline on forces:
You can apply a force to a body in one of three ways: A linear force
that only affects the body’s linear velocity. An angular force that
only affects the body’s angular velocity. A force applied to a point
on the body. The physics simulation calculates separate changes to the
body’s angular and linear velocity, based on the shape of the object
and the point where the force was applied.

How to get Constant Velocity for Spritekit Gravity

I am making a Tetris kind of game, where I want my blocks to fall at a constant velocity. I want to achieve it using SpriteKit Physics Words Gravity.
Problem is that gravity is necessarily acceleration and hence block start to move faster as they fall. I know I can turn gravity off and use actions to move the block but I wish to do it with gravity.
Is there a way to make the gravitational force in SpriteKit world a linear constant velocity?
Using the default physics you will not achieve what you are looking for.
In the definition of Gravity in Spite Kit is clear that is a acceleration, so is no possible to achieve linear speed with it.
A vector that specifies the gravitational acceleration applied to
physics bodies in the physics world.
But, you can have some workarounds to achieve the behavior you want.
Gravity Acceleration 0, and add speed to the falling object.
Limit the maximum Speed of an Object.
Do you own physics
I Think the best way to do it, with gravity working as default, is by limiting the maximum speed.
2 - Limit the maximum Speed
Consulting this post.
In didSimulatePhysics(), you can verify the speed of the object, and limit it.
Like this (Credits to #Andrew, in the original post)
- (void)didSimulatePhysics {
if (node.physicsBody.velocity.x < MAX_SPEED_X) {
node.physicsBody.velocity = CGVectorMake(MAX_SPEED_X, MAX_SPEED_Y);
}
}

SpriteKit - Why my bouncing ball passes through the ground?

I'm working for a small bouncing ball game using the SpriteKit physics engine. My problem is:
When I apply a huge impulse on the bouncing ball to have it fall on ground fast, sometimes it may pass through the ground (very thin, height=2).
I find this in the Apple document, but it doesn't work.
Specify High Precision Collisions for Small or Fast-Moving Objects
When Sprite Kit performs collision detection, it first determines the locations of all of the physics bodies in the scene. Then it determines whether collisions or contacts occurred. This computational method is fast, but can sometimes result in missed collisions. A small body might move so fast that it completely passes through another physics body without ever having a frame of animation where the two touch each other.
If you have physics bodies that must collide, you can hint to Sprite Kit to use a more precise collision model to check for interactions. This model is more expensive, so it should be used sparingly. When either body uses precise collisions, multiple movement positions are contacted and tested to ensure that all contacts are detected.
ship.physicsBody.usesPreciseCollisionDetection = YES;
You can set your sprite's node.physicsBody.usesPreciseCollisionDetection = YES; but this will not guarantee a collision flag all the time as your sprite's velocity could simply be just too high.
You should apply a speed limit to your nodes as to prevent them from going too fast. Something like this:
if(node.physicsBody.velocity.dx > 200)
node.physicsBody.velocity = CGVectorMake(200, node.physicsBody.velocity.dy);
The above code example will limit the right movement, dx, of your node to 200 while keeping the dy (up/down) velocity as is.

Accelerate an SKSpriteNode

Is it possible to accelerate an SKSpriteNode?
I know the velocity can be set easily with node.physicsBody.velocity but how hard would it be to set it's acceleration?
Working backwards from newtons second law a motion : F = m.a
You can achieve a desired acceleration by using applyForce where the force is the acceleration multiplied by the mass.
[node.physicsBody applyForce:CGVectorMake(node.mass*acceleration.dx,
node.mass*acceleration.dy)];
applyImpulse instantly imparts a quantity of energy (in Newton.seconds). Your object doesn't accelerate so much as instantly reach the desired speed. This is unlikely to look very natural as it implies near-infinite power (energy divided by time) therefore is only really suitable for explosions (shooting bullets for example).
applyForce applies a force (in Newtons) for the time-interval the simulation runs in (i.e.: 1/60th of a second). This allows you to correctly accelerate an object and simulate many different forces being applied simultaneously (gravity, wind, rocket boost etc.) in different directions.
Also worthy of note is applyForce:atPoint: this allows you to specify at which point of the object the force is applied. For example if you were simulating a balloon with a string, the string would apply its weight to the bottom of the balloon, whereas the lift of the base in balloon would be applied to the centre of the ballon. Applying a force elsewhere than at the centre of gravity will cause the object to rotate.
Lastly, you have the corresponding applyAngularImpulse: and applyTorque: which allow you to influence an object's rotation speed. This is useful for example if you want to keep an object upright despite various bounces: you could apply a torque proportional to the angle (or square it if you want to avoid oscillations).
All this is very well documented here: SKPhysicsBody
But if you need more information about the physics themselves then have a look at Wikipedia:
Newtonian Physics and associated pages (angular momentum for example).
If you want it to accelerate, then you should change the direction of gravity for the object
self.physicsWorld.gravity = CGVectorMake(dx,dy)
but this would make everything accelerate, if that is okay

Slow motion in Sprite Kit iOS

Does anyone have any good ideas of how to accomplish a slow motion effect in Sprite Kit for iOS? This would make all nodes including particle nodes move at 1/2 the speed and also make the particles move that 1/2 the speed.
I can think of how to do this manually, but I wanted to get some more ideas before I start implementing.
I believe you can do:
self.physicsWorld.speed = 0.5;
The docs reference:
speed
The rate at which the simulation executes.
#property(nonatomic) CGFloat speed
Discussion
The default value is 1.0, which means the simulation runs at normal speed. A value other than the default changes the rate at which time passes in the physics simulation. For example, a speed value of 2.0 indicates that time in the physics simulation passes twice as fast as the scene’s simulation time. A value of 0.0 pauses the physics simulation.
Availability
Available in iOS 7.0 and later.
Declared In
SKPhysicsWorld.h
In update method where you calculate movement speed everywhere when calculations are done multiply the movement by some variable, have it be 1 by default. But when you need slow motion set it to 0.5.

Resources