I am trying to tile an SKTexture on a SKSpriteNode. From what I see this is not directly possible as answered here :
How do you set a texture to tile in Sprite Kit
Upon checking the reference I noticed that SKTexture has a textureByApplyingCIFilter method.
How could this be used to tile a certain SKTexture?
This is what I have tried:
SKTexture *tile = [SKTexture textureWithImageNamed:#"tile"];
CIFilter *tileTransform = [CIFilter filterWithName:#"CIAffineTile" keysAndValues:kCIInputImageKey, conveyorTexture, nil ];
CGAffineTransform xform = CGAffineTransformIdentity;
[tile setValue:[NSValue valueWithBytes:&xform
objCType:#encode(CGAffineTransform)]
forKey:#"inputTransform"];
tile = [tile textureByApplyingCIFilter:tileTransform];
Also what would be the memory consequences of using this solution as opposed to using multiple SKSpriteNode objects with the same SKTextures ?
You can just create an SKSpriteNode, set its texture, and set its filter property to your CIFilter. The inputImage property of the Filter is automatically set to the SKSpriteNode's texture. But remember to set its property shouldEnableEffects to YES.
Related
Trying to create a tiled background image for a top down game. The SKScene is 8000,8000 and instead of creating a couple very large sprites I am trying to tile it to improve performance.
var coverageSize = CGSizeMake(8000,8000);
var textureSize = CGRectMake(0, 0, 100, 100);
var backgroundCGImage = [UIImage imageNamed:#"bg"].CGImage; //this line returns several errors.
UIGraphicsBeginImageContext(CGSizeMake(coverageSize.width, coverageSize.height));
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextDrawTiledImage(context, textureSize, backgroundCGImage);
UIImage *tiledBackground = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
SKTexture *backgroundTexture = [SKTexture textureWithCGImage:tiledBackground.CGImage];
SKSpriteNode *backgroundTiles = [SKSpriteNode spriteNodeWithTexture:backgroundTexture];
backgroundTiles.yScale = -1;
backgroundTiles.position = CGPointMake(0,0);
[self addChild:backgroundTiles];
one way to do tiles is you create a node used to draw your tiles
You draw the amount of tiles that fits the screen into this special tile
use:
var texture = self.view!.textureFromNode(drawingTile, crop: CGRectMake(-column.width, -row.height, self.frame.width + column.width , self.frame.height + row.height));
To convert this node to a texture
now remove all nodes from the drawing node
add in the a new node to the drawing node using this texture.
we now have our background in one node.
when you need to scroll, shift the drawing node, then you draw the 1 row and 1 columns worth of tiles that are missing. Do this only when you need your drawing mode has shifted so much that you have a gap on the screen to fill in. Use the above code again to create a new drawing mode texture. Rinse, repeat
Is it possible to create a SKSpriteKitNode without a texture, add it to the scene and then set a texture to it?
I have tried creating node this way:
SKSpriteNode *node = [SKSpriteNode spriteNodeWithTexture: nil];
and then adding a texture:
node.texture = [SKTexture textureWithImage:image];
but this doesn't work.
Try:
SKSpriteNode* node = [SKSpriteNode node];
and then set the texture later on, but be sure to update the size:
node.texture = [SKTexture textureWithImage:image];
node.size = node.texture.size;
Alternatively, you can create a sprite node with color or texture and just set its hidden property to YES, or change its scale to 0.0 or change its size to 0 width/height or change its alpha to 0.0. So many things you can do to not show a (sprite) node ... ;)
We used below code to get sprite's collision area in cocos2d.
CGRect heroRect = [heroBird boundingBox];
if(CGRectContainsPoint(heroRect, bullet.position))
How to get boundingBox in sprite-kit?
Use the following line to get the bounding box:
CGRect heroRect = [heroBird calculateAccumulatedFrame]
see also Apple Docu
SKSpriteNode *heroBird;
heroBird = [SKSpriteNode spriteNodeWithImageNamed:#"heroBird.png"];
//heroBird rect can be set to whatever you like, shapes,rects,circles
heroBird.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:heroBird.size];
// set heroBird collision, category and contact bitmasks
// detect using didBeginContact method
CGRect heroRect = heroBird.frame;
I have the following sprite that falls to the bottom of the screen:
// The View
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
self.physicsWorld.contactDelegate = self;
// The Sprite
SKSpriteNode *cube = [[SKSpriteNode alloc] initWithImageNamed:#"cube"];
[cube setPosition:CGPointMake(160,250);
[self addChild:cube];
// The Physics
cube.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:cube.frame.size];
cube.physicsBody.dynamic = YES;
cube.physicsBody.affectedByGravity = YES;
cube.physicsBody.mass = 0.02;
Is there a way to make it so its sides are bulging when it hits the bottom border of the screen? Something that would be Jelly like or a soft body that still maintains its shape to some extent but bulges out under its own weight? I hope this makes sense....
Visit the site https://gist.github.com/kazukitanaka0611/4b9d4ac9dff0cd317b6c it have explanation and source code for soft bodies (jelly) in sprite kit
quick and easy way without math:
1 use flash to tween your box warping.
2 export the tweened frames as a sprite sheet (texture atlas)
3 animate the texture atlas on contact with an edge physics body in your scene.
your box will fall and on contact animate the separate images to give the impression its warping/bulging sides.
i used this method and it works - in other words it gives the desired effect, which in my view is what is important - your gamers don't care how you did it, as long as it looks great.
UIImageViews have a property called contentMode that you can use as
imageView.contentMode = UIViewContentModeScaleAspectFit;
and it will fill the entire view with your image without distorting, even if it has to bleed the image to do that.
Is there any similar stuff on Cocos2D? Sorry about the question, but I am new to Cocos2d.
I am creating the sprite like this:
CCTexture2D *textBack = [[CCTexture2D alloc] initWithImage:image];
CCSprite *sprite = [CCSprite spriteWithTexture:textBack];
thanks.
The equivalent method to performing a UIViewContentModeScaleAspectFit would be the .scale property. When a CCNode (or any of the sub nodes such as CCSprite etc.) is first created, the scale property is 1. Keep increasing it to scale the sprite up proportionally.
sprite.scale = 2.0f; // Scales the sprite proportionally at a factor of 2
As for it fitting to a specific size, you would have to write a routine:
Pass in desired rect and CCSprite bounding box rect.
Scale the box rect to aspect fit the desired rect.
Return the scaling factor
The result can then be applied to the CCSprite.scale property.
You can certainly scale the sprite to do that...
sprite.scale = ?
sprite.scaleX = ?
sprite.scaleY = ?
but I don't believe there is a function to automatically fill the entire screen. If you don't get a definitive reply here I would suggest posting on the Cocos2D forums (http://www.cocos2d-iphone.org/forum/).