SPriteKit Handling collision behaviour from different Angles - sprite-kit

I am working on game, in which i need different collision behaviours from different side,
Suppose there is a character when it collide to any other obstacle from down side, it will behave differently.
when it collide to any other obstacle or object while it is at top and the obstacle or object is below it, then i need different behavior,
what is the best way to acheive it.-(void)didBeginContact:(SKPhysicsContact*)contact how it be helpfull in my scenario
Thanks

You do not even need the contact point. The method called after you determine what came in contact has access to the nodes in contact. Therefore, you can just compare the x and y locations and handle them accordingly. You can then ignore collisionBitMask and replicate the collisions in the method called by contact.

LearnCocos2D guided me in Right direction
skphysicscontact gives you the contact point developer.apple.com/library/ios/documentation/SpriteKit/… Check where contact point is in relation to nodeA and nodeB position. Ie if posA.x < contactpoint.x and posB.x > contactpoint.x the contact was to the right of nodeA.

Related

Check if a specific node is near another one SpriteKit, Swift

I'm currently working on a game and when an enemy is shot I want to check if there's a protector enemy to take the damage instead of the one shot.
How can I check if there's this type of enemy within a certain distance of the enemy shot ?
I thought about enumerateChildNodes but I should change the name of the protectors and this doesn't help to count them as enemy in many functions
Thank you !
Is a "protector" enemy always associated with an enemy? Can you link the two with a protector optional property?
If not, you'll need to search using the radius from the enemy's position
Then search that array of nodes for the protector enemy, and pick the first (or one at random) to damage instead.

How do I make a SKSpriteNode avoid another SKSpriteNode?

I am working on an AI mode for a SpriteKit game I am making in Xcode. I have dynamic physics bodies which can be launched towards the AI. I want to make it so that when one of these bodies is within a certain radius of the AI, the AI tries to dodge it. I have started working through different routes and got decent results.
1st method (pseudocode): Check AI.position.x and AI.position.y and compare to incomingSprite.position.x and incomingSprite.position.y. Break this comparison into quadrants if both x and y are within radius. (i.e. incomingSprite is bottom left relative to AI, bottom right, etc). Based on this info move the AI's position to move away from it.
cons:
-lots of code and calculations in update function to account for multiple incoming sprites
-depending on dx and dy of incoming sprite, the AI often make illogical decision
2nd method (pseudocode): Calculate distance from AI to incomingSprite. Then check dx and dy of incomingSprite and set dx and dy to go in reverse direction of incomingSprite. This seems logical. I am a little rusty on reversing vectors to do this. I feel like this might be possibly a good idea though.
Is there a better method to accomplish this? Perhaps a force field on the magnet I could use to repel the AI at a certain strength so that if the incomingSprite is fast enough it will override and still collide anyway? Im concerned about memory as most of the AI logic is in the update function, which can cause big problems if I'm not careful.
Edit: I decided to use the electric field and gave the incoming sprites a positive charge so that they are repelled by the AI. This makes things accurate/lightweight and more interesting. If the incoming sprites are fast enough, they will break through the electric field and still collide with AI. This also gives room as an additional difficulty parameter in my game (the stronger the field, the harder it is to get the incoming sprites to collide with the AI).

Physics contacts in SpriteKit

