How to Spawn Sprites with Increasing Speed - sprite-kit

I want to know how to continuously spawn sprites with gradually increasing speed. I did see the question "How to gradually increase the rate of something?" but I'm not sure how to apply it to my code. Additionally, if there is a better way to spawn sprites regularly than using a game timer, please let me know.
I tried using a loop and having the "scheduledTimerWithTimeInterval" increase, but it ended up just causing numerous sprites to spawn at the same time.
-(void)getBalls {
//[userScore.node removeFromParent];
SKSpriteNode *ball = [SKSpriteNode spriteNodeWithImageNamed:#"ball"];
int x = arc4random() %320;
CGPoint myPoint = CGPointMake(x, 480);
ball.position = myPoint;
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ball.frame.size.width/2];
ball.physicsBody.categoryBitMask = ballCategory;
ball.physicsBody.contactTestBitMask = paddleCategory;
ball.physicsBody.collisionBitMask = ballCategory;
[self addChild:ball];
SKLabelNode *userScore = [SKLabelNode labelNodeWithFontNamed:#"Impact"];
userScore.fontColor = [SKColor blackColor];
userScore.text = [NSString stringWithFormat:#"SCORE: %i", score];
userScore.fontSize = 18;
userScore.position = CGPointMake(CGRectGetMidX(self.frame) + 110, CGRectGetHeight(self.frame)
- 30);
[self addChild:userScore];
[userScore runAction:[SKAction fadeAlphaTo:1.0 duration:1.5] completion:^{
[userScore removeFromParent];
}];
}
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
self.backgroundColor = [SKColor whiteColor];
self.physicsWorld.gravity = CGVectorMake(0, -9.8);
self.physicsWorld.contactDelegate = self;
gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.5 target:self
selector:#selector(getBalls) userInfo:nil repeats:YES];
[self addPlayer:size];
}
Thanks for your help.

Use a non-repeating NSTimer. Also, in the method called by the timer (getBalls) recall the timer and decrease the interval rate (linearly, exponentially, however you want).
float decTime;
decTime = 1.5f;
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
self.backgroundColor = [SKColor whiteColor];
self.physicsWorld.gravity = CGVectorMake(0, -9.8);
self.physicsWorld.contactDelegate = self;
gameTimer = [NSTimer scheduledTimerWithTimeInterval:decTime target:self
selector:#selector(getBalls) userInfo:nil repeats:NO];
[self addPlayer:size];
}
-(void)getBalls {
//[userScore.node removeFromParent];
SKSpriteNode *ball = [SKSpriteNode spriteNodeWithImageNamed:#"ball"];
int x = arc4random() %320;
CGPoint myPoint = CGPointMake(x, 480);
ball.position = myPoint;
ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ball.frame.size.width/2];
ball.physicsBody.categoryBitMask = ballCategory;
ball.physicsBody.contactTestBitMask = paddleCategory;
ball.physicsBody.collisionBitMask = ballCategory;
[self addChild:ball];
....
if (decTime > .05f) {
//linear increase
decTime -= .01f;
gameTimer = [NSTimer scheduledTimerWithTimeInterval:decTime target:self
selector:#selector(getBalls) userInfo:nil repeats:NO];
}
}

Related

Infinite scrolling on a sprite(Parallax)

I am a newbie to the world of cocos2d i am developing my first tutorial and facing one problem
my problem is i have an image (1024 X 320) and my orientation is landscape i need to move that image continuously from right to left for this purpose i have used space shooter tutorial by Ray(Thanks to him) but the image doesn't seem to be appearing again and again.
my code is..
-(id) init
{
if( (self=[super init])) {
CGSize screenSize = [CCDirector sharedDirector].winSize;
// 1) Create the CCParallaxNode
backgroundNode = [CCParallaxNode node];
[self addChild:backgroundNode z:-1];
// 2) Create the sprites we'll add to the CCParallaxNode
Back = [CCSprite spriteWithFile:#"bg_front_spacedust.png"];
//Back.position=ccp(screenSize.width/2, screenSize.height/2);
Back.rotation = -90;
Back1 = [CCSprite spriteWithFile:#"bg_front_spacedust.png"];
Back1.rotation = -90;
// 3) Determine relative movement speeds for space dust and background
CGPoint dustSpeed = ccp(0.1, 0.1);
// 4) Add children to CCParallaxNode
[backgroundNode addChild:Back z:0 parallaxRatio:dustSpeed positionOffset:ccp(screenSize.width/2, screenSize.height/2)];
NSLog(#"back.content width is...%f",Back.contentSize.width);
[backgroundNode addChild:Back1 z:1 parallaxRatio:dustSpeed positionOffset:ccp(screenSize.width/2, screenSize.height*2)];
// 5) Enable updates
[self scheduleUpdate];
}
return self;
}
- (void)update:(ccTime)dt {
// 1) Update background position
CGPoint backgroundScrollVel = ccp(0,-1000);
backgroundNode.position = ccpAdd(backgroundNode.position, ccpMult(backgroundScrollVel, dt));
// 2) Check for background elements moving offscreen
NSArray *spaceDusts = [NSArray arrayWithObjects:Back, Back1, nil];
for (CCSprite *spaceDust in spaceDusts) {
if ([backgroundNode convertToWorldSpace:spaceDust.position].x < -spaceDust.contentSize.width) {
[backgroundNode incrementOffset:ccp(2*spaceDust.contentSize.width,0) forChild:spaceDust];
}
}
}
please help me out of this
Thanks in advance.
try this one
if (backgroundNode.position.y <-screenSize.height*2)
backgroundNode.position = ccp(0,0);
As init method is called only once the approach you are doing will be done only one time you need to again set the Position of the backgroundNode to 0 in your update method.
here the multiple may vary
Try this code it is creating a paralax moving from bottom to top change CGPointMake(0, 1.0) to this CGPointMake(1.0,0) in paraNode addChild line.
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if( (self=[super init]) )
{
float yPos =0.0;
NSMutableString *fileNameString = [[NSMutableString alloc]initWithCapacity:0];
if (IS_IPHONE_5)
{
[fileNameString appendString:#"Background-568h.png"];
yPos= 560.0;
}
else
{
[fileNameString appendString:#"Background.png"];
yPos= 470.0;
}
background1 = [CCSprite spriteWithFile:fileNameString];
background1.tag = 1;
background1.anchorPoint = CGPointMake(0,0);
background2 = [CCSprite spriteWithFile:fileNameString];
background2.tag = 2;
background2.anchorPoint = CGPointMake(0,0);
background3 = [CCSprite spriteWithFile:fileNameString];
background3.tag = 3;
background3.anchorPoint = CGPointMake(0,0);
background4 = [CCSprite spriteWithFile:fileNameString];
background4.tag = 4;
background4.anchorPoint = CGPointMake(0,0);
paraNode = [CCParallaxNode node];
[paraNode addChild:background1 z:1 parallaxRatio:CGPointMake(0, 1.0) positionOffset:CGPointMake(0, 0)];
[paraNode addChild:background2 z:2 parallaxRatio:CGPointMake(0, 1.0) positionOffset:CGPointMake(0, -yPos)];
[paraNode addChild:background3 z:3 parallaxRatio:CGPointMake(0, 1.0) positionOffset:CGPointMake(0, -yPos*2)];
[paraNode addChild:background4 z:4 parallaxRatio:CGPointMake(0, 1.0) positionOffset:CGPointMake(0, -yPos*3)];
[self addChild:paraNode z:-1 tag:123];
[self updateFrameRate:0.7 andYposition:yPos];
[fileNameString release];
fileNameString = nil;
}
return self;
}
-(void)updateFrameRate:(float)speedValue andYposition:(float)yposToSet
{
move1 = [CCMoveBy actionWithDuration:speedValue position:CGPointMake(0, yposToSet)];
move2 = [CCMoveBy actionWithDuration:0.0 position:CGPointMake(0, -yposToSet)];
move3 = [CCMoveBy actionWithDuration:0.0 position:CGPointMake(0, 0)];
CCSequence* sequence = [CCSequence actions:move1,move2,move3, nil];
CCRepeatForever* repeat = [CCRepeatForever actionWithAction:sequence];
[paraNode runAction:repeat];
}

Contents are shuffles in GridView

I am new to IOS development. I am using custom GridView to load the content in my project, and it is working fine for Simulator when the content reloads. But in iPad the content gets shuffles when reloads.
- (void)reloadData {
if (_gridViewDelegate && self.superview != nil) {
CGFloat maxX = 0.f;
CGFloat maxY = 0.f;
_scrollView.pagingEnabled = YES;
self.gridRects = [self.gridViewDelegate rectsForCellsInGridView:self];
[self.gridCells.allValues makeObjectsPerformSelector:#selector(removeFromSuperview)];
[self.reuseableCells addObjectsFromArray:self.gridCells.allValues];
[self.gridCells removeAllObjects];
for (NSValue *rectValue in self.gridRects) {
CGRect rect = [rectValue CGRectValue];
maxX = MAX(maxX, rect.origin.x + rect.size.width);
maxY = MAX(maxY, rect.origin.y + rect.size.height);
}
CGFloat pageWidth = self.scrollView.frame.size.width;
self.maximumContentWidth=maxX;
maxX = MAX(MIN(maxX, self.maximumContentWidth), self.contentSize.width);
maxY = MAX(MIN(maxX, self.maximumContentHeight), self.contentSize.height);
maxX=pageCount*pageWidth;
self.scrollView.contentSize = CGSizeMake(maxX, maxY);
[self loadCellsInRect:self.visibleRect];
[self updateStickyViewsPosition];
[pageNumberLable removeFromSuperview];
currentPage = floor((self.scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
if(pageWidth == 1024)
{
pageNumberLable=[[UILabel alloc]initWithFrame:CGRectMake(self.scrollView.contentOffset.x+990, 690, 20, 20)];
pageNumberLable.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
}
else
{
pageNumberLable=[[UILabel alloc]initWithFrame:CGRectMake(self.scrollView.contentOffset.x+740, 943, 20, 20)];
pageNumberLable.backgroundColor=[UIColor redColor];
pageNumberLable.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
}
pageNumberLable.text=[NSString stringWithFormat:#"%d",currentPage+1];
pageNumberLable.textColor=[UIColor blackColor];
pageNumberLable.font = [UIFont boldSystemFontOfSize:16];
pageNumberLable.backgroundColor=[UIColor clearColor];
[self.scrollView addSubview:pageNumberLable];
pageIndex = [NSUserDefaults standardUserDefaults];
[pageIndex setInteger:currentPage+1 forKey:#"integerKey"];
}
}
-(void)reloadGrid
{
if(rotate == newIntValue)
{
[spinningLibrary stopAnimating];
[update removeFromSuperview];
settingLabel.hidden=YES;
spinningLibrary.hidden=YES;
}
if(rotate<newIntValue)
{
rotate++;
[self.gridView scrollRectToVisible:CGRectMake(768*rotate, 0, self.gridView.frame.size.width, self.gridView.frame.size.height) animated:YES];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(reloadGrid123) userInfo:nil repeats:NO];
}
[NSThread sleepForTimeInterval:0.2];
self.gridView.scrollView.hidden=NO;
[settingsPopoverController dismissPopoverAnimated:YES];
}
You're comparing iPad's RAM and your machine's RAM.It's not fair though.
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(reloadGrid123) userInfo:nil repeats:NO];
Try to adjust the interval(> 0.1) by setting, scheduledTimerWithTimeInterval.
And it's a bad way of blocking the main thread.
Use below blocks approach to "do something after sometime".
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do something taking a long time in background.
[NSThread sleepForTimeInterval:0.2];
// Background thread has finished it's work.
// Call another block on main thread to do UI stuff like updating etc..
dispatch_async(dispatch_get_main_queue(), ^{
// Here you are in the main thread again
// You can do whatever you want
});
});

CCSprite overrite on scene cocos2d-iPhone

My App is generating sceenshoot of my game.and when i scale up my sceenshoot(CCSprite), other controls like CCMenu doesn't work.I guess CCSprite(screeenshoot) overrite on my scene.
How to control my CCMenu while CCSprite Scales Down. ?!
here is my code
- (void) showGameOver
{
CCDirector *director = [CCDirector sharedDirector];
appDelegate.screenshootimage = [director screenshotUIImage];
imgsprite = [CCSprite spriteWithCGImage:appDelegate.screenshootimage.CGImage key:#"spriteKey"];
if(flagRescale == false)
{
imgsprite.scaleX = 0.40;
imgsprite.scaleY = 0.40;
flagRescale = true;
}
CCMenuItemImage *image = [CCMenuItemSprite itemFromNormalSprite:imgsprite selectedSprite:nil target:self selector:#selector(imgAction)];
image.position = ccp(40, 50);
imageMenu = [CCMenu menuWithItems:image, nil];
[self addChild:imageMenu];
menu_.visible = true;
menu_.position = ccp(windowCenter_.x, windowCenter_.y - 70);
lblGameOver.visible = true;
lblGameOver.position = ccp(windowCenter_.x, windowCenter_.y + 50);
[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
}
-(void)imgAction
{
if(flagRescale == TRUE)
{
imgsprite.scaleX = 0.7;
imgsprite.scaleY = 0.7;
flagRescale=false;
}
else
{
imgsprite.scaleX = 0.4;
imgsprite.scaleY = 0.4;
flagRescale=true;
}
}

Looping multiple methods

I've made a program that generates an image at a random x-coordinate at the top of the screen. The image then falls down to the bottom. However, I want to keep generating new images (of the same image) every few seconds so that it's as though these duplicates of the same image are continually "raining" from the top.
How can I make all of this code repeat every 0.5 seconds?
#implementation ViewController {
UIImageView *_myImage;
}
- (void)viewDidLoad
{
srand(time(NULL));e
int random_x_coordinate = rand() % 286;
CGRect myImageRect = CGRectMake(random_x_coordinate, 0.0f, 40.0f, 40.0f);
UIImageView *myImage = [[UIImageView alloc] initWithFrame:myImageRect];
[myImage setImage:[UIImage imageNamed:#"flake.png"]];
myImage.opaque = YES;
[self.view addSubview:myImage];
_myImage = myImage;
//FALLING BIRDS TIMER
moveObjectTimer = [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:#selector(moveObject) userInfo:nil repeats:YES];
}
//FALLING BIRDS MOVER
-(void) moveObject { // + means down and the number next to it is how many pixels y moves down per each tick of the TIMER above
_myImage.center = CGPointMake(_myImage.center.x, _myImage.center.y +1);
}
Just put animation cycle inside the method you call on timer, something like
- (void)viewDidLoad
{
[super viewDidLoad];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.5
target:self
selector:#selector(animate)
userInfo:nil repeats:YES];
[timer fire];
}
- (void)animate
{
CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0
CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from white
CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black
UIColor *color = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view.backgroundColor = color;
[self.view addSubview:view];
[UIView animateWithDuration:1.0 animations:^{
view.frame = CGRectMake(0, 200, 50, 50);
}];
}
Will give you squares dropping down from top, continuously. Just remember to clean up unused views regularly to avoid memory issues.

Move 10 images continuously in the time interval of 5 sec using objective c?

I have some 10 images, I wanted to show 10 images continuously in two way, one by moving the image with user interaction and other way by automatically moving the images in a time interval with out any user interaction. Following code allow me to move images when user touch and moves the image.... but how can i move the images automatically?
{
scrollView.delegate = self;
[self.scrollView setBackgroundColor:[UIColor blackColor]];
[scrollView setCanCancelContentTouches:NO];
scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
scrollView.clipsToBounds = YES;
scrollView.scrollEnabled = YES;
scrollView.pagingEnabled = YES;
NSUInteger nimages = 0;
CGFloat cx = 0;
for (; ; nimages++) {
NSString *imageName = [NSString stringWithFormat:#"pimac%d.gif", (nimages + 1)];
UIImage *image = [UIImage imageNamed:imageName];
if (image == nil) {
break;
}
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
CGRect rect = imageView.frame;
rect.size.height = image.size.height;
rect.size.width = image.size.width;
rect.origin.x = ((scrollView.frame.size.width - image.size.width) / 2) + cx;
rect.origin.y = ((scrollView.frame.size.height - image.size.height) / 2);
imageView.frame = rect;
[scrollView addSubview:imageView];
[imageView release];
cx += scrollView.frame.size.width;
}
self.pageControl.numberOfPages = nimages;
[scrollView setContentSize:CGSizeMake(cx, [scrollView bounds].size.height)];
}
You can use NSTimmer and invoke your image move function there.
self.timer = [NSTimer scheduledTimerWithTimeInterval:5
target:self
selector:#selector(imageMove)
userInfo:nil
repeats:YES];
const CGFloat kScrollObjWidth = 320.0;
const NSUInteger kNumImages = 3;
-(void)viewdidLoad
{
// additional further step
[NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:#selector(onTimer) userInfo:nil repeats:YES];
curXLoc=0;
}
- (void) onTimer {
curXLoc += kScrollObjWidth;
//This makes the scrollView scroll to the desired position
if(curXLoc<(kNumImages * kScrollObjWidth))
ScrollView.contentOffset = CGPointMake(curXLoc,0 );
else
{
curXLoc =0;
ScrollView.contentOffset = CGPointMake(curXLoc,0 );
}
}