Spritekit how to not veer off - sprite-kit

I'm building a pacman style maze game.
I can apply impulse and limit it to whatever vertical or horizontal direction as desired on the hero.
However, when I add physics body sprites for walls, it gets weird.
I have set the hero physics body and the walls to have no bounce.
Running head on into a wall it stops dead like expected.
But if I then change direction and move along the wall I veer off at a slight angle from the wall.
Any ideas what causes this and how to avoid it?
I want to only move in vertical and horizontal straight lines.

Ok so the solution here is slightly counter intuitive.
Rather than using applyForce: or applyImpulse: family of methods on the physicsBody, use runAction:forKey: on the sprite itself.
For any change in direction, removeAction:forKey: just before calling runAction:forKey: to keep things orthogonal.
(Otherwise there will be a brief angular movement )
The other trick here is to find an appropriate speed for distance. Too fast and it will fly through walls. (Bug?)
Then apply the speed and distance with a multiplier based on the size of your scene.
The total distance should be something greater than possible in any direction.
That keeps the thing moving until it hits a wall or you tell it to move in a different direction.
This works really well.
Using the physics body movement, it seems best suited to a platformer situation where you have a gravity.
In a top down view, there isn't normally gravity.
( though it is imaginable that you could want something that exerts gravity on a sprite to suck it in)

Related

Objects not colliding Unity2D

I am trying to make a Retro Tenis Game in Unity2D but I have some issues with the colliding system.
My controller does not collide with the walls. It goes through them.
It should stop in the wall like pic1 but it goes through it like pic2.
Can anyone help me, please?
pic1
pic2
UPDATE#1: I added a RigidBody component but it does not fix it. (pic3)
pic3
You shouldn't use the colliding system for this purpose. It would be much better that the script in charge of moving your paddle was able to control its maximum and minimum height too (note that the screen size can change, and the paddles should move at different heights depending on the screen size).
Although if you want to do it with the collision system and "walls" that limit the space of the paddles, both the "walls" and the paddles need to have a correctly positioned BoxCollider2D and the paddles an extra kinematic Rigidbody2D too (as they can move).
Also make sure to move the paddles using physics and not modifying its position with transform.position (see Rigidbody2D.MovePosition)
Edit: Unity2D physics system is rather a complicated topic and difficult to get it well on your own. I'd suggest to learn the basics in the Unity Learning Platform. You could start with this project.
You need add RigidBody2D to your "circle"

remove bouncing from PhysicsBody?

How can I completely remove the bounciness from my PhysicsBodies, I already set the restitution of all PhysicsBodies to 0 but when multiple PhysicsBodies collide they still bounce off of each other, how can turn this off?
Here's a video where i swipe up and down which triggers this code on the blue SpriteNodes:
node.physicsBody?.applyImpulse(CGVector(dx: x, dy: y))
https://imgur.com/a/MD2Sc
I want the blue SpriteNodes to just stay up or down and not bounce away
Are you experimenting in a space without any world damping/friction? If so, you will need to zero the velocity of objects the moment they collide in order to get zero bounce. But you'll also need to move them outside the boundary of the objects they collided with.
By way of explanation:
This is, I presume, happening because your objects are achieving a (slight) state of overlap right before the collision is reported to the physics engine. When this happens, the first response of some physics engines is to remove this overlap by moving the object with a corrective amount of force or movement. What's happening looks like a continuation of that movement.
In some physics engines you get the opportunity to determine how strongly the corrective behaviour is, and how frequently it occurs, and even set the physics simulation to much higher rates of solving than the frame rate. In these engines you could find the right balance of settings to prevent this. But not in SpriteKit.

Unity Brick Breaker: Ball hitting in-between two bricks

