How can I add a texture to a joint in SpriteKit? - ios

Maybe I could do it with the anchor points, but I don't really understand how I should do that.

The solution I'm building needs to have a SKSpriteNode with a texture for the joint, then add it as a child of one of the conjoining nodes, such that it covers the area the SKPhysicsJoint is operating on. Anytime I rotate the joint the texture rotates with it. I got the idea from action figures with hidden joints, basically, you're just putting something over the mechanical joint, in order to make for more pleasing aesthetics.
I don't know if this will work for you, but you could also define a texture using the centerRect of an existing texture and then define the part you want to paint on the joint node. This is more work than I wanted to put in, depending on your artwork assets this may be a good way to get around having another image in your bundle. I'm the artist as well as the programmer, so its faster for me to just create a joint image and add another node over the upper and lower nodes in the joint.

Joints can't have a texture. You can estimate or for some joints calculate where the connection point is by using the two connected body's positions and then put a sprite there (and continue to update the sprite's position).

Related

Can I change anchors or move images with ARKit and ARSK View?

I am trying to build a compass with ARKit, but I am having trouble with moving images. The compass is made up of 4 sprites for each of the cardinal directions, and they each hover one meter away from the camera in their specific locations. I would like the compass to surround the camera, so that even when the user moves, the compass still surrounds them. However, I do not know how to move the positions of these images after they are set for the first time.
I know it is possible to move nodes in an ARSCN View, but I am using an ARSK View, and as far as I know, it is impossible to move an anchor. In what way could I change the positions of the images if I do not move the anchor? Is this even possible with ARSK View, or should I give up and switch to ARSCN View?
Your use case suggests you don't really need elements that "move" in 3D, but elements whose 3D position is fixed relative to the camera. This sort of thing is trivial in a 3D framework like SceneKit, but much harder when you're trying to work in the space between ARKit (which mostly is concerned with world-relative positions) and a 2D framework that "fakes" a 3D effect for 2D content.
In SceneKit, you can make nodes follow the camera by making them children of the pointOfView node. Of course, that'll make them follow not just the camera's position but also orientation. If you want to selectively follow some aspects of the camera's transform but not others, you'd do well to combine node hierarchy with constraints — for example, a child of the camera node with a world space orientation constraint always returning identity, so that the node follows the camera's position but not its orientation.

is there a simple way to draw coordinates for SKnodes obstacles from images?

I am creating a game and I need to draw some obstacles on in (SKNodes), depending on the level (background image).
Let's say I have a tree, i would like to draw borders around it as in the picture below:
I will need the coordinates to create a physicsBody.
Is there a simple way to do it? (maybe a software?)
I will need to adapt the same coordinates for different devices, therefore I believe it's too complicated to manually do it.
Any ideas?
Thanks!
There is a SKPhysicsBody class method that could be of help:
+ bodyWithTexture:size:
From the description:
Use this method when your sprite has a shape that you want replicated
in its physics body. The texture is scaled to the new size and then
analyzed. A new physics body is created that includes all of the
texels in the texture that have a nonzero alpha value. The shape of
this body attempts to strike a good balance between performance and
accuracy. For example, fine details may be ignored if keeping them
would cause a significant performance penalty.
Check out this SKPhysicsBody Path Generator.
You can easily create a path as you desire with this tool (but make sure you read the rules at the top right)

How to find the normal vector of the contact point between two sprites

I am creating a game where the character can jump in the direction opposite of the surface he lands on. For example if he is on the ground he can only jump up. If he is on a right edge he can only jump left...etc etc.. Currently I have set up my SKNodes into leftWall, rightWall, bottomSurface, topSurface and have a huge if/else... this works but will become way more complicated as I add different surfaces with different angles etc...
I thought a better way to implement this would be to find the normal vector direction at the point of contact between the character sprite and a general wallNode sprites.
Can anyone help me determine A) the point of contact between sprites assuming the character has a circle physics body and the walls are always straight edges. and B) the normal to the contact point
thank you!
I don't think the vector or angle of impact will do you much good as your player's jump would likely be in an ark. As such, hitting the same surface at different points of the player's jump ark would yield different results.
I suggest you use unique category bit masks for your surfaces. A more advanced version of that would be to use only one category and utilize the SKSpriteNode's dictionary property to hold the angle value.
Based on the contact data you can then set the correctly angled jump for your player.

Get SKPhysicsBody to update as textures are animated (Swift)

So I've got an 'SKSpriteNode(texture: someTexture)' object that I run an 'SKAction' on which animates it (walking animation) with a couple of textures.
I set it's physicsBody using the texture parameter so that the physicsBody would be a perfect outline of my character, only thing is I can't quite figure out how to get the physicsBody to change as the texture changes (due to the animation).
I tried the obviously wrong choice of assigning the object a new SKPhysicsBody (in update method) with texture of object.texture (for current texture in animation), but that doesn't retain all the other properties I originally set. I searched for methods in the documentation for someway I could achieve this but found nothing.
What would be the best way to go about this?
Normally you would design your game such that the same physics shape applies to all animation frames. It often does not matter at all whether a human character's limbs are all properly outlined in the shape, generally a rectangle often suffices.
Your approach was correct btw, you would have to create a new physics body every time and you would have to copy over the properties of the previous body before you replace it with a new one. However that is not a good solution anyway because the internal state of the body can't be preserved, and different shapes will not case the now-animating physics shapes to have proper physics behavior. For example if the character is swinging a bat, hitting the ball, it would basically just move the ball away from the bat but not apply any force from the swinging motion.
In essence what you are trying to achieve is not (really) possible. Instead give the node a shape that is a good compromise over all animation frames. Typically it's best to use the smallest possible shape. Alternatively you could compose the character of multiple sprites to be able to compose it of multiple (connected) bodies.

Surface Detection in 2d Game?

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.

Resources