Reputation: 2871
I've tried many different things and I can't understand why any integer I put into my dictionary comes out as 0.
self.lastDinoIndex = [[NSMutableDictionary alloc] init];
unsigned index = arc4random_uniform(28);
[self.lastDinoIndex
setObject:[NSNumber numberWithUnsignedInt:index]
forKey:dinosaur];
NSLog(@"hmmm %d, %d, %d",
index,
[[NSNumber numberWithUnsignedInt:index] unsignedIntValue],
[self.lastDinoIndex[dinosaur] unsignedIntValue]);
this prints out "hmmmm 8, 8, 0" where 8 is the random number and 0 is the source of my frustration.
Dinosaur is an SKSpriteNode instance.
EDIT: The whole function:
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
self.dinoFNs = @[@"broncosoro.png", @"STEGOZAURUS", @"terrorredacter.png", @"treks.png", @"velorappers.png"];
self.lastDinoIndex = [[NSMutableDictionary alloc] init];
/* Setup your scene here */
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
//That was entirely too difficult to get the background image set properly... holy shit.
SKSpriteNode *background = [SKSpriteNode spriteNodeWithImageNamed:@"prehistoric_urban_centre"];
background.anchorPoint = CGPointZero;
background.position = CGPointZero;
background.size = self.frame.size;
[self addChild:background];
for (NSUInteger i = 0; i < ARRAY_SIZE(points); ++i) {
SKSpriteNode *anode = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(30, 30)];
anode.position = points[i];
[self addChild:anode];
}
SKAction *wait = [SKAction waitForDuration:4];
SKAction *spawnDino = [SKAction runBlock:^{
SKSpriteNode* dinosaur = [SKSpriteNode spriteNodeWithImageNamed: self.dinoFNs[arc4random_uniform(5)]];
unsigned index = arc4random_uniform(28);
[self.lastDinoIndex setObject:[NSNumber numberWithUnsignedInt:index] forKey:dinosaur];
NSLog(@"hmmm %d, %d, %d",index, [[NSNumber numberWithUnsignedInt:index] unsignedIntValue], [self.lastDinoIndex[dinosaur] unsignedIntValue]);
dinosaur.position = points[index];
[self addChild:dinosaur];
CGFloat duration = 2.0;
SKAction *moving = [SKAction runBlock:^{
//get next index
int curIndex = [self.lastDinoIndex[dinosaur] unsignedIntValue];
int nextIndex;
if((curIndex +1) % 5 != 0)
nextIndex = ((arc4random_uniform(2) == 1)
? curIndex + 1
: curIndex + 5);
self.lastDinoIndex[dinosaur] = [NSNumber numberWithUnsignedInt: nextIndex];
NSLog(@"%d => %d", curIndex, nextIndex);
//TODO: also add option to go down.
if (nextIndex < 29) { //at or beyond spawn point
NSLog(@"%d: %f, %f", nextIndex, points[nextIndex].x, points[nextIndex].y);
[dinosaur runAction:[SKAction moveTo: points[nextIndex] duration:duration]];
}
else
[dinosaur removeFromParent];
}];
SKAction *delayedMoving = [SKAction sequence:@[[SKAction waitForDuration:duration], moving]];
[dinosaur runAction:[SKAction repeatActionForever: delayedMoving]];
}];
SKAction *sequence = [SKAction sequence:@[wait, spawnDino]];
[self runAction:[SKAction repeatActionForever:sequence]];
}
return self;
}
Upvotes: 1
Views: 107
Reputation: 104082
In my testing, the problem seems to be with how isEqual: is implemented by SKSpriteNode (a bug?). Here is the test code I used,
-(void)doStuff {
self.dinoFNs = @[@"back1.tiff", @"back2.tiff", @"Baldacci.tiff"];
self.lastDinoIndex = [[NSMutableDictionary alloc] init];
SKSpriteNode* dinosaur = [SKSpriteNode spriteNodeWithImageNamed: self.dinoFNs[arc4random_uniform(3)]];
unsigned index = arc4random_uniform(28);
[self.lastDinoIndex setObject:[NSNumber numberWithUnsignedInt:index] forKey:dinosaur];
NSLog(@"hmmm %d, %d",index, [self.lastDinoIndex[dinosaur] unsignedIntValue]);
NSLog(@"%@",self.lastDinoIndex.allKeys[0]);
NSLog(@"%@",dinosaur);
NSLog(@"%d", [dinosaur isEqual:self.lastDinoIndex.allKeys[0]]);
}
And here are the logs,
2014-03-29 18:01:47.811 SpriteNodeDictionaryProblem[2058:60b] hmmm 21, 0
2014-03-29 18:01:47.812 SpriteNodeDictionaryProblem[2058:60b] <SKSpriteNode> name:'(null)' texture:[<SKTexture> 'back2.tiff' (321 x 482)] position:{0, 0} size:{321, 482} rotation:0.00
2014-03-29 18:01:47.812 SpriteNodeDictionaryProblem[2058:60b] <SKSpriteNode> name:'(null)' texture:[<SKTexture> 'back2.tiff' (321 x 482)] position:{0, 0} size:{321, 482} rotation:0.00
2014-03-29 18:01:47.813 SpriteNodeDictionaryProblem[2058:60b] 0
As you can see, when I log dinosaur and self.lastDinoIndex.allKeys[0], the logs are identical, but when I compare them with isEqual:, they come back as not equal. According to the NSDictionary class reference, any object that conforms to NSCopying (which SKSpriteNode does), should be ok as a key.
Upvotes: 2
Reputation: 237070
self.lastDinoIndex
is nil. You need to make sure to create the dictionary created before you use it.
The thing about nil is that it just silently accepts any message you send it and returns the type's "zero" value if it has one (so 0 for integers, 0.0 for floats, NULL/nil for pointers and objects). So mysterious zeros often mean that something is nil.
Upvotes: 3