Communication Between Unrelated Objects - objective-c

Background
I'm creating a rhythm app for MIDI drumming using SpriteKit on Mac OS. Note objects are the ones in green and blue below. The notes move from right to left on the screen. As the notes get closer to the "play bar" in red, I want to create an outline of the notes next to the play bar to indicate to the user that the notes are getting close to the play bar and that it's time to play soon.
The Problem
I need each Note object to notify another class called Sequencer when they get a certain distance from the play head so that it can start the note outline animation for the closest note. The notes know how far they are from the play head, so that's not a problem. Would delegation be a candidate for this situation? I have tried to understand the purpose of delegation, but I can never figure out how to implement it into my specific game-related situation.
EDIT: Code added
GameScene.m
#implementation GameScene
- (void)didMoveToView:(SKView *)view {
...
[self initSequence];
[self initNoteProcessor];
[self initPlayBar];
...
}
...
//keeps track of a collection of notes and vertical line measure markers and
//responsible for drawing them in scene and moving them left
-(void) initSequence {
_sequence = [[Sequencer alloc] initWithWidth:1150];
[_sequence setPosition:CGPointMake(130, 0)];
[self addChild:_sequence];
}
...
//responsible for handling incoming MIDI input from a keyboard and checking to see
//if notes are played on time, early or late
-(void) initNoteProcessor {
_noteProcessor = [[NoteProcessor alloc] initWithSequence:_sequence];
}
...
//creates a vertical line that indicates when notes need to be played
-(void) initPlayBar {
_playBar = (SKSpriteNode*)[self childNodeWithName:#"playBar"];
_playBar.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:_playBar.frame.size];
_playBar.physicsBody.affectedByGravity = NO;
[_playBar.physicsBody setDynamic:YES];
[_playBar.physicsBody setAllowsRotation:NO];
[_playBar.physicsBody setCategoryBitMask:kPlayBarCategory];
[_playBar.physicsBody setCollisionBitMask:kNoCategory];
[_playBar.physicsBody setContactTestBitMask:kNoteCategory | kLineCategory];
[[NSUserDefaults standardUserDefaults] setDouble:_playBar.position.x forKey:#"playBarXPosition"];
}
NoteProcessor.m
#implementation NoteProcessor
-(instancetype) initWithSequence:(Sequencer*)sequence {
if (self = [super init]) {
_sequence = sequence;
_noteActiveIndex = 0;
[self initActiveNoteIndices];
[self initNoteIndicator];
//when user plays key on keyboard, notify this class
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(midiPlayed:) name:#"MidiPlayedNotificationKey" object:nil];
}
return self;
}
//keeps track of the next note of each pitch that is incoming
-(void) initActiveNoteIndices {
_activeNoteIndicesByPitch = [NSMutableArray array];
for (int i = 0; i < kTotalKeys; i++) {
[_activeNoteIndicesByPitch addObject:[NSNumber numberWithInteger:0]];
}
}
//checks position of note and decides whether they are on time, early or late
-(void) updateCurrentNoteStatus {
...
}
//handles notifications from MIDI keyboard when user plays a key
-(void) midiPlayed:(NSNotification*)notification {
//stuff happens here
}
#end
Sequencer.m
#implementation Sequencer
-(instancetype) initWithWidth:(double)width {
if (self = [super init]) {
...
[self drawNotes];
}
return self;
}
//draws all of the notes on screen
-(void) drawNotes {
NSMutableArray *parsedNotes = [_midiParser getNoteData];
float distancePerBeat = [self getGridArea] / [self getMeasuresDisplayed] / 4;
float xPos = 0;
for (int i = 0; i < [parsedNotes count]; i++) {
NSArray *currNote = [parsedNotes objectAtIndex:i];
double location = [[currNote objectAtIndex:0] doubleValue];
double duration = [[currNote objectAtIndex:1] doubleValue];
int midiValue = [[currNote objectAtIndex:2] intValue];
Note *note = [[Note alloc] initWithLocation:location Duration:duration MidiValue:midiValue];
xPos = distancePerBeat * (location - 1);
float yPos = kNoteHeight[note.midiValue - 36];
[note setPosition:CGPointMake(xPos, yPos)];
[note setZPosition:kNoteZPosition];
NSMutableArray *noteList = [_notes objectAtIndex:midiValue-36];
[noteList addObject:note];
[self addChild:note];
}
}
//this method is called 60 times per second
//each call moves 1/60th of the distance it would move in 1/60th of a second
-(void) moveLeftAfterElapsedTime:(double)elapsedTime {
double timePerBeat = 60 / [self getBpm];
double timePerMeasure = timePerBeat * 4;
double lengthPerMeasure = [self getGridArea] / [self getMeasuresDisplayed];
double distancePerFrame = lengthPerMeasure / (timePerMeasure * 60);
double x = elapsedTime * distancePerFrame * 60;
[self moveAllNotesLeftByDistance:x];
}
//actually does all of the moving of the notes
-(void) moveAllNotesLeftByDistance:(double)distance {
for (int i = 0; i < [_notes count]; i++) {
NSMutableArray *noteList = [_notes objectAtIndex:i];
for (int j = 0; j < [noteList count]; j++) {
Note *note = [noteList objectAtIndex:j];
double xPos = note.position.x - distance;
double y = note.position.y;
[note setPosition:CGPointMake(xPos, y)];
}
}
}

Related

infinite carousel with objective-c

I'm facing 2 problems with my code and i would like to see if somebody can help me to fix it?
here is my code:
#import "ViewController.h"
#interface ViewController () {
#private NSInteger index;
#private NSInteger iterations;
#private UIButton* buttons[6];
#private CGPoint centers[6];
#private CGRect bounds[6];
#private CGFloat opacities[6];
#private CGFloat opacitieOffsets[6];
#private CGPoint centerOffsets[6];
#private CGRect boundOffsets[6];
#private NSString* titles[6];
}
#property (strong, nonatomic) NSTimer *timer;
#end
#implementation ViewController
#synthesize Button1;
#synthesize Button2;
#synthesize Button3;
#synthesize Button4;
#synthesize Button5;
#synthesize Button6;
#synthesize TitleLabel;
- (void)viewDidLoad
{
[super viewDidLoad];
buttons[0] = Button1;
titles[0] = #"btnTitle1";
buttons[1] = Button2;
titles[1] = #"btnTitle2";
buttons[2] = Button3;
titles[2] = #"btnTitle3";
buttons[3] = Button4;
titles[3] = #"btnTitle4";
buttons[4] = Button5;
titles[4] = #"btnTitle5";
buttons[5] = Button6;
titles[5] = #"btnTitle6";
for (NSInteger i = 0; i < 6; i++)
{
centers[i] = buttons[i].center;
bounds[i] = buttons[i].bounds;
opacities[i] = buttons[i].alpha;
}
}
- (void)viewDidUnload
{
[self stopAnimation];
[self setButton1:nil];
[self setButton2:nil];
[self setButton3:nil];
[self setButton4:nil];
[self setButton5:nil];
[self setButton6:nil];
[self setTitleLabel:nil];
[super viewDidUnload];
}
/////////////////////////////////////////////////////
- (IBAction)swipeLeft:(UISwipeGestureRecognizer *)sender {
[self stopAnimation];
buttons[index].enabled = NO;
{
TitleLabel.text = #"";
index = [self next:index];
[self startAnimation];
}
}
- (IBAction)swipeRight:(UISwipeGestureRecognizer *)sender {
[self stopAnimation];
buttons[index].enabled = NO;
{
TitleLabel.text = #"";
index = [self back:index];
[self startAnimation];
}
}
///////////////////////////////////////////////////
- (void)startAnimation
{
[self prepareForUpdate];
[self.timer invalidate];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:#selector(update) userInfo:nil repeats:YES];
}
- (void)stopAnimation
{
[self.timer invalidate];
[self finalizeUpdate];
self.timer = nil;
}
- (void)prepareForUpdate
{
NSInteger i = 0;
NSInteger iter = index;
do
{
centerOffsets[iter] = CGPointMake
(
(centers[i].x - buttons[iter].center.x) / 30,
(centers[i].y - buttons[iter].center.y) / 30
);
boundOffsets[iter] = CGRectMake
(
(bounds[i].origin.x - buttons[iter].bounds.origin.x) / 30,
(bounds[i].origin.y - buttons[iter].bounds.origin.y) / 30,
(bounds[i].size.width - buttons[iter].bounds.size.width) / 30,
(bounds[i].size.height - buttons[iter].bounds.size.height) / 30
);
opacitieOffsets[iter] = (opacities[i] - buttons[iter].alpha) / 30;
i++;
iter = [self next:iter];
}
while ( iter != index);
iterations = 30;
}
- (void)update
{
if (iterations <= 1)
{
}
if (iterations > 0)
{
for (NSInteger i = 0; i < 6; i++)
{
buttons[i].center = CGPointMake
(
centerOffsets[i].x + buttons[i].center.x,
centerOffsets[i].y + buttons[i].center.y
);
buttons[i].bounds = CGRectMake
(
boundOffsets[i].origin.x + buttons[i].bounds.origin.x,
boundOffsets[i].origin.y + buttons[i].bounds.origin.y,
boundOffsets[i].size.width + buttons[i].bounds.size.width,
boundOffsets[i].size.height + buttons[i].bounds.size.height
);
buttons[i].alpha = buttons[i].alpha + opacitieOffsets[i];
}
iterations--;
}
else [self stopAnimation];
}
- (void)finalizeUpdate
{
NSInteger i = 0;
NSInteger iter = index;
do
{
buttons[iter].center = centers[i];
buttons[iter].bounds = bounds[i];
buttons[iter].alpha = opacities[i];
i++;
iter = [self next:iter];
}
while ( iter != index);
iterations = 0;
buttons[index].enabled = YES;
TitleLabel.text = titles[index];
}
- (NSInteger)back:(NSInteger) i
{
return i == 0 ? 5 : i - 1;
}
- (NSInteger)next:(NSInteger) i
{
return i == 5 ? 0 : i + 1;
}
i want to said that my code work, but need some adjustment or many probably!!
1) first problem it's that the carousel go left/right very slow, I change the time but i still haven't figure out??????
2) I can still see the buttons from the carousel when they rotating in the back, i set alpha to 0 but i can still see them????
I'm new to objective-c so sorry for my mistake, objective-c is very different than c++
help and advice please???
The following line is incorrect:
self.timer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:#selector(update) userInfo:nil repeats:YES];
You are scheduling a timer to fire every 0 seconds, which is consuming the runloop by trying to execute continuously. You have to change that line to schedule the timer with a value greater than 0, for example:
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(update) userInfo:nil repeats:YES];