Is it possible to explain how bitmasking works for just this simplistic situation:
A big (blue) ball. Contact BitMask 0b0001
A medium (red) ball. Contact BitMask 0b0010
A small (white) ball. Contact BitMask 0b0100
They have no collisions between them, because somehow this is turned off between them. I assume by setting their collision masks to 00 all the way through the 32 bits... but let's leave that for another question, I haven't yet figured out how to turn these off.
Having set each ball to have a unique contact bit mask, what is done that gives contact information when they contact?
How is it possible to know which two balls have contacted each other?
Is it possible to have the contact information only received by the biggest ball in any given contact?
UPDATE:
I'm not necessarily after code. If you need code to explain what's what, how it works, and why whatever does what, go for it.
But what I'm really after is an understanding of how bitmasking works to provide logic that permits the determination of "who" was involved in any contact.
The reason I've given each ball size a different bitmask is that I thought this might help determine the bigger ball in any given contact between two balls. I could be wrong about this, though.
UPDATE 2:
Understanding of processes progressing:
As I understand it, these are the parts of the process:
Register SKView subclassed SKScene as conforming to the physics world contact notification delegate. Say it is so, too.
Set bitmask as categories for each type of bodily interaction type desire to be known about and/or controlled in the simulation
Use these bitmasks to articulate the nature of each object desired to be a part of contacts and/or collisions by applying them appropriately (some magic decision making in here).
Override the contacts callback with code that does stuff, in the same SKView subclass registered as the delegate
Create some magic code that determines who/what has contacted whom.
I understand some of these, but not the differentials of setting contact bitmasks versus the reasoning for the naming of category bitmasks, and not how to determine who has contacted whom.
In almost all physics engines, collision layers are represented by bit masks. All objects in the same collision layers will collide with each other. In the bit mask, each layer is represented by a bit. If the bit at position 0 is on, the object will collide with other objects which have the bit at the same position in their bit mask on.
While checking for collisions, the physics engine's broad-phase routine only reports those pairs as potentially colliding which have at least one common bit set to 1 in their collision bit mask. This check is simply done by ANDing (&) the two bit masks. The potentially colliding pair is reported to the narrow-phase routine only if the above check returns a non-zero result.
For example, if you wanted the blue ball to collide with both the red and white balls but wanted the red and white balls to not collide with each other, you'd set the bit masks to somewhat the following:
Blue -> 0b0011
Red -> 0b0001
White -> 0b0010
In your example, since none of the bodies have a common bit set in their collision bit mask, none of them collide with each other. In the above example, since the red and white balls don't have a common bit in their bit mask, they don't collide.
You might want to set all the collision bit masks to -1 (which turns all bits on) and remove bits/categories from the mask by XORing. The above example would then be implemented by the following pseudocode:
blueBody.collisionMask = -1;
whiteBody.collisionMask = -1;
redBody.collisionMask = -1;
redBodyCategory = 0b0001;
whiteBodyCategory = 0b0010;
whiteBody.collisionMask ^= redBodyCategory;
redBody.collisionMask ^= whiteBodyCategory;
I don't use SpriteKit, but from the little information I obtained from this SO answer, the contactTestBitmask sets the categories with which events will be raised on contact, while the collisionBitmask sets the categories with which the body will actually collide. So if you want contact information only from contacts which involve the Blue ball, you'd set the contactTestBitmask to the values as in my example above.
To check which balls are colliding with each other, you'd have to check the bit mask values and discern which one is which. In the above example, the Blue ball can be recognized by checking if body.contactTestBitmask == 0b0011, and so on for each other body.
As a side note, you might want to look into using a proper game engine like Unity that will make all this much easier.
First, you need to define what your sprites are, this is what the categoryBitMask is for. Think of this as a binary name for your sprite, with each digit being a unique name. Now it is possible to give your sprite more than 1 name, but for simplicity purposes, let's keep it to one.
contactBitMask tells the sprites what names it should be looking for.
So during the physics phase, the engine will take a given sprite, and look for all other physics sprites with the search name provided in the contactBitMask.
After this, evaluations are performed against the original sprite and the sprites in the filtered list.
On a contact, didBegin(contact:) is called, and contact contains all the information you need, including the 2 contact bodies. You then check the categoryBitMask to get the name of the sprites in question, and you do your conditioning based on these names.

Unity3d - check for collision on non moving objects

