Move spritenode in a circle with controls - swift

How would I be able to move a SKSpriteNode along a circle while controlling the movement. For example, there are two buttons, left and right, and each one will make the SKSpriteNode move either clockwise around the circle or counter clockwise.
This is a great example of what I trying to accomplish. Notice how you move 'Trump'.
http://www.trumpsimulator.com/
This is what I have tried so far:
let circularMove = SKAction.followPath(circle.CGPath, asOffset: false, orientToPath: true, duration: 5)

Don't move the sprite node at all.
Place the node onto a parent node. (Call it a layer or something).
Now rotate the layer.
If you place the sprite off centre then it will follow a circle with a radius of the distance of the sprite from the centre of the layer.
Now you don't need to worry about paths or anything. Just update the rotation angle each update.

Related

Collision without sprites colliding

I have some simple code that adds a block sprite at the leftmost part of a tile like this :
block.position = CGPointMake((-self.size.width * 0.5), 0);
[self addChild:block];
Since the anchor point is in the middle of the block sprite. self refers to the actual tile.
This works fine and indeed adds the block on the left side of the tile sprite.
Now I also have a player sprite that can collide with that block if it tries to go through it. That also works just fine.
The problem happened when i tried to get the block sprite to show in the exact same spot using another anchor point (i need a new anchor point for a shrink effect i wanted to create - which appears to work fine btw).
The new code becomes :
block.position = CGPointMake(-(self.size.width * 0.5), -(self.size.width * 0.5));
block.anchorPoint = CGPointZero;
[self addChild:block];
The new block appears in a similar to the first case position (though not totally identical).
I am not sure why the position is not identical but i can fix that by adding/subtracting 1 or 2 from the x,y points.
The weird problem is that if my player sprite now tries to go below that block on the tile below (which is an open tile without any blocks), i get a contact between the player and the block.
I have even added debug paths with SKShapeNode to make sure that the player and block sprites do not actually collide. And they don't ! But i still get a collision event.
The player scale is (0.8, 0.9), but i don't think this would play much of a role.
I really don't get why this could be happening. Any ideas guys ?
Changing the sprite's anchor point have no effect on the physics body.
When talking about CGRect, the rect origin is at point {0, 0},
So what is happening is that you now have a sprite that its image is centred around anchor point {0, 0} but with a physics body, that starts at {0, 0} and is the size of the sprite, meaning that it is centred around {0.5, 0.5}.
So even that the player doesn't collide with the image of the sprite, it does collide with its physics body.
What is happening is that you have a physics body, that before had the same centre point as the sprite,
But as oppose to before, where the sprite anchor point were in the middle, which would 'fit' into the physics body,
Now the sprite's anchor point is {0, 0}, which causes the physics body centre point, to actually be the most bottom left point of the sprite.
To resolve this, you need to offset your physics body, so it will be centred around the new anchor point.
For example:
block.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:block.size center:CGPointZero];
CGPoint newCenter = CGPointMake(block.size.width, block.size.height);
block.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:block.size centre:newCenter];
Good luck mate.
EDIT- On a second thought, I think I got confused with the offset directions.
An edit has been made to correct it.

Why is the coordinate system in sprite kit flipped and can I change that globally?

I noticed that in Sprite Kit the coordinate system is flipped.
For example, here is a SKSpriteNode:
SKSpriteNode *car = [SKSpriteNode spriteNodeWithImageNamed:#"car"];
car.position = CGPointMake(0, 0);
[road addChild:car];
The car is positioned in the center of it's parent.
When I set position to:
car.position = CGPointMake(-50, 0);
then it is positioned more to the left.
But when I want to move it down, and increase Y, it moves UP!
car.position = CGPointMake(-50, 20);
In UIKit increasing Y always means something moves down. It feels more logical to me. Is there a way to flip the coordinate system in Sprite Kit?
You can set your scene's yScale property to -1. Everything will render upside down, but you can also set the yScale property for each node to -1, which will cause them to render right side up.
You could also make a class category and create a property called invertedPosition with a custom getter/setter that inverts the default position property.
Sprite Kit uses a coordinate orientation that starts from the bottom left corner of the scene (0,0), and the values increase as you move to the right (increasing x) and up (increasing y).

In the SpriteKit framework, how can I make a sprite point in the direction a sprites PhysicsBody is going?

I have a sprite moving around the scene, that has physics. I want to create a motion blur effect, but I am stuck on getting it so that the SKSPriteNode with the blurred image is pointing in the right way.
The SKPhysicsBody has a velocity and angularVelocity property. Those properties can be used to determine your direction for this purpose.
You can use the zRotation property of any SKNode to adjust it's rotation to get the proper facing.
You could do something like this.
-(void)didSimulatePhysics {
if (node.physicsBody.velocity.dx!=0 || node.physicsBody.velocity.dy!=0)
node.zRotation = atan2(node.physicsBody.velocity.dy, node.physicsBody.velocity.dx);
}
If you use an SKAction there is a parameter called OrientToPath. This will align your object with the path it is on. All you have to do initially is ensure the orientation starts in the right position.
SKAction.followPath(cgpath, asOffset: false, orientToPath: true, duration: 5)

stick a sprite to another when it collide with it

so I have a sprite that is created every second and that is moving at a random position (sprite1) and another sprite that has a fixed position (sprite2). I would like that when sprite1 collide with sprite2, sprite1 is like sticked to it (it stops moving and is sticked to it) . How can I do this please ? sorry for my english I'm french :/
p.s : sprite2 is rotating with accelerometer, so if sprite1 collide with it I would like that it rotate too :)
I think, you can try to use box2d to do this. It will help to detect collisions and to manage rotations, movement, etc.
I think, you can do it simply in Cocos2d.
1) First set the rect for sprite1 and sprite2 using CGRectMake(x,y,width,height)
2) As you told sprite1 is moving at random position and sprite2 is fixed to particular position, you can check them collide by using CGRectIntersectsRect([sprite1 bounds],[sprite2 bounds]).
3) if it intersects, set sprite1.position = sprite2.position
Note: you said sprite1 is rotating, rect can be fit only to the regular bodies. if you want exact collision or physical properties for sprite better you can go for box2d.
If you don't want to use Box2d (which can handle circle collisions), you can try something like this:
1.) Detect collision, is the distance between the two circles center point (x,y), less than the sum of the two circles radius.
2.) Make the Sprite1 stick to Sprite2, Stop the movement of Sprite1, and save the relative delta (x,y) to Sprite2, then whenever Sprite2 moves or rotates apply the same delta movement and rotation to Sprite1.

Cocos2D iPhone - screen coordinates x sprite's internal coordinates

I am new to Cocos2D on iPhone. I see that Cocos2D uses a coordinate axis where 0,0 is at the bottom left corner and X positives are to the right and Y positives up.
Now I have created a sprite and added several sprites as subsprites of this one. For my surprise the subsprites appear mirrored in Y!!! The point 10,10 will be on the upper left corner of the sprite!!!
I can simply flip the sprite in Y to make it follow the same screen coordinate, but then the content will be reversed.
Is this a bug or what?
thanks.
Without seeing any example code is a shot in the dark, but I think you need to use Anchor points.
Each sprite has an anchor point of x, y.
ccp(0.5f, 0.5f) would be the center of the sprite.
(0,0) is the bottom left....(1.0f,1.0f) is top right etc.... Over 1.0 goes outside the sprite.
Child nodes (CCSprite) will use their anchor point on the parent node coordinates.
MySprite.anchorPoint = ccp(0.5f,0.5f);