How to stop a sprite from bouncing off a specific surface - ios

Hi I am making a endless scrolling game where the character basically avoids obstacles as they come and he can jump over them. I got everything to work pretty well but I see that the character texture will bounce slightly after hitting the ground. I want the sprite to stop immediately after touching down. I tried setting the .restitution property to 0 but i still see it bouncing. Here is the setup code for my stickman character and the edge physics category in question
stickman.physicsBody?.dynamic = true
stickman.physicsBody?.allowsRotation = false
stickman.physicsBody?.usesPreciseCollisionDetection = true
stickman.physicsBody?.categoryBitMask = PhysicsCategory.Stickman
stickman.physicsBody?.collisionBitMask = PhysicsCategory.Edge
stickman.physicsBody?.contactTestBitMask = PhysicsCategory.Obstacle | PhysicsCategory.Edge
stickman.physicsBody?.restitution = 0
self.physicsWorld.gravity = CGVector(dx: 0, dy: -9.8)
physicsBody = SKPhysicsBody(edgeLoopFromRect: playableRect)
physicsWorld.contactDelegate = self
physicsBody?.categoryBitMask = PhysicsCategory.Edge
Where playable rect is just the screen boundary for universal deployment purposes.
Has anyone run into this problem. I couldn't quite find the same issue in other posts.

Set the restitution of the physics body your sprite is running into to 0 as well. Both physics bodies in a physics collision need to have a restitution of 0 to result in no bounciness.

Related

How to make a Sprite an obstacle for another Sprite?

I am making a game with sprites that move and obstacles to learn SpriteKit. I want the sprites that move to collide with the obstacles and bounce off of them but I want the obstacles to stay fixed. How do I do this? I have tried the following with no success:
Setting obstacle.physicsBody?.isDynamic = true. This made the sprites go through the obstacle.
Fixing the movement and rotation of the object with SKConstraint. When I do this they just go through each other.
Setting the mass of the body to be really high as follows obstacle.physicsBody?.mass = CGPoint.maxFiniteMagnitude but this freezes the game. When I set it really high it doesn't seem to do anything.
Setting obstacle?.physicsBody.velocity = CGVector(dx: 0, dy: 0) when the objects collide. I know that the contact.bodyA and contact.bodyB are passed by value and not reference so I loop through an array with the obstacles and set the velocity this way. The obstacles are still pushed by the other sprites.
Update:
- Setting obstacle.physicsBody?.collisionBitMask = PhysicsCategory.none so the sprite collides with the obstacle but not the other way around.
The object is setup as follows, with fish being the other sprite:
obstacle.position = location
obstacle.physicsBody = SKPhysicsBody(rectangleOf: obstacle.size)
obstacle.physicsBody?.isDynamic = true
obstacle.physicsBody?.categoryBitMask = PhysicsCategory.obstacle
obstacle.physicsBody?.contactTestBitMask = PhysicsCategory.fish
obstacle.physicsBody?.collisionBitMask = PhysicsCategory.fish
obstacle.physicsBody?.usesPreciseCollisionDetection = true
self.obstacles.append(obstacle)
super.addChild(obstacle)
Please let me know if there is something I am doing wrong / misunderstanding. Thanks.
Found the answer here. One of the objects needs to have .physicsBody?.isDynamic = true. In this case I set the obstacle to false so it is stationary.

Swift Collision Not Working After SKReferenceNode Scale

