I'm hoping to simulate the movement of a train along a fixed path. The path itself is representable by a CGPath.
So far, I've found SKPhysicsJointSliding, which seems close, but appears to only work along a fixed axis, and since my path has curves that seems like a deal breaker.
I know I could use a series of SKActions to accomplish the movement, but in my case it's far preferable to have the physics engine handle the movement for me.
My question is basically whether or not this is something the SpriteKit physics engine can accommodate via something I've missed in the documentation (or if I'm somehow misunderstanding the sliding joint)?
Why is "physics" more preferable? Once you're on rails, you aren't really utilizing the physics engine. If you're looking for semi-realistic y-axis yaw as it rumbles down the track, try doing a random rotation about that axis.
You could also try utilizing the SKNode.physicsBody as well. According to Apple's docs, your SKNode doesn't participate in physics simulations until you attach one.
https://developer.apple.com/documentation/spritekit/sknode/1483117-physicsbody
Giving it mass and other physical properties could simulate slowing down, speeding up, etc.
Otherwise, you will have to do a lot of complicated math to apply physical forces in the direction you want the train to go.
Related
So.
After many years of iOS development I said it's time to try to do a little game for myself. Now I chose to do it using Apple's SceneKit since it looks like it provides everything I need.
My problem is that I've stumbled upon a huge problem (for me) and searching on Google doesn't yeld any results.
Any idea how do I go about having an object (a sphere for that matter) that deforms itself, say, because of a gravitational force. So basically it should squash on impact with the ground.
Or, how do I go about deforming it when it collides with other spheres, like a soft beach ball would?
Any starting point along those lines would be helpful.
I can post my code here, but I'm afraid it has nothing to do with my problem since I really don't know where to start.
Thanks!
Update
After doing a bit more reading I think that what I want could be doable with Vertex Shaders. Is that a right path to follow?
For complicated animations, you'll generally be better off using a 3D modeling tool like Blender, Maya, or Cheetah3D to build the body and construct the animation. Those tools let you think at a higher level of abstraction. Then you can export that model to Collada (DAE) format and then import it into SceneKit.
https://en.wikibooks.org/wiki/Blender_3D:_Noob_to_Pro/Basic_Animation/Bounce has a tutorial on building a deforming, bouncing ball using Blender.
SceneKit only does physics using rigid bodies. If you want something to deform, you would have to do it yourself.
It is probably because SceneKit has no way of knowing how an object should be deformed. Should it just compress, should it compress in one direction and expand in all others to preserve it's volume, should only part of the model compress and the rest stay rigid (like the tires on a car).
What you could try is wait for a collision to occur and do the following
calculate and store the velocity after the bounce
disable collision checking on the object
run an animation for the "squash"
enable collision checking on the object
apply the calculated velocity
It will be entirely up to you how real or cartoony you want to make the bounce look.
Let's say I have a SKSpriteNode that represents a car wheel, with a circular SKPhysicsBody successfully attached to it. The genre would be sideways scrolling 2d car driving game/simulator, obviously.
What I want is to calculate all the in-motor physics myself without resorting to the SpriteKit physics engine quite yet. I'd like to keep full control on how the mechanics of the motor, clutch, transmission etc. are calculated, all the way to the RPM of the drive wheel.
From that point onwards, though, I'd happily give control to the SpriteKit physics engine, that would then calculate what happens, when the revolving drive wheel touces the surface of the road. The car advances, slows down, accelerates and/or the wheels slip, whatever the case might be.
Calculating the mechanics to get the wheel RPM is no problem. I'm just not sure on how to go on from there.
I'm able to rotate the wheel simply by applying zRotation in the update: method, like this:
self.rearWheelInstance.zRotation += (self.theCar.wheelRPS/6.283 * timeSinceLastUpdate); // revolutions / 2pi = radians
This way I'm able to apply the exact RPM I've calculated earlier. The obvious downside is, SpriteKit's physics engine is totally oblivious about this rotation. For all that it knows, the wheel teleports from one phase to the next, so it doesn't create friction with the road surface or any other interaction with other SpriteKit physicsBodies, for that matter.
On the other hand, I can apply torque to the wheel:
[self.rearWheelInstance.physicsBody applyTorque: someTorque];
or angular impulse:
[self.rearWheelInstance.physicsBody applyAngularImpulse: someAngularImpulse];
This does revolve the wheel in a fashion that SpriteKit physics engine understands, thus making it interact with its surroundings correctly.
But unless I'm missing something obvious, this considers the wheel as a 'free rolling object' independent of crankshaft, transmission or drive axel RPM. In reality, though, the wheel doesn't have the 'choice' to roll at any other RPM than what is transmitted through the drivetrain to the axel (unless the transmission is on neutral, the clutch pedal is down or the clutch is slipping, but those are whole another stories).
So:
1) Am I able to somehow manipulate zRotation in a way that the SpriteKit physics engine 'understands' as revolving movement?
or
2) Do I have a clear flaw in my logic that indicates that this isn't what I'm supposed to be trying in the first place? If so, could you be so kind as to point me to the flaw(s) so that I could adopt a better practice instead?
Simple answer, mixing 2d UI settings, like position and zRotation, with a dynamic physics system isn't going to have the results you want, as you noticed. As you state, you'll need to use the pieces of the physics simulation, like impulse and angular momentum.
The two pieces of the puzzle that may also help you are:
Physics Joints - these can do things like connect a wheel to an axel so that it can freely rotate, set limits on rotation, but still impart rotational forces on it.
Dynamically Adjusting Physics Properties - like increasing friction, angular dampening or adding negative acceleration to the axel as the user presses the brakes.
After quite a few dead ends I noticed there is in fact a way to directly manipulate the rotation of the wheel (as opposed to applying torque or impact) in a way that affects the physics engine accordingly.
The trick is to manipulate the angularVelocity property of the physicsBody of the wheel, like so:
self.rearWheelInstance.physicsBody.angularVelocity = -self.theCar.wheelRadPS;
// Wheel's angular velocity, radians per second
// *-1 just to flip ccw rotation to cw rotation
This way I'm in direct control of the drive wheels' revolving speed without losing their ability to interact with other bodies in the SpriteKit physics simulation. This helped me over this particular obstacle, I hope it helps someone else, too.
I am wondering how beautiful is "Contre jour" game for IOS.
Especially i like elastic "tentacles",shown in this video on 2 min 20 seconds:
http://www.youtube.com/watch?v=ptdTdJarWLw
How can I implement such effects?
I know that there is technic called "Verlet integration" and even implementation of "verlet rope" for drawing ropes in cocos2d, but how to make such nice elastic effects to "tentacle" sprite?
I have experience of box2D usage, and may try to implement physics for this effect, but cann't find a solution how to draw sprite with such elastic morphing.
Can anybody help me or give some hints?
Just even explanation of technics, that can help me?
I have a little of experience in opengl, great cocos2d experience, so I plan to use cocos2d.
Sorry for bad english, I hope, you will understand my problem:)
If you use Box2D, you could try a distance joint with the frequencyHz and dampingRatio options set to non-default values. Perhaps a low frequency of around 4-6, and a damping of around 0.5-0.7 could be a good point to start from. You could think of frequency as how many times per second the joint tries to correct the distance, and damping as how well the distance is corrected each time. Setting the damping to a value lower than 1 will means the joint will be slower to correct the distance, and it will have a springy/rubbery behavior.
As for rendering, you could indeed use verlet integration for this. Take the two anchor points of the distance joint as the endpoints of the 'rope', and put a handful of points (doesn't look like too many would be necessary) in between them in an evenly spaced line. Every timestep, the points in between will simply move towards the average of the two points on either side of themselves. You could make the rope look tighter or looser by adjusting how far the inbetween points move to the target position each time step.
The final texture/sprite rendering would then take its position from the current location of the verlet points.
thanks for taking the time to read my question.
I'm writing a 2d top-down shooter game. It is currently using Box2d as a physics engine. The thing is, it isn't really using Box2d to it's fullest potential, just for collision detection and the underlying velocity/rotation update loop. Any plans to add real physics would simply be eye-candy, not a game changer.
Now I chose Box2d because I went through 2 other physics engines, and they just couldn't handle the types of collisions I'm detecting. I'm creating several 'bullets' with very high velocities, and I do not want them to be instant hits on their targets. JigLib and Flixel both had the same problem - bullets were not overlapping enemies at the time of the frame update, and thus were not detected as collisions (i.e. the bullets passed through enemies because they moved to fast).
I moved to Box2d because of it's iterative collision sampling, as well as the SetAsBullet method on bodies. And it works great! But now Box2d is giving me troubles too - generating several bullets per second, or at the same time, is severely lowering my fps.
So I removed Box2d to confirm that it was not a rendering limitation... added my own velocity/rotation system, and I can fire hundreds of bullets per second. Great! But its lacking any sort of collision detection.
So the questions:
1) Should I write my own iterative collision engine?
2) Should I give Box2d a try again, perhaps with some tweaks to make adding new bodies faster?
3) Is there some other alternative, maybe a lightweight physics engine that specializes in this?
4) Do you know of any other techniques or design patterns that could be of use?
Thanks so much for your help!
Edit: I should note, there are not just bullets, but larger, slower projectiles as well. I considered ray casting a line segment to the projectile's previous position, and catching intersections, but that won't work for the larger objects :(
It depends on how complex your situation can become, If you are good at math and physics you can rollout a fast engine that can handle simple collisions more faster than you can learn using box2d, but why should anyone invent the bycicle if there are plenty of them already invented so choose one you like a try using it, i recommend using box2d
I'm working on a 2D Platform game, and I was wondering what's the best (performance-wise) way to implement Surface (Collision) Detection.
So far I'm thinking of constructing a list of level objects constructed of a list of lines, and I draw tiles along the lines.
alt text http://img375.imageshack.us/img375/1704/lines.png
I'm thinking every object holds the ID of the surface that he walks on, in order to easily manipulate his y position while walking up/downhill.
Something like this:
//Player/MovableObject class
MoveLeft()
{
this.Position.Y = Helper.GetSurfaceById(this.SurfaceId).GetYWhenXIs(this.Position.X)
}
So the logic I use to detect "droping/walking on surface" is a simple point (player's lower legs)-touches-line (surface) check
(with some safety approximation
- let`s say 1-2 pixels over the line).
Is this approach OK?
I`ve been having difficulty trying to find reading material for this problem, so feel free to drop links/advice.
Having worked with polygon-based 2D platformers for a long time, let me give you some advice:
Make a tile-based platformer.
Now, to directly answer your question about collision-detection:
You need to make your world geometry "solid" (you can get away with making your player object a point, but making it solid is better). By "solid" I mean - you need to detect if the player object is intersecting your world geometry.
I've tried "does the player cross the edge of this world geometry" and in practice is doesn't work (even though it might seem to work on paper - floating point precision issues will not be your only problem).
There are lots of instructions online on how to do intersection tests between various shapes. If you're just starting out I recommend using Axis-Aligned Bounding Boxes (AABBs).
It is much, much, much, much, much easier to make a tile-based platformer than one with arbitrary geometry. So start with tiles, detect intersections with AABBs, and then once you get that working you can add other shapes (such as slopes).
Once you detect an intersection, you have to perform collision response. Again a tile-based platformer is easiest - just move the player just outside the tile that was collided with (do you move above it, or to the side? - it will depend on the collision - I will leave how to do this is an exercise).
(PS: you can get terrific results with just square tiles - look at Knytt Stories, for example.)
Check out how it is done in the XNA's Platformer Starter Kit Project. Basically, the tiles have enum for determining if the tile is passable, impassable etc, then on your level you GetBounds of the tiles and then check for intersections with the player and determine what to do.
I've had wonderful fun times dealing with 2D collision detection. What seems like a simple problem can easily become a nightmare if you do not plan it out in advance.
The best way to do this in a OO-sense would be to make a generic object, e.g. classMapObject. This has a position coordinate and slope. From this, you can extend it to include other shapes, etc.
From that, let's work with collisions with a Solid object. Assuming just a block, say 32x32, you can hit it from the left, right, top and bottom. Or, depending on how you code, hit it from the top and from the left at the same time. So how do you determine which way the character should go? For instance, if the character hits the block from the top, to stand on, coded incorrectly you might inadvertently push the character off to the side instead.
So, what should you do? What I did for my 2D game, I looked at the person's prior positioning before deciding how to react to the collision. If the character's Y position + Height is above the block and moving west, then I would check for the top collision first and then the left collision. However, if the Character's Y position + height is below the top of the block, I would check the left collision.
Now let's say you have a block that has incline. The block is 32 pixels wide, 32 pixels tall at x=32, 0 pixels tall at x=0. With this, you MUST assume that the character can only hit and collide with this block from the top to stand on. With this block, you can return a FALSE collision if it is a left/right/bottom collision, but if it is a collision from the top, you can state that if the character is at X=0, return collision point Y=0. If X=16, Y=16 etc.
Of course, this is all relative. You'll be checking against multiple blocks, so what you should do is store all of the possible changes into the character's direction into a temporary variable. So, if the character overlaps a block by 5 in the X direction, subtract 5 from that variable. Accumulate all of the possible changes in the X and Y direction, apply them to the character's current position, and reset them to 0 for the next frame.
Good luck. I could provide more samples later, but I'm on my Mac (my code is on a WinPC) This is the same type of collision detection used in classic Mega Man games IIRC. Here's a video of this in action too : http://www.youtube.com/watch?v=uKQM8vCNUTM
You can try to use one of physics engines, like Box2D or Chipmunk. They have own advanced collision detection systems and a lot of different bonuses. Of course they don't accelerate your game, but they are suitable for most of games on any modern devices
It is not that easy to create your own collision detection algorithm. One easy example of a difficulty is: what if your character is moving at a high enough velocity that between two frames it will travel from one side of a line to the other? Then your algorithm won't have had time to run in between, and a collision will never be detected.
I would agree with Tiendil: use a library!
I'd recommend Farseer Physics. It's a great and powerful physics engine that should be able to take care of anything you need!
I would do it this way:
Strictly no lines for collision. Only solid shapes (boxes and triangles, maybe spheres)
2D BSP, 2D partitioning to store all level shapes, OR "sweep and prune" algorithm. Each of those will be very powerfull. Sweep and prune, combined with insertion sort, can easily thousands of potentially colliding objects (if not hundreds of thousands), and 2D space partitioning will allow to quickly get all nearby potentially colliding shapes on demand.
The easiest way to make objects walk on surfaces is to make then fall down few pixels every frame, then get the list of surfaces object collides with, and move object into direction of surface normal. In 2d it is a perpendicular. Such approach will cause objects to slide down on non-horizontal surfaces, but you can fix this by altering the normal slightly.
Also, you'll have to run collision detection and "push objects away" routine several times per frame, not just once. This is to handle situations if objects are in a heap, or if they contact multiple surfaces.
I have used a limited collision detection approach that worked on very different basis so I'll throw it out here in case it helps:
A secondary image that's black and white. Impassible pixels are white. Construct a mask of the character that's simply any pixels currently set. To evaluate a prospective move read the pixels of that mask from the secondary image and see if a white one comes back.
To detect collisions with other objects use the same sort of approach but instead of booleans use enough depth to cover all possible objects. Draw each object to the secondary entirely in the "color" of it's object number. When you read through the mask and get a non-zero pixel the "color" is the object number you hit.
This resolves all possible collisions in O(n) time rather than the O(n^2) of calculating interactions.