So I have sprites, which are generated randomly in the screen and are then given random movements via SKAction.
For example:
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:#"Icicle.png"];
sprite.position = CGPointMake (randomX, 0); //randomX is a random integer between 0 and screen width
SKAction *action = [SKAction moveToY:-200 duration:2];
[sprite runAction:action];
[self addChild:sprite];
Now in my touches began method:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
}
What I am seeing is that my nodes are not getting selected very accurately. The Icicle images have a buffer width of 20 pixels around all four sides.
Does being in the middle of an SKAction, make node selection via tapping inaccurate?
Moreover, any suggestions on how to select nodes that are constantly moving via a touchesbegan method?
Related
How can I drag and move sprites with touch in sprite kit but in a grid manner? I can already move them on touch, but I need to simulate a tiledmap...
Override the method in your SKScene:
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
Then when you receive messages in this, just check the position with:
UITouch *touch = [touches anyObject];
if(touch){//
CGPoint location = [touch locationInNode:self];
.. moving code here
}
Once you have your position, just move it based upon which grid item the touch is currently within:
//Grid of 20x20 pixels, with entire grid starting at 0,0
static const CGFloat GridSize = 20;
int gridColumn = (int)(location.x/GridSize); //we can lose the precision here
int gridRow = (int)(location.y/GridSize); //we can lose the precision here
node.position = CGPointMake(gridColumn*GridSize, gridRow*GridSize);
Of course you could animate the move with an SKAction, but if you're tracking a touch, you probably want it in realtime.
I'm using Sprite Kit to create my first iOS app, and I'm stumbling over what seems to be a pretty basic problem.
I'm trying to animate the contents (fillNode) of a SKCropNode (cropNode). The code below sets up the SKScene just fine (I see the illustration masked correctly, placed over the background image in the right location)...
SKSpriteNode *logoBG = [[SKSpriteNode alloc] initWithImageNamed:logoBackground];
logoBG.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:logoBG];
SKCropNode *cropNode = [[SKCropNode alloc] init];
cropNode.maskNode = [[SKSpriteNode alloc] initWithImageNamed:logoMask];
SKSpriteNode *fillNode = [[SKSpriteNode alloc] initWithImageNamed:logoImage];
[cropNode addChild:fillNode];
fillNode.position = CGPointMake(0,300);
cropNode.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
self.logoContent = cropNode;
[self addChild:self.logoContent];
...but I can't access the masked illustration to animate its position (I want it to start off outside the mask and slide into position):
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
SKAction *moveUp = [SKAction moveByX: 0 y: 100 duration: 5];
SKAction *moveSequence = [SKAction sequence:#[moveUp]];
[self.logoContent.target_illustration runAction: moveSequence completion:^{ // '.target_illustration' = the SKSpriteNode that I want to animate; cropNode.fillNode
SKScene *titleScreen = [[TitleScreen alloc] initWithSize:self.size];
SKTransition *fade = [SKTransition fadeWithDuration:(1)];
[self.view presentScene:titleScreen transition:fade];
}];
I can only animate the whole logoContent rather than its child nodes.
Any ideas where I'm going wrong?
Just for reference if anyone wants to know how to mask, here is a simple snippet
- (void) cropNodes
{
// the parent node i will add to screen
SKSpriteNode *picFrame = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(100, 100)];
picFrame.position = CGPointMake(200, 200);
// the part I want to run action on
SKSpriteNode *pic = [SKSpriteNode spriteNodeWithImageNamed:#"Spaceship"];
pic.name = #"PictureNode";
SKSpriteNode *mask = [SKSpriteNode spriteNodeWithColor:[SKColor blackColor] size:CGSizeMake(80, 50)];
SKCropNode *cropNode = [SKCropNode node];
[cropNode addChild:pic];
[cropNode setMaskNode:mask];
[picFrame addChild:cropNode];
[self addChild:picFrame];
// run action in this scope
//[pic runAction:[SKAction moveBy:CGVectorMake(30, 30) duration:10]];
// outside scope - pass its parent
[self moveTheThing:cropNode];
}
- (void) moveTheThing:(SKNode *) theParent
{
// the child i want to move
SKSpriteNode *moveThisThing = (SKSpriteNode *)[theParent childNodeWithName:#"PictureNode"];
[moveThisThing runAction:[SKAction moveBy:CGVectorMake(30, 30) duration:10]];
}
Got it!
[self.logoContent.target_illustration runAction: moveSequence completion:^{
should be
[self.logoContent.children[0] runAction: moveSequence completion:^{
My illustration now moves as directed :)
Im wondering how to do this. How can i make it so that when a user taps and HOLDS my sprite they can drag it across the x axis only, maintaining the same y value?
Follow this tutorial
http://www.raywenderlich.com/2343/how-to-drag-and-drop-sprites-with-cocos2d
When it sets the position of the sprite instead of setting the y position to that of the touch, just set it to a fixed value where you want it.
Where ever you handle your touches:
if (CGRectContainsPoint(sprite.rect, touchLocation)){
sprite.position = ccp(touchLocation.x,sprite.position.y);
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *Drag = [[event allTouches] anyObject];
CGPoint CurrentPosition = [Drag locationInView:self.view];
CurrentPosition.x = Sprite.center.x;
Sprite.center = CurrentPosition;
}
I created a slider like this: https://github.com/Antem/Custom-Slider-xCode
I am fairly new to touch event and i have a problem. I use the code above to drag two images on screen. The code works however when the the second finger touches the screen the first movement stops. So, the problem is related to multi-touch. I also, do not know how to calculate the second touches co-ordinates. I enabled multitouch in the view and in both images. I would be great full if somebody could help me move each image with each finger.
Thanks in advance!
-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [[event allTouches] anyObject];
CGPoint location = [touch locationInView:self.view];
if ([touch view] == image) {
image.center = location;
} else if ([touch view] == image2) {
image2.center = location;
}}
-(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
[self touchesBegan:touches withEvent:event];}
I would recommend using a custom UIGestureRecognizer for that. It will give you an nice encapsulated way to manage what you want. Dragging two images at the same time is in essence a gesture.
I'm working on a touch draw app, everything is working fine in portrait, but when i rotate my iPad the line i draw when touching is 5 cm above my finger.
iv been googling a lot to try and find out how x & y changes when rotating.
can any of you help me ?
my code for drawing it this:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
mouseSwiped = YES;
UITouch *touch = [touches anyObject];
CGPoint currentPoint = [touch locationInView:self.view];
currentPoint.y -= -20;
UIGraphicsBeginImageContext(self.view.frame.size);
[drawImage.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
CGContextSaveGState(UIGraphicsGetCurrentContext());
CGContextSetShouldAntialias(UIGraphicsGetCurrentContext(), YES);
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound);
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy);
CGContextSetLineWidth(UIGraphicsGetCurrentContext(), f5);
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), f1, f2, f3, f4);
CGContextBeginPath(UIGraphicsGetCurrentContext());
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y);
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y);
CGContextStrokePath(UIGraphicsGetCurrentContext());
drawImage.image = UIGraphicsGetImageFromCurrentImageContext();
CGContextRestoreGState(UIGraphicsGetCurrentContext());
UIGraphicsEndImageContext();
lastPoint = currentPoint;
mouseMoved++;
if (mouseMoved == 10) {
mouseMoved = 0;}}
I was using bounds in my appDelegate and frame in my draw code ...
i changed it to:
UIGraphicsBeginImageContext(self.view.bounds.size);
[drawImage.image drawInRect:CGRectMake(0, 0, self.view.bounds.size.width,self.view.bounds.size.height)];