Mirror a sprite with touchesBegan? - ios

Here is my current code:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
SKAction *moveNodeRight = [SKAction moveByX:-200.0 y:0.0 duration:0.7];
[_squirrelSprite runAction: moveNodeRight withKey:#"changeside"];
}
When I tap the screen I want my current sprite to mirror itself. If there isn't a way to mirror it, is there a way to change the sprite when the screen is tapped?
Also, when you tap the screen again I want the sprite to go back to it's original position on the screen and be flipped to the original sprite. Should I use code similar to this to determine which way it should go? Thank you!
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (isRightSide) {
//Change to sprite's position to the LEFT side
} else {
//Change to sprite's position to the RIGHT side
}
isRightSide = !isRightSide;
}

To horizontally mirror a SKSpriteNode's texture:
mySprite.xScale = -1.0;
To flip back and forth, in the touchesBegan use this code:
if(mySprite.xScale == -1.0)
{
mySprite.xScale = 1.0;
} else {
mySprite.xScale = -1.0;
}

Related

Spritekit how to run an SKAction depending on where a touch and hold is at

So I'm trying to implement a method into a game where if a player has their finger touching the screen at lets say 50 on the y axis or lower, an SKAction will run to move the character sprite down, and if their finger is touching above the 50, another action will run moving the sprite up. I don't know how you have it recognize a touch and hold though. Help please.
You will need to capture the touch event of the user in order to pull this off. I suggest checking out the excellent tutorial provided by RayWenderlich at: Animating Textures and Moving Them With Touch Events
If you don't have time for that this is what your code might look like:
First the knowledge that you will need is that the two most generic touch events are the:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
and the:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
Basically the touches began method is called when the user places their finger on the screen whereas the touches ended method will be triggered when the user takes their finger off the screen.
For this example I will use touchesEnded, but feel free to change it if you want, its as easy as switching the "Ended" with "Began".
All of the code I am about to show you will take place within the scenes implementation file:
If you just want the sprite to move up when above a certain point and down when below a certain point use the following:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//capture the location of the touch
CGPoint location = [[touches anyObject] locationInNode:self];
//used to hold the location to travel
CGPoint moveLocation;
//check if the Y location is less than 50
if(location.y < 50)
{
//the the location to the bottom of the screen
moveLocation = CGPointMake(sprite.position.x, 0);
}
//and then if its more than 50
else
{
//set the locaiton to the top of the screen
moveLocation = CGPointMake(sprite.position.x, self.frame.size.height);
}
//move the sprite
//Check if their already moving
if(sprite actionForKey:#"moving")
{
//If they are stop them so they can move in the new direction
[sprite removeActionForKey:#"moving"];
}
SKAction *moveAction = [SKAction moveTo:location duration:5.0f];
//remember to give the action a key so that we can check for it during the above if statement
[sprite runAction:moveAction withKey:#"moving"];
}
And there you have it. The only flaw is that it will always take 5 seconds to reach the location regardless of your distance from it, read on if you would like hints on how to correct that, or if you would like to see how to make the sprite travel to any touched location on the screen.
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//capture the location of the touch
CGPoint location = [[touches anyObject] locationInNode:self];
//move the sprite
//Check if their already moving
if(sprite actionForKey:#"moving")
{
//If they are stop them so they can move in the new direction
[sprite removeActionForKey:#"moving"];
}
SKAction *moveAction = [SKAction moveTo:location duration:5.0f];
//remember to give the action a key so that we can check for it during the above if statement
[sprite runAction:moveAction withKey:#"moving"];
}
That code will make it so that for 5 seconds the sprite will move to the location touched on the screen. Just remember to replace the instances of "sprite" with the name of your SKSpriteNode variable. For more complex movement try the following:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
//capture the location of the touch
CGPoint location = [[touches anyObject] locationInNode:self];
//set the velocity of the subject
float velocity = self.frame.size.width/3.0;
//The above will ensure that it will take the sprite 3 seconds to travel the distance of the screen
//Determine the difference between the point touched and the sprites position
CGPoint moveDifference = CGPointMake(location.x - sprite.position.x, location.y - sprite.position.y);
//Use pythagorean theorem to figure out the actual length to move
float distanceToMove = sqrtf(moveDifference.x * moveDifference.x + moveDifference.y*moveDifference.y);
//Use the distance to travel and the velocity to determine how long the sprite should move for
float moveDuration = distanceToMove / velocity;
//and finally move the sprite
if(sprite actionForKey:#"moving")
{
[sprite removeActionForKey:#"moving"];
}
SKAction *moveAction = [SKAction moveTo:location duration:moveDuration];
[sprite runAction:moveAction withKey:#"moving"];
}
That will set a velocity for the sprite, determine the length of the travel, and how long it will take to get to the new location.
If you want to involve textures I highly suggest reading the link I provided.
Upon request I would be glad to offer examples using forces to control movement speed as well.
I hope that helps, let me know if there are any problems I wasn't in a position where I could run the code but I am sure that it is fine.

How to create button in sprite kit iOS (similar to toggle button)

I am trying to make a button in sprite kit using SKSpriteNode. I want the button image to change when it is pressed and revert back to old image as soon as the press ends. What i have done till now is following:-
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
self.startTouch = [[touches allObjects][0] locationInNode:self ];
for (UITouch *touch in touches){
CGPoint position = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:position];
if ([node.name isEqualToString:#"missileButton"]) {
TEMissileButtonNode *button = (TEMissileButtonNode*) node;
button.isPressed = YES;
}
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches){
CGPoint position = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:position];
if ([node.name isEqualToString:#"missileButton"]) {
TEMissileButtonNode *button = (TEMissileButtonNode*) node;
button.isPressed = NO;
}
}
}
inside the update method i am calling this method to check if the touch has ended
-(void)changeMissileButton{
if (self.missileButton.isPressed) {
[self.missileButton addMoreMissileButtons];
[self.missileButton setTexture:[SKTexture textureWithImageNamed:#"missileButtonPressed"]];
}else{
[self.missileButton setTexture:[SKTexture textureWithImageNamed:#"missileButtonDeselected"]];
[self.missileButton hideMissileButtons];
}
}
The issue is that the touch doesn't get registered at times. Sometimes it works the way i want. When i touch it, its texture changes and when i remove my finger, the texture reverts back to old texture. But most of the times, the button doesn't react to my touch. Am i missing something?
Use touchesBegan, touchesMoved, touchesEnded.
touchesBegan - check if the button (SKSpriteNode) contains the touch. If so, change you button texture.
touchesMoved- if button does not contain touch, change texture back.
touchesEnded- if touch stayed within button during touchesMoved, change texture back.
Above is the logic for how to efficiently accomplish what you are trying to do. Yes, it is annoying Spritekit decided to abandon buttons.

How to make the sprite move positions when the screen is tapped

I would like my sprite to move from one side of the screen to the other like this:
Before tapped:
http://imgur.com/wIFa3JL
And then after the screen has been tapped:
http://imgur.com/ZtWiE7b
Would it start with something like this:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
Thank you!
I am not quite sure if you want to get the position of your finger when you touch the screen and apply to the sprite's position or just to change the position of the sprite when you touch the screen.
If you want to get your finger's position inside touchesBegan and apply that position to the sprite:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (UITouch *touch in touches) {
CGPoint location = [touch locationInView:self];
spriteNode.position = location;
}
}
If you want to just change the sprite's position to the opposite side of the tree every time you touch:
First you need to keep track of which side your sprite is currently. Let's create a BOOL to hold that info:
BOOL isRightSide;
Then, at the beginning, if your sprite start at the right side of the tree, just assign TRUE to the boolean.
Finally, in the touch event:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (isRightSide) {
//Change to sprite's position to the LEFT side
} else {
//Change to sprite's position to the RIGHT side
}
isRightSide = !isRightSide;
}
I hope this helps =)

How to add a Get Ready screen in spritekit

Hi I want to add a title or label that says Get Ready and when you tap it you start spawning custom sprites. Does any one know how to do this. As a reference I want the Get ready screen to act like Flappy Birds or Splashy Fish. Anywhere I can get info on this?
SKSpriteNode *getReady = [SKSpriteNode spriteNodeWithImageNamed:#"myImage.png"];
//remember to set position and other custom stuff here
[self addChild:getReady];
_isFirst = YES; //BOOL property
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (_isFirst)
{
SKAction *fadeOut = [SKAction fadeOutWithDuration:10];
[getReady runAction:fadeOut];
_isFirst = NO;
} else {
//other time you tap, code here
}
}
You need to creat a SKSpriteNode with the image you want and add to your scene.
SKSpriteNode *getReady = [SKSpriteNode spriteNodeWithImageNamed:#"myImage.png"];
//remember to set position and other custom stuff here
[self addChild:getReady];
Then when the user tap you can run an action to fade it out.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
SKAction *fadeOut = [SKAction fadeOutWithDuration:10];
[getReady runAction:fadeOut];
}
Also, I think you would be great if you check out some tutorials, cause that's really basic stuff. I'm sure you can easily find then.

rotate an image with touch

I making an app which sets the sleep timer with a clock .Basically it is clock which has a single hand which user can move to set his sleep time .I tried to rotate the image with uitouch but it rotates from middle but i want it to rotate from the tip.Secondly i want that the image only rotates when user is touching the tip of the image but in my project the image is also rotating when use touches any part of the screen.Also i want to rotate the image in both directions but in my project it moves only clockwise due to this method
image.transform = CGAffineTransformRotate(image.transform, degreesToRadians(1));
Can anybody give me hints or solutions about how can it be done?
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
//
touch = [[event allTouches] anyObject];
touchLocation = [touch locationInView:touch.view];
NSLog(#"began");
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
// get touch event
[image.layer setAnchorPoint:CGPointMake(0.0,0.0)];
if ([touch view] == image) {
image.transform = CGAffineTransformRotate(image.transform, degreesToRadians(1));
//image.center = touchLocation;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
NSLog(#"end");
}
In detail, you can custom a rotateView,then:
1: In the delegate method of "touchesBegan", get initialPoint of finger and initialAngle.
2: During "touchesMoved",get the newPoint of finger:
CGPoint newPoint = [[touches anyObject] locationInView:self];
[self pushTouchPoint:thePoint date:[NSDate date]];
double angleDif = [self angleForPoint:newPoint] - [self angleForPoint:initialPoint];
self.angle = initialAngle + angleDif;
[[imageView layer] setTransform:CATransform3DMakeRotation(angle, 0, 0, 1)];
3: At last, in "touchesEnded" you can calculate final AngularVelocity.
If anything being confused, for more detail, you can write back.
To rotate it the other way you just use:
image.transform = CGAffineTransformRotate(image.transform, degreesToRadians(1));
And to rotate form the tip you should use setAnchorPoint (like you used in your code, but i think you should do: [image setAnchorPoint]).
more on the subject: setAnchorPoint for UIImage?
I tried to rotate the image with uitouch but it rotates from middle but i want it to rotate from the tip
I dont know any way in SDK to rotate an element on its extreme end. If you want to have that effect take the clock handle image you have twice in length with half portion transparent. It is not a direct solution, but a workaround.
Also i want to rotate the image in both directions but in my project it moves only clockwise due to this method
As per iOS developer documentation, a positive angle value specifies counterclockwise rotation and a negative value specifies clockwise rotation.

Resources