removing sprites of lost reference from page in cocos 2d - sprite

I am using a single sprite again and again (requirement of program) for different animations on different touch location and keeping the final image after each animation on screen [sprite spriteWithSpriteFrameName:#"abc.png"] .
Now problem is that after completion of all animation i want to remove all done animation's final image from screen but due to using same sprite again and again sprite has only reference of last done animation and using [sprite removeFromParentAndCleanup:true] only remove last done animation.Please help me to remove all done animation spriteFrame.
here is sample code
-(void)draw1
{
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"a.plist"];
// Create a sprite sheet with the images
spritebatch= [CCSpriteBatchNode batchNodeWithFile:#"a.png"];
[self addChild:sprite z:12];
// Load up the frames of our animation
NSMutableArray *animFrames = [NSMutableArray array];
for(int i = 1; i <= 13; ++i) {
[animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"crta%d.png", i]]];
}
CCAnimation *walkAnim = [CCAnimation animationWithFrames:animFrames delay:.1f];
sprite=[CCSprite spriteWithSpriteFrameName:#"crta13.png"];
[self addChild:sprite z:20];
drawaction = [CCRepeat actionWithAction:[CCAnimate actionWithAnimation:walkAnim] times:1];
//[CCRepeat actionWithAction: [CCAnimate actionWithAnimation:animation] times:1];
[sprite runAction:drawaction];
}
-(void)draw2
{
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:#"a.plist"];
// Create a sprite sheet with the images
spritebatch= [CCSpriteBatchNode batchNodeWithFile:#"a.png"];
[self addChild:sprite z:12];
// Load up the frames of our animation
NSMutableArray *animFrames = [NSMutableArray array];
for(int i = 1; i <= 13; ++i) {
[animFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:#"crta%d.png", i]]];
}
CCAnimation *walkAnim = [CCAnimation animationWithFrames:animFrames delay:.1f];
sprite=[CCSprite spriteWithSpriteFrameName:#"crta13.png"];
[self addChild:sprite z:20];
drawaction = [CCRepeat actionWithAction:[CCAnimate actionWithAnimation:walkAnim] times:1];
//[CCRepeat actionWithAction: [CCAnimate actionWithAnimation:animation] times:1];
[sprite runAction:drawaction];
}

Related

Shooting a projectile in spritekit

I am looking to shoot a SKSpritenode (a cannonball) from a another Sprite node (enemy ship).
The cannonball should travel directly down toward bottom of screen from the enemy ship node.
I can't seem to get positioning right, cannonball seems to shoot from the corner of the screen and not move far, the enemy-ship node is randomly chosen from an array of all halos on screen at once and the cannonball position assigned to the front of halo:
// the cannonball
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:6];
ball.physicsBody.velocity = CGVectorMake(SHOT_SPEED, SHOT_SPEED);
// we dont want ball to lose speed or momentum when it hots edges so..
ball.physicsBody.restitution=1.0; // max bounceness of node
ball.physicsBody.linearDamping =0.0; // dont reduce linear velocity ove time
ball.physicsBody.friction=0.0;
ball.physicsBody.categoryBitMask = kCCBallCategory;
// ball.physicsBody.contactTestBitMask = kCCEdgeCategory;
ball.physicsBody.collisionBitMask= kCCEdgeCategory;
ball.physicsBody.contactTestBitMask = kCCEdgeCategory | KCCShieldUPCategory | kCCMultiUpCategory ; // | KCCShieldUPCategory notify
// the array of enemy ship nodes
NSMutableArray *allHalos = [NSMutableArray array];
[_mainLayer enumerateChildNodesWithName:#"halos" usingBlock:^(SKNode *node, BOOL *stop) {
[allHalos addObject:node];
}];
if ([allHalos count]>0) {
NSUInteger allHalosInteger = arc4random_uniform([allHalos count]);
SKSpriteNode *shooterHalo=[allHalos objectAtIndex:allHalosInteger];
ball.position = CGPointMake(shooterHalo.position.x, shooterHalo.position.y - shooterHalo.frame.size.height/2 + ball.frame.size.height / 2);
CGPoint bulletDestination = CGPointMake(shooterHalo.position.x, - ball.frame.size.height / 2);
[self fireBullet:ball toDestination:bulletDestination withDuration:2.0 ];
}
-(void)fireBullet:(SKNode*)ball toDestination:(CGPoint)destination withDuration:(NSTimeInterval)duration {
//1
SKAction* bulletAction = [SKAction sequence:#[[SKAction moveTo:destination duration:duration],
[SKAction waitForDuration:3.0/60.0],
[SKAction removeFromParent]]];
[ball runAction:[SKAction group:#[bulletAction, _soundLaser]]];
[self addChild:ball];
}
Any input appreciated.

Sprite Kit NSArray of multiple sprites?

I have 6 sprite images I am trying to add to my scene, adding each of them seems to slow everything down a lot. I figured I would need to create an NSArray in order to help with speed. Here is the array I've created, but it's only adding the first image, how can I get it to add all 6?? Thank you in advance!
myArray
NSArray *myArray = [NSArray arrayWithObjects:#"image1",#"image2",#"image3",#"image4",#"image5",#"image6", nil];
NSInteger count = [myArray count];
for (int i = 0; i < count; i++) {
if (i > 5) {
break;
}
result = [myArray objectAtIndex:i];
}
//Setting SKSpriteNodes from array.
dice = [SKSpriteNode spriteNodeWithImageNamed:[myArray objectAtIndex:result.intValue]];
Define a property in you scene:
#interface MyScene
#property (nonatomic) NSMutableArray *items;
#end
Then create a method to fill that array:
- (void)fillItems {
for (int i=0; i<10; i++) {
SKSpriteNode *d1 = [SKSpriteNode spriteNodeWithImageNamed:#"Sprite1"];
d1.position = CGPointMake(self.frame.size.width/4 + arc4random() % ((int)self.frame.size.width/2),
self.frame.size.height/2 + arc4random() % ((int)self.frame.size.height/2));
d1.color = [self randomColor];
d1.colorBlendFactor = 1.0;
d1.xScale = 0.25;
d1.yScale = 0.25;
d1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:d1.frame.size];
//Adding SpriteKit physicsBody for collision detection
d1.physicsBody.categoryBitMask = diceCategory;
d1.physicsBody.dynamic = YES;
d1.physicsBody.contactTestBitMask = frameCategory;
d1.physicsBody.collisionBitMask = diceCategory | frameCategory;
d1.physicsBody.usesPreciseCollisionDetection = YES;
d1.name = #"Sprite1";
[self.items addObject:d1];
[self addChild:d1];
}

How can I add a menu option to the NSTextAttachment popup menu is UITextView?

I want to add another menu option to the default image attachment menu options (Copy Image, Save to Camera Roll). Note that these options are shown when you long press on an image embedded in the UITextView if the textView is not in editing mode.
I have tried adding a custom menu to the uimenucontroller and using -(void)canPerformAction to enable or disable the option, however this seems to add the menu item to the uitextView's edit menu and has no affect on the attachments popup menu.
-(void)canPerformAction never seems to get called when long pressing on the image attachment.
Well according to Apple there is no public API for doing this, however as it turns out its relatively straight forward to replace the default menu with one that looks and behaves the same.
In the viewController that contains the UITextView add the following or similar and set it up as the textView's delegate.
- (BOOL)textView:(UITextView *)textView shouldInteractWithTextAttachment:(NSTextAttachment *)textAttachment inRange:(NSRange)characterRange {
// save in ivar so we can access once action sheet option is selected
_attachment = textAttachment;
[self attachmentActionSheet:(UITextView *)textView range:characterRange];
return NO;
}
- (void)attachmentActionSheet:(UITextView *)textView range:(NSRange)range {
// get the rect for the selected attachment (if its a big image with top not visible the action sheet
// will be positioned above the top limit of the UITextView
// Need to add code to adjust for this.
CGRect attachmentRect = [self frameOfTextRange:range inTextView:textView];
_attachmentMenuSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Copy Image", #"Save to Camera Roll", #"Open in Viewer", nil];
// Show the sheet
[_attachmentMenuSheet showFromRect:attachmentRect inView:textView animated:YES];
}
- (CGRect)frameOfTextRange:(NSRange)range inTextView:(UITextView *)textView {
CGRect rect = [textView.layoutManager boundingRectForGlyphRange:range inTextContainer:textView.textContainer];
// Now convert to textView coordinates
CGRect rectRange = [textView convertRect:rect fromView:textView.textInputView];
// Now convert to contentView coordinates
CGRect rectRangeSuper = [self.contentView convertRect:rectRange fromView:textView];
// Get the textView frame
CGRect rectView = textView.frame;
// Find the intersection of the two (in the same coordinate space)
CGRect rectIntersect = CGRectIntersection(rectRangeSuper, rectView);
// If no intersection then that's weird !!
if (CGRectIsNull(rectIntersect)) {
return rectRange;
}
// Now convert the intersection rect back to textView coordinates
CGRect rectRangeInt = [textView convertRect:rectIntersect fromView:self.contentView];
return rectRangeInt;
}
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (actionSheet == _attachmentMenuSheet) {
switch (buttonIndex) {
case 0:
[self copyImageToPasteBoard:[_attachment image]];
break;
case 1:
[self saveToCameraRoll:[_attachment image]];
break;
case 2:
[self browseImage:[_attachment image]];
break;
default:
break;
}
}
}
- (void)saveToCameraRoll:(UIImage*)image {
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
}
- (void)copyImageToPasteBoard:(UIImage*)image {
UIPasteboard *pasteboard = [UIPasteboard generalPasteboard];
NSData *data = UIImagePNGRepresentation(image);
[pasteboard setData:data forPasteboardType:#"public.png"];
}
-(void)browseImage:(UIImage*)image
{
OSImageViewController *_imageViewerController = [[OSImageViewController alloc] init];
UIImage *img = [[UIImage alloc] initWithData:UIImagePNGRepresentation(image)];
_imageViewerController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
_imageViewerController.modalPresentationStyle = UIModalPresentationFullScreen;
_imageViewerController.delegate = self;
[self presentViewController:_imageViewerController animated:YES completion:^(void){
[_imageViewerController setImage:img];
}];
}

CALayer as SubLayer Not Visible

I am trying to built an animated circle which would be drawn clockwise until it becomes complete circle as illustrated in iPhone Core Animation - Drawing a Circle
Problem is that CALayer object is not added or build. I tested and saw that it is not accessing my drawInContext:CGContextRef and animatingArc methods.
What so far I have done is:
In AnimateArc.h
#interface AnimateArc : CALayer {
CAShapeLayer *circle;
}
-(void) animatingArc;
#end
In AnimateArc.m
-(void) drawInContext:(CGContextRef)ctx
{
CGFloat radius = 50.0;
circle = [CAShapeLayer layer];
//make a circular shape
circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0.0, 0.0, 2 * radius, 2 * radius) cornerRadius:radius].CGPath;
CGPoint centerPoint = CGPointMake(CGRectGetWidth(self.bounds)/2, CGRectGetHeight(self.bounds)/2);
//center the shape in self.view
circle.position = centerPoint;
//configure appearence of circle
circle.fillColor = [UIColor clearColor].CGColor;
circle.strokeColor = [UIColor blackColor].CGColor;
circle.lineWidth = 5;
/*CGPointMake((self.contentsCenter.size.width), (self.contentsCenter.size.height));*/
//path the circle
CGContextAddArc(ctx, centerPoint.x, centerPoint.y, radius, 0.0, 2 * M_PI, 0);
CGContextClosePath(ctx);
//fill it
CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
CGContextFillPath(ctx); }
///////////////////////////////////////////////////////////////////////
-(void) animatingArc
{
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:#"arcEnd"];
anim.duration = 20.0; //animate over 20 seconds
anim.repeatCount = 1.0; //animate only once
anim.removedOnCompletion = NO; //Reamin there after completion
//animate from start to end
anim.fromValue = [NSNumber numberWithFloat:50.0f];
anim.toValue = [NSNumber numberWithFloat:150.0f];
//experiment with timing to get appearence to look the way you want
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
//add animation to circle
[circle addAnimation:anim forKey:#"animatingArc"];
}
/////////////////////
//needed since key not part of animatable properties
+(BOOL) needsDisplayForKey:(NSString *)key
{
if([key isEqualToString:#"arcEnd"])
return YES;
else
return [super needsDisplayForKey:key];
}
//ensure custom properties copied to presentation layer
-(id) initWithLayer:(id)layer
{
if((self = [super initWithLayer:layer]))
{
if ([layer isKindOfClass:[AnimateArc class]])
{
AnimateArc *other = (AnimateArc *) layer;
[other setNeedsDisplay];
}
}
return self; }
And finally in my viewController,
- (void)viewDidLoad
{
[super viewDidLoad];
[self.view.layer addSublayer:AnimateArcObject];
[AnimateArcObject animatingArc];
}
Apology for bad formatting.... Please can someone tell me what am I doing wrong? I have also doubt that my code can crash at any place after accessing those two functions since I am novice about Core Animation and haven't got any idea that I am in right direction or not.
Any help will be appreciated. Thanks.
From my painful experience with CoreAnimation, you must always set the bounds property of any CALayer you instantiate.
So, you're layer is not showing because you are missing something like:
layer.bounds = CGRectMake(0, 0, width, height);
you should place this as soon as you instantiate the layer, and make it a habit to do so, so you don't fall into it again.
As for your code crashing, sorry. It's too distributed and I am not sure how it's linked together, so I can't help you there.
After little searching, I thought that I am going in wrong direction. So I deleted this AnimateArc file and added new one which is inheriting from UIViewController.
Then in viewDidLoad Method, I wrote the code from this link to create circle and animations using path.
In parent view controller, I added AnimatedArc ViewController's subview. Now its working perfectly :)

iAds in a Scrolling View

In my application I want to show iAd in table view controller which have both navigation bar and Tab bar. I am able to show iAd in my application but this iAd is give trouble when I try to scroll, the problem is that iAd is also scrolling with the cells due to which I am not able to view the cell in bottom. I am creating the iAd using below code. can some one help me out in resolving following issue.
#pragma mark -
#pragma mark === Banner View Methods ===
#pragma mark -
- (void)createBannerView {
Class cls = NSClassFromString(#"ADBannerView");
if (cls) {
ADBannerView *adView = [[cls alloc] initWithFrame:CGRectZero];
adView.requiredContentSizeIdentifiers = [NSSet setWithObjects:ADBannerContentSizeIdentifierPortrait,
ADBannerContentSizeIdentifierLandscape, nil];
// Set the current size based on device orientation
adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
adView.delegate = self;
adView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin;
// Set intital frame to be offscreen
CGRect bannerFrame =adView.frame;
bannerFrame.origin.y = self.view.frame.size.height;
adView.frame = bannerFrame;
self.bannerView = adView;
[self.view addSubview:adView];
[adView release];
}
}
- (void)showBanner {
CGFloat fullViewHeight = self.view.frame.size.height;
CGRect tableFrame = self.tv.frame;
CGRect bannerFrame = self.bannerView.frame;
// Shrink the tableview to create space for banner
tableFrame.size.height = fullViewHeight - bannerFrame.size.height;
// Move banner onscreen
bannerFrame.origin.y = fullViewHeight - bannerFrame.size.height;
[UIView beginAnimations:#"showBanner" context:NULL];
self.tv.frame = tableFrame;
self.bannerView.frame = bannerFrame;
[UIView commitAnimations];
}
- (void)hideBanner {
// Grow the tableview to occupy space left by banner
CGFloat fullViewHeight = self.view.frame.size.height;
CGRect tableFrame = self.tv.frame;
tableFrame.size.height = fullViewHeight;
// Move the banner view offscreen
CGRect bannerFrame = self.bannerView.frame;
bannerFrame.origin.y = fullViewHeight;
self.tv.frame = tableFrame;
self.bannerView.frame = bannerFrame;
}
- (void)releaseBanner {
if (self.bannerView) {
bannerView.delegate = nil;
self.bannerView = nil;
}
}
- (void)changeBannerOrientation:(UIInterfaceOrientation)toOrientation {
if (UIInterfaceOrientationIsLandscape(toOrientation)) {
self.bannerView.currentContentSizeIdentifier =
ADBannerContentSizeIdentifierLandscape;
}
else {
self.bannerView.currentContentSizeIdentifier =
ADBannerContentSizeIdentifierPortrait;
}
}
#pragma mark -
#pragma mark === ADBannerViewDelegate Methods ===
#pragma mark -
- (void)bannerViewDidLoadAd:(ADBannerView *)banner {
[self showBanner];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
[self hideBanner];
}
yes i got it you use addSubView which i think is wrong Add this Banner in last cell of a tableview or in a fotter of a table view if you are not use load more functionalty in you app
– tableView:viewForFooterInSection:
use that delegate method of table view UItableViewDelegate i think it helps you
– tableView:heightForFooterInSection:
add that method too to specify the height of footer of your table
add the calculate banner size code in
– tableView:heightForFooterInSection:
and add banner in – tableView:heightForFooterInSection:

Resources