Objective C - NSMutableSet not working properly

I have an NSMutableSet that I am trying to add labels to. After each label added, I check the set's count and it comes back as 0. Any help will be appreciated
In my .h file:
#interface MainMenu : CCLayerColor {
NSMutableSet* letters;
}
In my .m file:
-(void)initiateLetters{
//Grab the window size
CGSize size = [[CCDirector sharedDirector] winSize];
int i;
for(i=0;i<100;i++){
CCLabelTTF *label;
int r = rand() % 35 + 60;
char c = (char) r;
label = [CCLabelTTF labelWithString:[NSString stringWithFormat:#"%c",c] fontName:#"Courier" fontSize:30];
[label setColor:ccc3(0,0,0)];
[label setOpacity:255/2];
//Generate a random number for the x variable, y will be 0
int x = (arc4random() % (int)size.width);
int y = size.height+(arc4random() % 50)+25;
[label setPosition:ccp(x,y)];
[self addChild:label];
[letters addObject:label];
//Here's what's printing 0:
printf("%lu",[letters count]);
}
}
You have to instantiate the set before you can add things to it. You can do that in an overridden implementation of init:
- (id)init
{
self = [super init];
if (self) {
letters = [[NSMutableSet alloc] init];
}
return self;
}
…or at the beginning of your initiateLetters method:
- (void)initiateLetters
{
letters = [[NSMutableSet alloc] init];
...
Instead, the code you posted is simply sending addObject: to nil, which does nothing.
the array is probably nil. Did you create it in the class init method ?
something like
-(id) init {
if (self = [super init]){
// ...
letters = [[NSMutableSet set] retain]; // not using ARC
// ...
}
return self;
}
and of course
-(void) dealloc {
// ...
[letters release]; // not using ARC
[super dealloc];
}

Score system in Cocos2d project

I have a game where the user collects different types of objects and a label that has a value of 0 at the start. Every time the user collects an object (by touching it) it should make the score = current score + 1; I have tried with the following code but it crashes when I click on the object.
This is the code for my score label which puts a 0 on the screen:
score = 0;
scoreLabel1 = [CCLabelTTF labelWithString:#"0" fontName:#"Times New Roman" fontSize:33];
scoreLabel1.position = ccp(240, 160);
[self addChild:scoreLabel1 z:1];
And this is the void function which I call every time I touch an object:
- (void) addScore
{
score = score + 1;
[scoreLabel1 setString:[NSString stringWithFormat:#"%#", score]];
}
And this is the actual part where I put the code for touching the object:
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[self ccTouchesMoved:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
for (Apple in self.appleArray)
{
if (CGRectContainsPoint(Apple.boundingBox, location))
{
[self addScore];
Apple.visible = NO;
}
}
Everything else works except for the score. Also is there a way to make the apple disappear instead of just making it invisible by apple.visible = false? because this way the apple is still there but not visible, I want to get rid of it.
Hope some one can help!
If you have any questions let me know.
Thanks.
This is where I draw the apples:
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if( (self=[super init]) ) {
isTouchEnabled_ = YES;
self.appleArray = [CCArray arrayWithCapacity:20];
for (int i = 0; i < 5; i++) {
Apple = [CCSprite spriteWithFile:#"Apple4.png"];
[self addChild:Apple];
[appleArray addObject:Apple];
}
[Apple removeFromParentAndCleanup:true];
[self scheduleUpdate];
}
return self;
}
And this is where the screen gets updated:
-(void) update: (ccTime) dt
{
for (int i = 0; i < 5; i++) {
Apple = ((CCSprite *)[appleArray objectAtIndex:i]);
if (Apple.position.y > -250) {
Apple.position = ccp(Apple.position.x, Apple.position.y - (Apple.tag*dt));
}
}
}
a couple of things here. In setScore, your format is broken and will cause a crash (%# requires an NSObject*). Try:
[scoreLabel1 setString:[NSString stringWithFormat:#"%i", score]];
also, the syntax of your for loop is odd. Try
for (Apple *anyApple in self.appleArray)
{
if (CGRectContainsPoint(anyApple.boundingBox, location))
{
if (anyApple.visible) {
[self addScore];
anyApple.visible = NO;
}
}
}
score = score + 1;
[scoreLabel1 setString:[NSString stringWithFormat:#"%#", score]];
Please read this: String Format Specifiers
%# - Objective-C object, printed as the string returned by descriptionWithLocale: if available, or description otherwise. Also works with CFTypeRef objects, returning the result of the CFCopyDescription function.
If your score is an object, you can't "increment" its value that way. If it's an int or a float, you are using wrong format specifier.

How to add a CCsprite to layer from array

Hi guys I really need some help, I have been stuck in this part of my game for over a week now and I can't seem to get past this issue, So have look at my code below,
#import "HelloWorldLayer.h"
#import "AppDelegate.h"
#implementation HelloWorldLayer
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if( (self=[super init]) ) {
moles = [[NSMutableArray alloc] init];
winSize = [[CCDirector sharedDirector]winSize];
CCSprite *mole1 = [CCSprite spriteWithFile:#"lightsabericonblue.png"];
[self starCreateCurrentLevel:mole1];
}
return self;
}
-(void)starCreateCurrentLevel:(CCSprite *)mole1{
starCountCurrentLevel = 10;
for (int i = 0; i < starCountCurrentLevel;) {
[moles addObject:mole1];
starCountCurrentLevel--;
}
[self schedule:#selector(tryPopMoles:) interval:1];
}
- (void)tryPopMoles:(ccTime)dt {
if(moles.count != 0){
for (CCSprite *mole in moles) {
if (arc4random() % moles.count == 0) {
if (mole.numberOfRunningActions == 0) {
[self popMole:mole];
}
}
}
}else if(moles.count == 0){
NSLog(#"No More Moles To Spawn");
[self unschedule:#selector(tryPopMoles:)];
}
}
- (void) popMole:(CCSprite *)mole {
mole.position = ccp(150, 150);
[self addChild:mole];
}
- (void) dealloc
{
[moles release];
moles = nil;
[super dealloc];
}
#end
When I run this code i get the following error, * Assertion failure in -[HelloWorldLayer addChild:z:tag:], /Users/....../libs/cocos2d/CCNode.m:335.
I when i add the child in the init method its fine but I don't want to do that, I want to be able to call the try pop mole which will then call the pop mole based on if there is anymore sprites left in the array, I have a feeling I am missing something or doing something wrong.
UPDATE -
#import "HelloWorldLayer.h"
#import "AppDelegate.h"
#pragma mark - HelloWorldLayer
CGSize winSize;
int enemyX;
int enemyY;
int randomAngleY;
int randomAngleX;
int winSizeX;
int winSizeY;
int minDuration = 1;
int maxDuration = 4.0;
int rangeDuration;
int actualDuration;
int starCountCurrentLevel;
int test = 0;
#implementation HelloWorldLayer
+(CCScene *) scene
{
CCScene *scene = [CCScene node];
HelloWorldLayer *layer = [HelloWorldLayer node];
[scene addChild: layer];
return scene;
}
-(id) init
{
if( (self=[super init]) ) {
moles = [[NSMutableArray alloc] init];
winSize = [[CCDirector sharedDirector]winSize];
[self starCreateCurrentLevel];
}
return self;
}
-(void)starCreateCurrentLevel{
starCountCurrentLevel = 10;
for (int i = 0; i < starCountCurrentLevel;) {
[moles addObject:[CCSprite spriteWithFile:#"lightsabericonblue.png"]];
starCountCurrentLevel--;
}
[self schedule:#selector(tryPopMoles:) interval:3];
}
- (void)tryPopMoles:(ccTime)dt {
NSMutableArray *tempArray = [NSMutableArray arrayWithArray:moles];
for (int randomIndex = tempArray.count -1; randomIndex < tempArray.count; randomIndex--) {
CCSprite * sprite = (CCSprite *)[tempArray objectAtIndex:randomIndex];
//CCSprite *sprite = [tempArray objectAtIndex:randomIndex];
[self popMole:sprite];
NSLog(#"Enemy Added");
[tempArray removeObject:sprite];
}
if([tempArray count] == 0){
NSLog(#"No More Moles To Spawn");
[self unschedule:#selector(tryPopMoles:)];
}
}
- (void) popMole:(CCSprite *)sprite {
winSizeX = winSize.width - sprite.contentSize.width + 25;
winSizeY = winSize.height - 25 - sprite.contentSize.height + 17;
randomAngleX = arc4random() % winSizeX;
randomAngleY = arc4random() % winSizeY;
enemyX = arc4random() % winSizeX ;
enemyY = arc4random() % winSizeY;
rangeDuration = maxDuration - minDuration;
actualDuration = (arc4random() % rangeDuration) + minDuration;
sprite.position = ccp(enemyX, enemyY);
[self addChild:sprite];
}
- (void) dealloc
{
[moles release];
moles = nil;
[super dealloc];
}
#end
You're only creating the sprite once, but trying to add it several times. (Remember, these are pointers to objects, so you're always referring to exactly the same sprite.) If you want 10 versions of the same sprite (at different positions, scales, speeds, whatever), you'll need to create the sprite (via the creator method) 10 times. You can do a copy on the original one, or just create it on the fly:
-(void)starCreateCurrentLevel:(CCSprite *)mole1{
starCountCurrentLevel = 10;
for (int i = 0; i < starCountCurrentLevel;) {
//[moles addObject:mole1];
// ^^ You're adding the same sprite (meaning same pointer reference) again and again. Try this instead:
[moles addObject:[CCSprite spriteWithFile:#"lightsabericonblue.png"]];
starCountCurrentLevel--;
}
Of course, now you don't need to pass mole1 into your method. You may (depending on your need) consider passing in a spriteFrameName or something.

The animation just run one time?

The problems is the animation just run one time then cannot repeat again. Do I need to add one more NSTimer in somewhere ?
Anything I missing ? Looking for help and advice. Thanks a lot !
And here is the code.
First, in ViewController.h & ViewController.m
#interface ViewController : UIViewController {
GameView* gameView;
}
- (void)viewDidLoad
{
[super viewDidLoad];
if(gameView == nil) {
gameView = [[GameView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
gameView.backgroundColor = [UIColor clearColor];
}
[self.view addSubview:gameView];
[[AppEngine sharedInstance] addSnow:CGPointMake((random() % 320),(random() % -20))];
[[AppEngine sharedInstance] addSnow:CGPointMake((random() % 320),(random() % -20))];
[[AppEngine sharedInstance] addSnow:CGPointMake((random() % 320),(random() % -20))];
[[AppEngine sharedInstance] addSnow:CGPointMake((random() % 320),(random() % -20))];
[[AppEngine sharedInstance] addSnow:CGPointMake((random() % 320),(random() % -20))];
}
In the GameView.h & .m
#interface GameView : UIView <UIAccelerometerDelegate>{
CADisplayLink* displayLink;
}
-(void) timeStep;
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
displayLink = [CADisplayLink displayLinkWithTarget:self selector:#selector(timeStep)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
return self;
}
-(void) timeStep {
[[AppEngine sharedInstance] timeStep];
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect {
[[UIImage imageNamed:#"Christmas.jpg"] drawInRect:CGRectMake(0,0,320,480)]; // set the background image
CGContextRef context = UIGraphicsGetCurrentContext();
for(MySnow* snowObject in [AppEngine sharedInstance].snowObjectArray)
{
CGContextSaveGState(context);
CGContextTranslateCTM(context, snowObject.x, snowObject.y);
NSString *imagePath = [NSString stringWithFormat:#"snowflake0%d.png",snowObject.type];
[[UIImage imageNamed: imagePath] drawInRect:CGRectMake(-16,-16,32,32)];
CGContextRestoreGState(context);
}
}
Third, in the snow.h & m
#interface MySnow : NSObject
{
float x,y;
float vx, vy;
float rotSpeed;
float rotation;
int type;
}
#property (nonatomic) float x,y;
#property (nonatomic) float vx, vy, rotSpeed,rotation;
#property (nonatomic) int type;
-(id) initWithStartPoint:(CGPoint) startPoint withType:(int) type;
-(void) timeStep;
#implementation MySnow
#synthesize x,y,vx,vy,rotation,rotSpeed,type;
-(id) initWithStartPoint:(CGPoint) startPoint withType:(int) _type {
self = [super init];
if(self) {
x = startPoint.x;
y = startPoint.y;
vx = RANDOM_FLOAT() * 1 + 0.1;
vy = RANDOM_FLOAT() * 2 + 0.1;
type = _type;
}
return self;
}
-(void) timeStep {
y += vy;
}
Finally, in AppEngine.h & m
#interface AppEngine : NSObject {
NSMutableArray* snowObjectArray;
float ax, ay;
}
#property (readonly) NSMutableArray* snowObjectArray;
#property (nonatomic) float ax,ay;
+(AppEngine*) sharedInstance;
+(void) destoryInstance;
-(void) timeStep;
-(void) addSnow:(CGPoint) point;
static AppEngine* _sharedEngine;
#implementation AppEngine
#synthesize snowObjectArray;
#synthesize ax,ay;
+(AppEngine*) sharedInstance {
if(_sharedEngine == nil)
_sharedEngine = [[AppEngine alloc] init];
return _sharedEngine;
}
+(void) destoryInstance {
if(_sharedEngine != nil) {
_sharedEngine = nil;
}
}
-(id) init {
self = [super init];
if(self) {
snowObjectArray = [[NSMutableArray alloc] init];
}
return self;
}
-(void) addSnow:(CGPoint) point {
int type = (arc4random() % 9) + 1; // random snow image 01 to 09
MySnow* snowObject = [[MySnow alloc] initWithStartPoint:point withType:type];
[snowObjectArray addObject:snowObject];
}
-(void) timeStep {
NSMutableArray* removeArray = [NSMutableArray array];
for(MySnow* item in snowObjectArray) {
[item timeStep];
if(item.y > 400 || item.y < -100)
[removeArray addObject:item];
}
[snowObjectArray removeObjectsInArray:removeArray];
[removeArray removeAllObjects];
}
Is this your code? Can you explain how it starts the animation?
It looks to me like the AppEngine's timeStep method has code that specifically deletes each item in the snowObjectsArray once it reaches some boundary. However, if this is your code, why don't you understand what it does?
EDIT: OK, so this is from a lecture.
If you want the animation to continue, here's what I would do:
Take the last block of code from your viewDidLoad method (the code that creates and adds snow objects) and put it in a separate method. Make viewDidLoad call that method. Let's call the method makeItSnow.
Then, at the end of your AppEngine timeStep method, if the object count in snowObjectArray drops to 0, call makeItSnow.
That approach would make a set of snowflakes start at the top, fall down and disappear, and then another group of snowflakes start. If you want a continuous stream of snowflakes to fall, then change the timeStep method to count the number of snowflake objects it deletes, and at the end of the method add that many snowflakes back to the array. That would cause your program to add a new snowflake as each one disappears.
Yet another approach would be to add a repeating timer to AppEngine, and make that timer create another snowflake. That would keep adding snowflakes on a regular interval.