I have a weird problem where my SKReferenceNode does not collide properly after being scaled up. It collides well in the center, but it ignores collisions and contacts on the edges.
Here is the first photo of the scene. The SKReferenceNode was scaled up significantly, and as seen in this photo, does not collide correctly on the edges. The PhysicsBody appears to be correct (with showPhysics on), yet the ball refuses to collide.
The SKReferenceNode is using an alpha collision mask, because I need to change it to a larger sprite in the future to do animations and such. Additionally, non-scaled objects work completely fine. Finally, after the ball collides with the center, which does work, and the block is reset, collisions start working as expected again. The code to fix it is probably in the reset function, but I reset everything before the level is loaded, so this wouldn't make sense. Here is a part of my reset code:
func reset() {
physicsWorld.gravity = CGVectorMake(0, -9.8)
for grav in gravityBlock {
grav.reset()
}
gravity = -9.8
//Resets blocks
for blocks in destroyedBlocks { //the blocks are stored in destroyedBlocks when collided with
blocks.reset()
}
destroyedBlocks = []
/*Irrelevant code removed*/
}
Here's my blocks.reset() function:
override func reset() {
super.reset()
self.physicsBody?.categoryBitMask = 1
removeAllActions()
self.texture = self.text
shadow.hidden = false
self.alpha = 0
shadow.alpha = 0
let appear = SKAction(named: "Appear")!
self.runAction(appear)
shadow.runAction(SKAction.fadeInWithDuration(0.25))
}
Here is super.reset()
func reset() {
self.hidden = false
state = .NotBroken
}
Thanks so much!
When you scale the sprite you are just changing it's visual representation. The Physics Body stays the same. That's why you are getting the "strange" during the collisions.
You can see that showing the physics uses in your scene, just open GameViewController and add this line
skView.showsPhysics = true
inside viewDidLoad, just after this line
skView.showsNodeCount = true
Then run again your game, the physics boundaries now will be highlighted.

Make a sprite keep bouncing

I'd like to know if there's any way to make a sprite have the same "amount of bouncing" when colliding with other objects in Sprite Kit. I mean, I want it move with the same force after a collision. I have set both colliding objects restitution to 1.0 but after some collisions and in a certain angle, the sprite decelerates.
First:
Change the gravity of the physics world to zero
self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
Second:
Reduce the body’s linear velocity (LinearDamping)
myBall.physicsBody!.linearDamping = 0
Third:
Change the bounciness of the physics body
myBall.physicsBody!.restitution = 0
Fourth:
Change the Friction
myBall.physicsBody!.friction = 0
See the whole explanation in the DevelopApps.org website
http://www.developapps.org/sprite-kit-tutorial-how-to-make-a-node-keep-bouncing/

How to make sprites respond to contact events but not collision events (SpriteKit)?

Is it possible to make sprites in Swift respond only to contact events, ignoring collision events? We set the dynamic property to false for one of the sprites, but it didn't trigger the didBeginContact method when another sprite contacted it.
In other words, we want to get notified in didBeginContact when another sprite contacts an object, but we don't want the sprite to experience physics (e.g., no bouncing or moving on collision).
Set collisionbitmask to 0 on both sprites. But set the contacttestbitmask to the opposite sprites categorybitmask
heres an example
heres the setup for my Power Up this is a physics body that doesnt exhibit physics behavior
self.physicsBody = SKPhysicsBody(rectangleOfSize: self.size)
self.physicsBody!.categoryBitMask = CategoryPowerup
self.physicsBody!.contactTestBitMask = CategoryShip
self.physicsBody!.collisionBitMask = 0
self.physicsBody!.dynamic = false
heres the setup for my Ship that gets the powerup
let physicsBodyInset = CGRectInset(CGRectMake(0, 0, self.size.width, self.size.height), 2, 2)
self.physicsBody = SKPhysicsBody(rectangleOfSize: physicsBodyInset.size)
self.physicsBody!.restitution = 0
self.physicsBody!.categoryBitMask = CategoryShip

Edge based SKPhysicsBody moves over time

I am using the following code to put a floor in my SpriteKit based game:
var floorNode = SKSpriteNode()
var floorBody = SKPhysicsBody(edgeFromPoint: CGPointMake(self.frame.minX, self.frame.minY), toPoint: CGPointMake(self.frame.maxX, self.frame.minY))
floorNode.physicsBody = floorBody
addChild(floorNode)
This places a floor at the bottom of the screen as expected. However as I add more things to the scene, one end of the floor eventually sinks down and everything in the scene that is resting on it slides off into the abyss.
I am at a complete loss here since Apple's documentation says that "an edge-based body does not have mass or volume, and is unaffected by forces or impulses in the system. Edge-based bodies are used to represent volume-less boundaries or hollow spaces in your physics simulation."
Anyone else seen this kind of behavior?
The easiest way to define floor for your scene, without adding any nodes to it:
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
where self is your SKScene.
If you don't want ceiling on the scene, define physicsBody as this:
[SKPhysicsBody bodyWithEdgeLoopFromRect:CGRectMake(self.frame.origin.x,
self.frame.origin.y,
self.frame.size.width,
self.frame.size.height*5)];

Resources