Reputation: 135
OK, so I'm having a problem directly modifying the contents of an NSMutableArray
. Basically, I have an Array of SKSpriteNodes
created in the initialisation function. I want to be able to modify a SKSpriteNode
at a specified index depending on where the user touches the screen. I can get the correct index, and I can get the node, but I can't seem to get the properties of the node to change.
I've included the full code in here for clarity, but the issue is in the last function (touchesBegan).
What I want to do is be able to set the properties of the SKSpriteNode
at the specified index. The debug messages are saying that *leftTile is being created properly and contains the correct data, but the changes don't take effect on the screen when I call the setHidden
function.
#import "FLGameScene.h"
@implementation FLGameScene
/**
* Convert Multidimensional Coordinates to Single Index
*
* @param int row Row index.
* @param int col Column index.
*
* @return int
*/
- (int)multiToSingle:(int)row :(int)col
{
return ((row * numTiles) + col);
}
/**
* Determine the Iso Coordinates closest to the Real Position.
*
* @param CGPoint coords Real coordinates.
*
* @return CGPoint
*/
- (CGPoint)xyToIso:(CGPoint)coords
{
// Determine the Row and Column
int x = (coords.x - offsetX) / tileSize;
int y = (coords.y - offsetY) / tileSize;
// Create the CGPoint
return CGPointMake(x, y);
}
/**
* Determine the Real Coordinates for a specified index.
*
* @param CGPoint coords Iso coordinates.
*
* @return CGPoint
*/
- (CGPoint)isoToXY:(CGPoint)coords
{
// Determine the X and Y Values
float x = (coords.x * tileSize) + offsetX;
float y = (coords.y * tileSize) + offsetY;
// Create the CG Point
return CGPointMake(x, y);
}
/**
* Initialisation Function.
*
* @param CGSize size Size of the Scene Area.
*
* @return *SKScene
*/
- (id)initWithSize:(CGSize)size
{
// Call the Parent Constructor
if (self = [super initWithSize:size])
{
// Log a Message
if (debugMode) NSLog(@"Game Scene Created. Size: %f x %f", size.width, size.height);
// Set the Background Colour
[self setBackgroundColor:[UIColor colorWithRed:0.15f green:0.25f blue:1.0f alpha:1.0f]];
// Set the Tile Size
tileSize = 50.0f;
// Set the Number of Tiles
numTiles = 14;
// Determine the Offset
offsetX = (size.width / 2.0f) - ((numTiles / 2) * tileSize);
offsetY = (size.height / 2.0f) - ((numTiles / 2) * tileSize);
// Create the Lilypad Texture
SKTexture *lilypadTex = [SKTexture textureWithImageNamed:@"lilypad"];
// Create the Frog Texture
SKTexture *frogTex = [SKTexture textureWithImageNamed:@"frog"];
// Create the Tile Array
_tileArray = [[NSMutableArray alloc] initWithCapacity:(numTiles * numTiles)];
// Loop through and Create the Grid
for (int col = 0; col < numTiles; col++)
{
for (int row = 0; row < numTiles; row++)
{
// Create a Random BOOL Value for the Frogs
int containsFrog = (rand() % 2);
// Log a Message
if (debugMode) NSLog(@"Square %i, %i :: %i", row, col, containsFrog);
// Calculate the X Position
float posX = (col * tileSize) + offsetX;
// Calculate the Y Position
float posY = (row * tileSize) + offsetY;
// Create the Sprite Node
SKSpriteNode *tile = [[SKSpriteNode alloc] initWithTexture:lilypadTex];
// Set the Tile Origin
[tile setAnchorPoint:CGPointZero];
// Add the Sprite User Data Dictionary
[tile setUserData:[NSMutableDictionary dictionary]];
// Set the Flag for Containing a Frog
[tile.userData setValue:[NSNumber numberWithInt:containsFrog] forKey:@"containsFrog"];
// Set the Tile Position
[tile setPosition:CGPointMake(posX, posY)];
// Set the Tile Size
[tile setSize:CGSizeMake(50.0f, 50.0f)];
// Add the Tile to the Board
[self addChild:tile];
// Add the Tile to the Array
[_tileArray addObject:[tile copy]];
}
}
for (SKSpriteNode *tile in _tileArray)
{
if ([[tile.userData valueForKey:@"containsFrog"] boolValue] == YES)
{
// Create a Frog Node
SKSpriteNode *frog = [[SKSpriteNode alloc] initWithTexture:frogTex];
[frog setAnchorPoint:CGPointZero];
[frog setSize:CGSizeMake(tileSize, tileSize)];
[frog setPosition:tile.position];
// Add the Frog Node
[self addChild:frog];
}
}
}
// Return the Instance
return self;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// Get the Touches
UITouch *touch = [touches anyObject];
// Get the Touch Location
CGPoint touchLocation = [touch locationInNode:self];
// Determine the Tile X and Y
CGPoint tileIndex = [self xyToIso:touchLocation];
// Log a Debug Message
if (debugMode) NSLog(@"Tile at %f, %f Tapped", tileIndex.x, tileIndex.y);
// Search Available Tiles
// Tile to the Left
int leftTileIndex = [self multiToSingle:(int)tileIndex.x - 2 :(int)tileIndex.y];
// Get the Tile Object
SKSpriteNode *leftTile = [_tileArray objectAtIndex:leftTileIndex];
if (debugMode) NSLog(@"Description: %@", [leftTile.userData description]);
// Check for Frogs
if ([[leftTile.userData objectForKey:@"containsFrog"] boolValue] == NO)
{
NSLog(@"Tile empty");
[leftTile setHidden: YES];
}
}
@end
Upvotes: 0
Views: 283
Reputation: 64477
// Add the Tile to the Board
[self addChild:tile];
// Add the Tile to the Array
[_tileArray addObject:[tile copy]];
The sprite added to the scene graph is not the same as the one you add to the array because you create a copy
of it. Don't copy and it'll work.
Even better: put all the tiles in an SKNode so you don't need the extra array, instead you can then refer to tiles via the children
array.
Upvotes: 2