If I Have a SKSpriteNodes Moving From Right To Left With This Code
CGFloat distanceToMove = self.frame.size.width + 2 * _pipeTexture1.size.width;
SKAction* movePipes = [SKAction moveByX:-distanceToMove y:0 duration:0.01 * distanceToMove];
SKAction* removePipes = [SKAction removeFromParent];
_movePipesAndRemove = [SKAction sequence:#[movePipes, removePipes]];
The Question Is How To Make These SKSpriteNodes Moving From Ù’Upper To Lower , What I Have To Use .Thanks
Related
In a SpriteKit game, I am using a forever repeating SKAction moveTo: to display metal shine/shimmer on a sprite. It's basically an SKCropNode mask that moves from one position to another, pauses, moves back to it's starting position, and repeats. The maskNode itself animates in the reverse direction.
This works fine, even with hundreds of them on the screen running for hours.
However, when the app goed to the background and comes back, all the positions of these nodes have changed. The animations still continue, but at the wrong positions. Metal shimmer everywhere on the screen, except where it should be.
I am not changing anything in the UIApplication delegate methods. Even if I pause the SKView while the app is in the background, the exact same thing happens.
// create the shine node
SKSpriteNode *shine = [SKSpriteNode spriteNodeWithTexture:#"metal_shine"];
shine.size = self.size;
// create the mask node
SKSpriteNode *maskNode = [SKSpriteNode spriteNodeWithTexture:#"disk_mask"]];
maskNode.size = self.size;
// create the crop node
SKCropNode *cropNode = [[SKCropNode alloc] init];
[cropNode addChild:shine];
cropNode.maskNode = maskNode;
cropNode.maskNode.position = CGPointMake(self.size.width * 0.5, self.size.height * -0.5);
cropNode.position = CGPointMake(self.size.width * -0.5, self.size.height * 0.5);
[self addChild:cropNode];
// add actions
SKAction *delayAction = [SKAction waitForDuration:1.0];
SKAction *pauseAction = [SKAction waitForDuration:3.0];
SKAction *resetActionMaskNode = [SKAction moveTo:CGPointMake(self.size.width * 0.5, self.size.height * -0.5) duration:0];
SKAction *moveActionMaskNode = [SKAction moveTo:CGPointMake(self.size.width * -0.5, self.size.height * 0.5) duration:0.6];
SKAction *resetActionCropNode = [SKAction moveTo:CGPointMake(self.size.width * -0.5, self.size.height * 0.5) duration:0];
SKAction *moveActionCropNode = [SKAction moveTo:CGPointMake(self.size.width * 0.5, self.size.height * -0.5) duration:0.6];
SKAction *repeatActionMaskNode = [SKAction repeatActionForever:[SKAction sequence:#[resetActionMaskNode, moveActionMaskNode, pauseAction]]];
SKAction *repeatActionCropNode = [SKAction repeatActionForever:[SKAction sequence:#[resetActionCropNode, moveActionCropNode, pauseAction]]];
// go
[cropNode.maskNode runAction:[SKAction sequence:#[delayAction, repeatActionMaskNode]] withKey:#"idleAnimation"];
[cropNode runAction:[SKAction sequence:#[delayAction, repeatActionCropNode]] withKey:#"idleAnimation"];
I have a circle spawning every few seconds and I have five lanes that I want them to spawn into but I want it to go to a different one at random. The code I'm using works properly but it won't let me use my five x positions? I've tried multiple solutions but they won't work. I'm still new to objective c so any help would be appreciated. (Also the code below isn't my whole method obviously but it's the only part I need to show.)
#import "GameScene.h"
int xPos1;
int xPos2;
int xPos3;
int xPos4;
int xPos5;
#implementation GameScene
-(void) addBall:(CGSize) size{
xPos1 = 8.5;
xPos2 = 74;
xPos3 = 138;
xPos4 = 203;
xPos5 = 267.5;
CGRect box = CGRectMake( arc4random() , self.frame.size.height, //pos
45, 45); //size
UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:box];
SKShapeNode *circle = [SKShapeNode node];
circle.path = circlePath.CGPath;
circle.fillColor = [SKColor colorWithRed:(243.0f/255) green:(134.0f/255) blue:(48.0f/255) alpha:1.0];
circle.strokeColor = nil;
circle.lineWidth = 3;
//add physics
circle.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:circle.frame.size.width/2];
//appy actions to move sprite
SKAction *wait = [SKAction waitForDuration:2];
SKAction *move = [SKAction moveToY:-self.size.height - 50 duration:2];
SKAction *remove = [SKAction removeFromParent];
SKAction *sequence = [SKAction sequence:#[wait, move, remove]];
SKAction *repeat = [SKAction repeatActionForever:sequence];
SKAction *spawn = [SKAction performSelector:#selector(addBall:) onTarget:self];
SKAction *delay = [SKAction waitForDuration:2.5];
SKAction *spawnThenDelay = [SKAction sequence:#[delay, spawn]];
[self runAction:spawnThenDelay];
[circle runAction:repeat];
[self addChild:circle];
}
Here are the different things I've tried using the x positions in arc4random:
CGRect box = CGRectMake( arc4random() %(xPos1, xPos2, xPos3, xPos4, xPos5) , self.frame.size.height, //pos
45, 45);
CGRect box = CGRectMake( arc4random(xPos1, xPos2, xPos3, xPos4, xPos5) , self.frame.size.height, //pos
45, 45);
I've also tried just putting the integers directly in there...
Try by creating an array of X Positions and selecting from that using a random index.
CGFloat xPositions[5] = {8.5,74,138,203,267.5};
int randomIndex = arc4random() % 5;
int randomXPosition = xPositions[randomIndex]
CGRect box = CGRectMake(randomXPosition, self.frame.size.height, 45, 45);
UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:box];
as you can see below, i try to run an action which increases the size of my ScoreLabel, whenever the score increases. When i run my app, i realized, that the size of my label doesn't set back to his original form. I tried many ways, but couldnt realize it
I hope for you quick answers
-(void)update:(CFTimeInterval)currentTime{
/* Called before each frame is rendered */
// Update wird vor jeden Frame aufgerufen
// Score Counter
if( [speerArray count] > 1) {
SKSpriteNode *sprite = [speerArray objectAtIndex:1];
if (sprite.position.y < superhero.position.y && [sprite.name isEqualToString:#"speer"] && sprite.position.y > 0) {
SKAction* scoreAction = [SKAction scaleBy:2 duration:1];
score ++;
[scoreLabel runAction:scoreAction];
scoreLabel.text = [NSString stringWithFormat:#"%d", score/2];
sprite.name = #"afterBird";
}
}
Using the following lines might be what you are looking for:
[scoreLabel removeAllActions];
SKAction* scoreAction = [SKAction scaleBy:2 duration:1];
SKAction* revertAction = [SKAction scaleTo:1 duration:1];
SKAction* completeAction = [SKAction sequence:#[scoreAction, revertAction]];
[scoreLabel runAction:completeAction];
You can put in a waitForDuration: action as well, if required.
How to repeat this action 3 or 2 times instead of repeating it forever
SKLabelNode *label = [SKLabelNode labelNodeWithFontNamed:#"AmericanTypewriter-Bold"];
label.text = #"Boom";
label.fontColor = [SKColor blackColor];
label.fontSize = 90;
label.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame)+25);
SKAction *disappear = [SKAction fadeAlphaTo:0.0 duration:0.2];
SKAction *appear = [SKAction fadeAlphaTo:1.0 duration:0.2];
SKAction *pulse = [SKAction sequence:#[disappear,appear]];
[label runAction:[SKAction repeatActionForever:pulse]];
[self addChild:label];
You need to use SKAction's repeatAction:count: method documented here.
[label runAction:[SKAction repeatAction:pulse count:3]];
I don't really know where to start. I have an image of a circle stored in an SKSpriteNode and a physicsBody that mirrors the size when it is created.
I am using an SKAction to scale down the size of the image though, and the physicsBody remains the same size. How can I scale down the physicsBody?
My code:
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:#"whiteball"];
sprite.size = CGSizeMake(20, 20);
sprite.position = CGPointMake(dx, CGRectGetHeight(self.frame)-dy);
sprite.name = #"ball";
sprite.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:sprite.size.width/2];
[self addChild:sprite];
SKNode *ballNode = [self childNodeWithName:#"ball"];
if (ballNode != Nil){
ballNode.name = nil;
SKAction *delay = [SKAction waitForDuration:3];
SKAction *scale = [SKAction scaleTo:0 duration:1]; // I want this to scale the physicsBody as well as the spriteNode...
SKAction *remove = [SKAction removeFromParent];
//put actions in sequence
SKAction *moveSequence = [SKAction sequence:#[delay, scale, remove]];
//run action from node (child of SKLabelNode)
[ballNode runAction:moveSequence];
}
If you set the size of the physicsbody to the size of the circle, you may achieve what you seek.
_circle = [SKSpriteNode spriteNodeWithImageNamed:#"cirlce"];
_circle.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:_circle.size.width/2];