I am making a 2D Brick Breaker game in Unity.
I have an issue with the scenario when ball hits in between two bricks. I have BoxCollider2D attached to all bricks and a CircleCollider2D attached to the ball. When the ball hits between 2 adjacent bricks, it bounces back in the same direction as if it hit the edge of the brick. There is no edge in between, but two adjacent bricks form a continuous surface. So, the ball should bounce off of the surface (in other direction) instead of bouncing back.
Anyone knows of any solution to tackle this problem? I asked this in the Unity Physics forums but didn't get any answer, so checking if anywhere here might have had this issue.
Thanks,
Mukul
I am guessing this could be the problem:
When your ball is hitting the bricks with a strong force, There is a chance it might move one of the bricks by a very very slight distance, even if the mass of the brick is much heavier.
This movement might cause an uneven surface, which is why the ball bounces back in the same direction.
Try adding a Rigidbody Component on every brick (if you have not done it already), and set its isKinematic property to true.
Let me know if this solves it.
Way 1:
Use one box collider for the wall, but not for every single brick.
This will fix your issue + will optimize your project.
Way 2:
You need to build wall programmaly and colliders in this case must be without spaces between them. This must fix the issue.
Way 3:
Make your own hitting wall logic.
OnColliderEnter you need to get balls velocity.
OnColliderEnd you need to set manually velocity.

SKPhysicsBody, rotate a sprite after applying impulse to change direction

I am looking for some info on how I can get my sprite to change its rotation by changing the angle of the sprite.
Basically here is how it is set up. Imagine a rocket that is sitting in a stationary position. The physics body is the shape of the rocket, with the tip pointing to the top. Now I apply an immediate impulse to the rocket to send it into the air. While in the air, I would like to use the accelerometer to rotate the sprite. With the rotation, I am expecting the direction of the sprite to change. Unfortunately, The sprite goes straight up and down instead of the direction it is rotated, even though the texture and physics body is rotated. I am having a hard time trying to find info on what techniques are used to achieve the results I want. Most examples have a continuous force, but I only have the initial force with no change after that. I have played around with linearDamping and angularDamping, but that was no help. I have also tried attaching another physics body to the tip to make the tip more heavy to see if the direction will change, but that didn't help either. My only work around that worked is to change the gravity direction, But I would like to avoid this. Any help or direction would be appreciated.
I think the solution you may be looking for is in Sprite Kits SKFieldNode class.
https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKFieldNode_Ref/#//apple_ref/occ/clm/SKFieldNode/linearGravityFieldWithVector:
The linearGravityFieldWithVector: is probably your best bet. It applies a linear gravity field in a direction you set.
You can also check out electricField which is similar however you can change the charge to positive or negative.

Cocos2d - Creating collidable Sprites?

Hello everyone I an very new to cocos2d, so I apologize if this is a simple question. I would like to create to sprites that collide when they hit each other.
For instance, one sprite, spriteA, is in a fixed position on the screen. And another sprite, spriteB, is moving around the screen. SpriteB will collide with spriteA. If that doesn't make sense or you don't understand it, tell me and I will elaborate further. Any help is appreciated. Thank YOU!
Try using Chipmunk or Box2d physics systems. These are included with Cocos2d and work by having a physics simulation that updates with every time the graphics change on screen.
The physics simulation will tell you if two objects are overlapping, and will provide physical attributes like weight, slipperiness (friction), speed and direction, which creates reactions like bouncing, sliding, realistic loss of speed and changes of direction on impact.
If you are new to physics simulation, here's a 30 second run down:
Create "bodies" in the physics simulation that represent each graphical sprite
Bodies are usually defined more simply than their graphical counterparts, like a circle, square or simple polygon shape
In order to update the graphics on the screen accurately, first you establish a pixels to meters ratio. Meters are notional (i.e. made up) measurement that is used in the physics sim
Each time the physics simulation "ticks", you update the graphics on screen accordingly
So if a body in the physics sim moves 1 meter, you might transform the pixel sprite 32 pixels
Here's a good tute on collision detection using Box2d.
http://www.raywenderlich.com/606/how-to-use-box2d-for-just-collision-detection-with-cocos2d-iphone
enjoy
Its actually very simple:
Just schedule a timer: [self schedule:#selector(checkForCollision:)];
Specify the method: - (void)checkForCollision:(ccTime)dt {}
In the curly braces, make CGRects for each sprite using CGRectMake.
Then in the same method, just call: if (CGRectIntersectsRect) {}
That easy!
Well technically speaking when the 2 sprites interact, or share at least one common point, then they are colliding. I'm a little confused by your question. Are you asking for direction on how to make the sprite move on screen, or are you asking how to handle the actual collision(such as calling a method if they collide)?