Set size for SKTexture - ios

How do I set a size for a SKTexture Ive gone through the documentation Class Reference I don't see anything about being able to set the size. I know the size method is a return method but just to make it clear what I'm trying to do its in my code below.
_bomb = [SKSpriteNode spriteNodeWithImageNamed:#"Bomb5.gif"];
SKTexture *Bomb5 = [SKTexture textureWithImageNamed:#"Bomb5.gif"];
Bomb5.size = CGSizeMake(40, 40);
SKTexture *Bomb4 = [SKTexture textureWithImageNamed:#"Bomb4.gif"];
Bomb4.size = CGSizeMake(40, 40);
SKTexture *Bomb3 = [SKTexture textureWithImageNamed:#"Bomb3.gif"];
Bomb3.size = CGSizeMake(40, 40);
SKTexture *Bomb2 = [SKTexture textureWithImageNamed:#"Bomb2.gif"];
Bomb2.size = CGSizeMake(40, 40);
SKTexture *Bomb1 = [SKTexture textureWithImageNamed:#"Bomb1.gif"];
Bomb1.size = CGSizeMake(40, 40);
SKTexture *explostion = [SKTexture textureWithImageNamed:#"explosionnn.gif"];
explostion.size = CGSizeMake(90, 90);
//5 second countdown and the bomb explodes
countdown = [SKAction animateWithTextures:#[Bomb5,Bomb4, Bomb3, Bomb2, Bomb1, explostion] timePerFrame:1];
Another solution?: Maybe I could add actions in sequence where after the 5 second countdown I can change the size of the spriteNode instead when it reaches the last animation image. But if I were to do it this way how do I change the size of the image from the centre origin of where the bomb is?

You are right: You cannot change the size of the texture, as the texture essentially is the image: "An SKTexture object is an image that can be applied to SKSpriteNode objects or particles created by a SKEmitterNode object." (from the documentation).
Have you considered having a separate sprite for the explosion? Then you can simply replace the countdown-sprite with this when the countdown has reached zero. If you put a factory-class to create your sprites this will also save you a lot of hassle if you want to use the same explosion elsewhere in your game...

Related

How to generate SKTexture from a modified SKSpriteNode?

So I have an SKSpriteNode which has undergone two SKActions which modify it's shape and coloring however I want to return the modified SKSpriteNode as an SKTexture which I can apply to another SKSpriteNode. This is what I'm currently using.
1) Generate the "modified" laserNode and store it as a property
-(void)generateLaserSprite
{
SKSpriteNode *laserNode = [SKSpriteNode spriteNodeWithTexture:[SKTexture textureWithImageNamed:#"Laser.png"]];
[laserNode runAction:[SKAction group:#[[SKAction colorizeWithColor:[SKColor redColor] colorBlendFactor:100 duration:0.0],
[SKAction scaleXBy:0.4 y:0.7 duration:0.0],
]]];
_laserSprite = laserNode
}
2) Then a method from the SKScene calls this method to retrieve a copy of the property
-(SKSpriteNode*)retrieveLaserSprite
{
SKSpriteNode *laserNode = [_laserSprite copy];
laserNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(laserNode.size.width*0.8, laserNode.size.height*0.8)];
//other laserNode.physicsBody modifications
return laserNode;
The problem with this currently is that when I call the second method (retrieveLaserSprite), the returned LaserNode then shows up on screen as the original image (pre-SKAction), and then you can visibly see the SKActions take place on-screen.
It should actually be possible to create a texture from a sprite whose rendering properties have been modified using the -(SKTexture *)textureFromNode: method of the SKView class.
Your code would go like this:
-(SKSpriteNode*)retrieveLaserSprite {
SKTexture *tempTexture = [self.view textureFromNode:_laserSprite];
SKSpriteNode *laserNode = [SKSpriteNode spriteNodeWithTexture:tempTexture];
laserNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(laserNode.size.width*0.8, laserNode.size.height*0.8)];
//other laserNode.physicsBody modifications
return laserNode;
}
You should be able to accomplish this task using something like:
-(SKSpriteNode*)retrieveLaserSprite
{
SKTexture *texture = [self.view textureFromNode:[_laserSprite copy]];
SKSpriteNode *laserNode = [SKSpriteNode spriteNodeWithTexture:texture];
laserNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(laserNode.size.width*0.8, laserNode.size.height*0.8)];
//other laserNode.physicsBody modifications
return laserNode;
}

(Spritekit) iPad resolution not 1024x768?

I'm trying to set a background texture and I want it to cover the entire screen.
I prepared the background files exactly to size in photoshop before hand. There are 2 files in my project:
background.png - 1024x768px
background#2x.png - 2048x1536px
I am running the following code:
SKTexture *backgroundTexture = [SKTexture textureWithImageNamed:#"background"];
SKSpriteNode *background = [SKSpriteNode spriteNodeWithTexture:backgroundTexture];
background.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
background.size = CGSizeMake(750, 550);
[self addChild:background];
And it is giving me this result http://d.pr/i/Ej2m - notice that the entire screen is almost filled and the background size is background.size = CGSizeMake(750, 550). Why is this?
You manually changed the sprite's size:
background.size = CGSizeMake(750, 550);
So it will display in a smaller region (750x550) than its original size (1024x768). Allow me to say: d'uh! ;)

How to change a characters image in 'touchbegan' in spritekit?

I'm currently using Sprite Kit and Xcode to design a game. My character is usually in the state of running which consists of two images - code below:
bobSKTexture* Texture1 = [SKTexture textureWithImageNamed:#"bob1"];
bobTexture1.filteringMode = SKTextureFilteringNearest;
SKTexture* bobTexture2 = [SKTexture textureWithImageNamed:#"bob2"];
bobTexture2.filteringMode = SKTextureFilteringNearest;
SKAction* run = [SKAction repeatActionForever:[SKAction animateWithTextures:#[birdTexture1, birdTexture2] timePerFrame:0.2]];
_bob = [SKSpriteNode spriteNodeWithTexture:birdTexture1];
[_bob setScale:2.0];
_bob.position = CGPointMake(self.frame.size.width / 4, CGRectGetMidY(self.frame));
[_bob runAction:run];
I want the image to change when a touch to the screen happens, only for a short amount of time and then I want it to return to the above code. How can I accomplish this?
As Jānis K said, it would be even easier to do like this when you want the image to change:
[_bob removeAllActions];
_bob.texture = [SKTexture textureWithImageNamed:NEW_TEXTURE];
[self performSelector:#selector(resetAnimation) withObject:nil afterDelay:2.0f];
NEW_TEXTURE is the name of the texture/image you want it to change to.
self would be the scene or wherever you call the code to make _bob
This is the resetAnimation method, defined in your scene or wherever you call the code to make _bob:
- (void)resetAnimation
{
SKAction* run = [SKAction repeatActionForever:[SKAction animateWithTextures:#[birdTexture1, birdTexture2] timePerFrame:0.2]];
[_bob runAction:run];
}

How to preload textures in Sprite Kit?

I have a few frames of animations on my node, and the first time I play the animation it lags, fps drops. Each next time is fine and dandy.
How do I preload the textures to make it work smooth?
I have this method to run when I load the game:
- (void)load
{
self.animationFrames = #[[SKTexture textureWithImageNamed:#"exp1"], [SKTexture textureWithImageNamed:#"exp2"],
[SKTexture textureWithImageNamed:#"exp3"], [SKTexture textureWithImageNamed:#"exp4"], [SKTexture textureWithImageNamed:#"exp5"], [SKTexture textureWithImageNamed:#"exp6"], [SKTexture textureWithImageNamed:#"exp7"], [SKTexture textureWithImageNamed:#"exp8"], [SKTexture textureWithImageNamed:#"exp9"]];
}
And this method to play animation:
-(void)playExplosionAnimation
{
self.size = CGSizeMake(250, 250);
SKAction *animation = [SKAction animateWithTextures:self.animationFrames timePerFrame:0.1];
[self runAction:animation completion:^{
self.hidden = YES;
}];
}
You should create a texture atlas and use SKTextureAtlas methods:
– preloadWithCompletionHandler:
+ preloadTextureAtlases:withCompletionHandler:
Here is what documentation says about this:
Sprite Kit creates a background task that loads the texture data from
the atlas. Then, Sprite Kit returns control to your game. After the
texture atlas is loaded, your completion handler is called.
If you need to preload multiple texture atlases at once, use the
preloadTextureAtlases:withCompletionHandler: method instead.

SKTexture from UIImage looks different

I'm playing around with SpriteKit and I'm creating a SKTexture from an UIImage, then using SKSpriteNode to add the child to my SKScene (As a background), everything works fine, except that the UIImage looks very different from the original image, I tried to recreate the image in photoshop and the issue still remains, tested on Simulator and real device and different image colors, no changes.
The image format is PNG, and I added through Images.xcassets in Xcode 5
Image, results:
Different image, results:
I'm using the following code in my SKScene subclass:
- (id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size]) {
SKTexture *textureGradient = [SKTexture textureWithImage:[UIImage imageNamed:#"Image"]];
SKSpriteNode* spriteGradient = [SKSpriteNode spriteNodeWithTexture:textureGradient];
[self addChild:spriteGradient];
}
return self;
}
What I'm doing wrong?
Any help would be appreciated. :)
Solution:
It was my fault, the image position was wrong, so I changed the position property:
SKTexture *textureGradient = [SKTexture textureWithImage:[UIImage imageNamed:#"Image"]];
SKSpriteNode* spriteGradient = [SKSpriteNode spriteNodeWithTexture:textureGradient];
spriteGradient.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));
[self addChild:spriteGradient];

Resources