This issue has been discussed here somewhat, but I would like to hear other people experience with physics world forcing nodes to pass through each other unpredictably.
I am using a SKAction to move one node. This node needs to slide at constant speed through the scene until it reaches a certain position. A 2nd node is falling through gravity until it touches the scene frame.
When the two nodes collide, I would assume the falling node is lifted against the gravity. Instead, occasionally, the 2nd node is repositioned on the opposite side of the first node. The collision is properly detected in the didBeginContact.
This seems to depend on the speed of the SKAction. If I slow down the SKAction that makes the 1st node slide by as little as 20%, the collision lift the 2nd node as expected.
What is the best way to work around this kind of behaviors?
Everything is pretty much explained in that link. If you are interested in physics simulation the only sanctioned way is to move all bodies through physics by applying forces or impulses, or by directly changing velocity vector.
If you look how each frame is processed in SpriteKit, you will se that :
actions are executed first
physics is simulated after
So, if you move a node manually, you are not letting the physics simulation to move it where it thinks it should be appropriate. You are pulling the object out of sync with an actual physics simulation. Also, this way, the node will be moved by both - the action and the physics engine, thus the unexpected result.
Contact detection will work though. But don't confuse terms "contact" and "collision" . Contacts will be trigered properly even if you use SKActions to move bodies. But, collisions may not be properly simulated etc . So as long as you are interested in contacts, you are good to go. If interested in any kind of physics similation, then use appropriate ways to interact with physics world.
Related
I have a 2D sidescrolling game. Right now, in order to jump, the player must be touching the ground. Therefor, I have a boolean, isOnGround, that is set to YES when the player collides with a tile object, and no when the player jumps. This generates a LOT of calls to didBeginContact method, slowing down the game.
Firstly, how can I optimise this by using one big physics body for the tiles on the floor (for example clustering multiple adjacent tiles into one single physics body)?
Secondly, is this even efficient? Is there a better way to detect if the play is on the ground? My current method opens up a lot of bugs, for example wall jumping. If a player collides with a wall, isOnGround becomes YES and allows the player to jump.
Having didBeginContact called numerous times should in no way slow down your game. If you are having performance issues, I suspect the problem is probably elsewhere. Are you testing on device or simulator?
If you are using the Tiled app to create your game map, you can use the Objects Layer to create a individual objects in your map which your code can translate into physics bodies later on.
Using physics and collisions is probably the easiest way for you to determine your player's state in relation to ground contact. To solve your wall issue, you simply make a wall contact a different category than your ground. This will prevent the isOnGround to be set to YES.
You could use the physics engine to detect when jumping is enabled, (and this is what I used to do in my game). However I too have noticed significant overhead using the physics engine to detect when a unit was on a surface and that is because contact detection in sprite kit for whatever reason is expensive, even when collisions are already enabled. Even the documentation notes:
For best performance, only set bits in the contacts mask for
interactions you are interested in.
So I found a better solution for my game (which has 25+ simultaneous units that all need surface detection). Instead of going through the physics engine, I just did my own surface calculation and cache the result each game update. Something like this:
final class func getSurfaceID(nodePosition: CGPoint) -> SurfaceID {
//Loop through surface rects and see if position is inside.
}
What I ended up doing was handling my own surface detection by checking if the bottom point of my unit was inside any of the surface frames. And if your frames are axis-aligned (your rectangles are not rotated) you can perform even faster checks to see if the point is inside the frame.
This is more work in terms of level design because you will need to build an array of surface frames either dynamically from your tiles or manually place surface frames in your world (this is what I did).
Making this change reduced the cpu time spent on surface detection from over 20% to 0.1%. It also allows me to check if any arbitrary point lies on a surface rather than needing to create a physics body (which is unnecessary overhead). However this solution obviously won't work for you if you need to use contact detection.
Now regarding your point about creating one large physics body from smaller ones. You could group adjacent floor tiles using a container node and recreate a physics body that fits the nodes that are grouped. Depending on how your nodes are grouped and how you recycle tiles this can get complicated. A better solution would be to create large physics bodies that just overlap your tiles. This would reduce the number of total physics bodies, as well as the number of detections. And if used in combination with the surface frames solution you could really reduce your overhead.
I'm not sure how your game is designed and what its requirements are. I'm just giving you some possible solutions I looked at when developing surface detection in my game. If you haven't already you should definitely profile your game in instruments to see if contact detection is indeed the source of your overhead. If you game doesn't have a lot of contacts I doubt that this is where the overhead is coming from.
I've been reading a book called "iOS Games by Tutorials" (recommend it to anyone interested in making iPhone games) & I'm learning how to make Tiled Maps with Sprite Kit with an overhead view (like the legend of zelda link's awakening). So far, I have made a tiled map using tiles that are 32x32, placed the player character & several NPC's into the world. Even made the NPC's randomly move around the map, though the way it teaches in the book is having them move from tile to tile (any of the 8 tiles surrounding the NPC at any time - if a tile has some property such as categoryBitMask then it won't move to that tile).
I am going to change NPC movement to physics-based (which is its own problem) just like the player character has right now (which means NPC's will collide with objects that have a physicsBody like the player character does). It's more fluid & dynamic.
But here is where the question begins. I want to implement Pathfinding (such as the A* algorithm) into the NPC & player character movement due to the map containing buildings, water, trees, etc. with their own physicsBodies. It's one thing to limit NPC's random movement or to force them to walk a predetermined path (which will kill the point of this game), but it's another to have to tap the screen very often to have the player character avoid all the buildings/trees he has to walk past. I don't want to use a grid system. Is it possible to implement some pathfinding algorithm into x,y coordinates? Is this more resource intensive? Could you share your thoughts about this?
Thank you.
This is a very interesting topic.
There are algorithms for finding paths in continuous spaces. For example, you can use a potential based method with the objective having a very low potential and obstacles being "hills" (perhaps infinitely high, although this requires a bit of care). The downside of potential methods is that you have to take special precautions to keep them from getting stuck at a local minimum. Situations like this
P
+----+
| M|
| |
+ ---+
Where M is a monster trying to get to the player, P can occur. In the example, the monster is at a local minimum, and it would have to go to a higher potential in order to get out the door at the lower left of the building. A variant of potential algorithms (in fact, it's often useful to reduce it to one), is to assign anti-gravity to obstacles and gravity to objectives. This is also somewhat non-deterministic and requires special precautions to avoid getting "stuck".
As #rickster points out, SpriteKit provides an SKFieldNode class that can help you implement a potential based solution.
Other approaches include "wall following" (for example, Pledge's algorithm) and are useful for finding your way around in a maze like environment.
One drawback to continuous methods is that NPC movement will often seem a bit unnatural -- for example, even if our monster in the example above is able to decide that it's at a local minimum and increase the "temperature" of it's search (that is, make larger moves, perhaps at random, against the potential gradient), it will bounce around instead of going straight for the door.
An alternative to searching in continuous spaces is to quantize the space. A simple method is to tile it, cover it with polygons, or represent it as a quadtree. Essentially, you want to have a way of mapping every point in the continuous space to a vertex on a graph representing the quantized space. At this point, graph search algorithms like A* and friends are applicable.
Graph search is somewhat resource intensive, but for a 2d zelda like game, it should be doable on a mobile device, especially with various optimizations like only "waking up" NPCs that are within a certain distance of the player (think aggro).
This page is a bit thin on implementation details, but it'll give you the right terms to google.
As always, start simple and iterate. Tiling is incredibly easy, and will let you experiment with the graph search method before optimizing.
Is there anyway of calculating when an SKPhysicsBody comes to rest (or rather its velocity gets very small) so that you can remove it from the physics simulation. I have tried watching the velocity but there are two issues. (1) on any given bounce there is a point at the apex where the object has little velocity, (2) when the SKPhysicsBody has visibly finished bouncing the velocity.dy still shows a pretty large number (i.e. 30+) even though for all intents the body is now at rest. Just curious if there is anything available I might have missed for checking when a body is no longer moving?
SKPhysicsBody has a boolean resting property that the physics world turns on when deemed at rest - that might be what you're looking for. Not sure that will work though in your case since you can't really set the threshold when it triggers.
It sounds like you want the resting property of SKPhysicsBody.
From the linked documentation,
This property is automatically set to YES by the physics simulation
when it determines that the body is at rest. This means that the body
is at rest on another body in the system. Resting bodies do not
participate in the physics simulation until an impulse is applied to
the object or another object collides with it. This improves the
performance of the physics simulation. If all bodies in the world are
resting, then the entire simulation is at rest, reducing the number of
calculations that are performed by the physics world.
How do I create a motion impact/collision like angry bird. When the object hit the box and wood, their interaction and the flow of the animation will to the right position. I need to learn from scratch how to build it. I need the basic of physic and concept
Example image:
So far, What i think so far is. Upon impact, I will apply
Law of Restitution
object 1 velocity = e(ball velocity)
I will take the direction of the ball and make the object 1 to rotation 90% against the ball.
if ball ---> direction. my end result for object 1 will be 90 degree against it. so it will become
|____| it will turn into this.
So far it seen right. But I am unsure how to interact with object 2. Do I repeat step and 2. Whereby I passed the velocity and direction to object 2. so it will rotation 90 degree again?
This is what I have gather so far. Any suggest that I am moving to right direction will be good.
For collision part. I intend to use AABB. and rotation AABB.
AngryBirds used Box2D physics when I opened About page inside game.
Box2D is open source physics engine.
Most physics engines are based on impulses. They sum impulses and re-calculate velocities.
The most complex and import part is what happens when collision occur.
Physic Engine detect all collisions and use Solver function. Solver is heart and sole of phsyics engine. Solve adds additional impulses to "solve" collision.
Solver usually has form of function that takes collision island (list of colliding objects: often 2 objects) and return force or impulse to be applied to each object.
Most modern engines are impulse based.
So most important part of physics engine to learn and understand is Solver function. But solver could be more complex entity then function.
In my upcoming iPhone game different scene elements are split up into their own CCNode.
My Obstacle node contains many nodes, each representing an obstacle. Inside every obstacle node are the images that make up the obstacle (1 - 4 images), and there are only ~10 obstacles at a time. Every update my game calls the update function in the Obstacle node, which moves every obstacle to the left. But this slows down my game quite a bit.
At the same time, I have a particle node that just contains images and moves them all every frame exactly the same way the Obstacle node does, but it has no noticeable effect on performance. But it has hundreds of images at a time.
My question is why do the obstacles slow it down so much but the particles don't? I have even tried replacing the images used in the obstacles with the ones in the particles and it makes no (noticeable) difference. Would it be that there is another level of child nodes?
You will dramatically increase the app's performance, run speed, frame rate and more if you put all your images in a texture atlas and rendering them once as a batch using the CCSpriteBatchNode class. If you are moving lots of objects around on the screen a lot, this makes the hardware work a lot less.
Using this class is easy. Create the class with a texture atlas that contains all your images, and then add this class as a child to your layer, just as you would a sprite.
However, when you create sprites, add them as children to this batch node, not as children to the layer.
It's very easy and will probably help you quite a lot here.
From what I recall of the Cocos2d documentation, particles are intended to be VERY lightweight so you can have many, many of them on screen at once. Nodes are heavier, require more processing between frames as they interact with the physics system and requiring node-specific rendering. The last time I looked at the render loop code, it was basically O(n) based on the number of CCnodes you had in a scene. Using NSTimers versus Cocos' built in run loop also makes quite a bit of difference in performance.
Could you provide an example of something that slows down a lot? Exactly how do you update these Obstacles?
The cocos2d documentation has some best practices that all, in one way or another, touch on performance. There's a LOT you can do to optimize your frames per second.
In general, when your code is slow, it helps to use Instruments.app to figure out where your code is spending so much time. Since you're using a framework this will be less helpful because you'll end up finding out what functions your code spends a lot of time in, and then figure out how to reduce that via the framework's best practices or other optimizations. There are a few good blog posts on improving performance, I found this one very helpful.