ios - 无法修改 SKSpriteNodes 的 objectAtIndex NSMutableArray

标签 ios objective-c sprite-kit

好的,所以我在直接修改 NSMutableArray 的内容时遇到了问题。基本上,我在初始化函数中创建了一个 SKSpriteNodes 数组。我希望能够根据用户触摸屏幕的位置修改指定索引处的 SKSpriteNode。我可以获取正确的索引,也可以获取节点,但我似乎无法获取要更改的节点的属性。

为了清楚起见,我在此处包含了完整代码,但问题出在最后一个函数 (touchesBegan) 中。

我想要做的是能够在指定索引处设置 SKSpriteNode 的属性。调试消息说 *leftTile 正在正确创建并包含正确的数据,但是当我调用 setHidden 函数时,更改不会在屏幕上生效。

#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

最佳答案

            // Add the Tile to the Board
            [self addChild:tile];

            // Add the Tile to the Array
            [_tileArray addObject:[tile copy]];

添加到场景图中的 Sprite 与您添加到数组中的 Sprite 不同,因为您创建了它的副本。不要复制,它会起作用。

更好的是:将所有图 block 放在一个 SKNode 中,这样您就不需要额外的数组,而是可以通过 children 数组引用图 block 。

关于ios - 无法修改 SKSpriteNodes 的 objectAtIndex NSMutableArray,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22774988/

相关文章:

ios - 如何在 if 语句中使用可选值?

iphone - 如何从 UIView 的子类推送 View Controller

ios - os_log timeval格式的Clang错误

swift - 转到上一个场景 SpriteKit

ios - 从 UITableViewCell 到 UIViewController 的 segue 不起作用(准备不调用 segue)

iphone - 如何使用 Xcode 4.5 将 UIImageView 嵌入到 iOS 中的 UIScrollView

ios - 如何从@implementation 外部调用方法?

ios - 显示状态栏和提示通知下拉

ios - SpriteKit 播放器跳跃按钮

ios - 将自定义 SKShader 应用于 SKScene,使用 Swift 在 iOS 8 SpriteKit 中对整个渲染场景进行像素化