I have a sphere build from multiple objects. What I want to do is when I touch/click an object, that object should find all adjunctive objects. But because none off them are moving, no collision detection can be used.
I can't find a way to detect these adjunctive objects even when the colliders do collide with each other, as I can see that in the scene. I tried all the possibilities, but none off them are working, because no objects are moving.
Is there a way to check for manual collision detection, or is there some sort of way to let Unity3d do the collision detection automatically?
You could keep a list of all those objects, then when your event happens you can send messages to all them to do what you want them to do.
Lets assume you want your sphere to break into little pieces. You send a Force message to the sphere. Then you use Newton's Laws of motion and find out how much velocity each piece gets. Remember velocity is a vector thus it has direction.
This is how I would do it and still keep the right amount of control over what happens in my game/simulation. Remember F = ma.
you could use RaycastHit (http://docs.unity3d.com/Documentation/ScriptReference/RaycastHit.html) for your collision, this also works on non-moving objects but it needs more performance
You can add rigidbody to every objects; when you touch one of them, give a force onto it, then it is going to move and trigger event of the adjacent objects.
for the reason you do not want to move the object you touch, you can cancel movement in the OnCollider or OnTrigger event handler function.
I managed to work around this by checking the distance from the selected object and all other objects that are part of the sphere. If the distance is below a certain value, then it is an adjunctive object.
Although this is certaintly not fool proof, it works without problems so far.
I am sorry I was not clear enough. Thanks for all the advice what so ever.

How to detect collision between three objects simultaneously in Box2D?

I am new to Objective-C. I am currently working on a game using Cocos2D and Box2D. My problem is that when 3 objects collide together, the game crashes. Now let me describe my game in details:
In my game I have a main character standing on top of a building. Below the building there's this the road. Enemies pass by the road at various random speeds entering the screen from right and exiting from the left. I have created the enemies as b2_kinematicBodies and set a random velocity for each of them using SetLinearVelocity(). The main character shoots the enemies. The projectile (the object being shot) is a b2_dynamicBody. When the projectile hits the enemies, both the projectile and the enemy are destroyed. During gameplay sometimes an enemy moving at a slow speed is crossed by one which is moving at a higher speed. If a projectile hits the two enemies just at the point when they are overlapping and one is about to pass the other one, the game crashes! Please help me with this.
I have detected collision using b2contactListener class.
One thing I didn't mention before is that I am not creating the enemies as individual distinct bodies. Instead, I am creating it once and making it move and I am calling this method (which creates the enemies and makes them move) inside init as below:
[self schedule:#selector(addRightTarget) interval:2.0];
I believe the issue is that the collisions are calculated before your handler gets any calls. Meaning that when your handler gets called, the bullet has hit 2 objects. So you get 2 call-backs as shown below.
Collision Detected: Bullet + Enemy1
Destroy Enemy1
Destroy Bullet
Collision Detected: Bullet + Enemy2
Destroy Enemy2
Destroy Bullet [CRAAAASH!!! You just tried to delete a non-existent object]
1st: You should not be removing anything except in your step function (as someone mentioned in another answer)
2nd: Pick one of these:
Make your list/array of objects-to-delete be a 'set' or implemented in such a way that duplicates are avoided.
Check for existence of your object in the world
The collision only happens between 2 objects in Box2D. So in your mentioned scenario your will get multiple collision events which could be,
Enemy-1 and Enemy-2
Enemy-1 and Bullet
Enemy-2 and Bullet
So one possible reason of crash could be that you are not expecting (Enemy-1 and Enemy-2) collision and you are handling it like you have collision between (Enemy-1 and Bullet) so you might be casting it into wrong class. Make sure you are checking the kind of class "isKindOf" before casting it.
Also you may want to use Contact Filtering and or assign category masks to your enemies so that they don't collide with each other and only collide with bullet.
But it will be more help full if you tell something about how and where you destroy your bodies (I hope its not inside your Collision Detection Functions) and also if you can share the exception text when your application crash, that will be helpful.
I used a rather cheap workaround. I alternately created enemy fixtures of different sizes(differing by few pixels). So now if i shoot them even when they overlap, the app doesn't crash(because only the bigger object collides and gets destroyed). This serves my purpose. Thanx a llot for your help. I really appreciate it! :)