SKSpriteNode moveTo:X 用于数组中的所有内容

Posted

技术标签:

【中文标题】SKSpriteNode moveTo:X 用于数组中的所有内容【英文标题】:SKSpriteNode moveTo:X for all in array 【发布时间】:2015-02-17 00:24:56 【问题描述】:
        for (int i = 0; i < [playerCards count]; i++) 
            int cardsLaid = i * (cardDisplay.size.width / 3);
            CGPoint forPoint = CGPointMake((0.5 - (self.frame.size.width / 4)) + cardsLaid, 0.0);

            playerCards[i]

            [??? runAction:[SKAction moveTo:forPoint duration:0.6]];
        

我需要某种SKSpriteNode withName : X move to point : forPoint;

没有更多的描述,基本上卡片从一个位置移动留下一个间隙。然后从 Players 数组中移出该卡后,它们的卡应该像以前一样收紧。然而,以 CardSpriteNodes 为目标被证明是困难的。

正如你所看到的位置,它将过滤阵列中的所有卡片,我将乘以它们之间的间隙,从而对它们进行排序。但我不能针对数组中的特定卡片,它们通过它们的 .names 存储在数组中

-编辑-

如您所见,在他们向上移动后,与他们被带走的地方留下了一个空隙。上面的卡片现在是cardsPlayed,下面的汽车是playerCards NSMutableArrays

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];
    if ([node isKindOfClass:[CardSpriteNode class]]) 
        int add = (int)[playerCards count] * (cardDisplay.size.width / 3);
        CGPoint origPos = CGPointMake(-self.frame.size.width/2.8 + add, -218);

        if ([cardsPlayed containsObject:node.name]) 
            //Card is already played, return to original position and remove from array.
            CGPoint point = origPos;

            [node runAction:[SKAction moveTo:point duration:0.6]];

            node.zPosition = zPosCount;
            zPosCount += 1;

            [cardsPlayed removeObject:node.name];
            [playerCards addObject:node.name];

            NSLog(@"this ran");
         else 
            //Card is not already played, position to add card and add to array.
            amountOfCardsLaid = (int)[cardsPlayed count] * (cardDisplay.size.width / 3);
            CGPoint point = CGPointMake((0.5 - (self.frame.size.width / 4
            )) + amountOfCardsLaid, 0.0);
            [node runAction:[SKAction moveTo:point duration:0.6]];

            node.zPosition = zPosCount;
            zPosCount += 1;

            [playerCards removeObject:node.name];
            [cardsPlayed addObject:node.name];

            for (int i = 0; i < [playerCards count]; i++) 
                int cardsLaid = i * (cardDisplay.size.width / 3);
                CGPoint forPoint = CGPointMake((0.5 - (self.frame.size.width / 4)) + cardsLaid, 0.0);

                playerCards[i]

                [??? runAction:[SKAction moveTo:forPoint duration:0.6]];
            
        

        //Hide.Unhide buttons
        if ([cardsPlayed count] == 0) 
            if (addButton.hidden == FALSE) addButton.hidden = true;
            if (cancelButton.hidden == FALSE) cancelButton.hidden = true;
         else 
            if (addButton.hidden == TRUE) addButton.hidden = false;
            if (cancelButton.hidden == TRUE) cancelButton.hidden = false;
        
    

如您所见,当从底部取出卡片时,它会移到顶部。当它在顶部时,如果再次按下它,它将移动到底部卡片的最后一个位置并重新添加到该数组中。但是,一旦卡片向上移动,我需要关闭gap

为了实现这一点,我将过滤每个包含 CardSpriteNode (SKSpriteNode) .name 的 playerCards 数组,并使用 forloop 移动每个数组。但无法准确弄清楚如何通过名称选择playerCard 中的每张卡?

【问题讨论】:

我不确定您从上面特别需要什么 如果您需要获取卡节点,您可以使用 enumerateChildNodesWithName:usingBlock: 或 SKNode 中可用于检索节点的各种其他方法来完成。您似乎遇到的问题似乎是编码结构问题。您必须提供更多详细信息,以便任何人了解您正在尝试做什么。由此: SKSpriteNode withName : X move to point : forPoint;听起来您只需要枚举节点并通过 name 属性检查节点的名称是否匹配。 @TheCodingArt 基本上就目前而言,卡片向上移动以进行播放,它们从playerCards 数组中移除并放入playedCards 数组中。然后,我想缩小卡牌造成的差距。并且它们的间距就像我用放置在 int 和 forpoint 的卡片所描述的那样。我会更新我的问题。 @TheCodingArt 为您更新了问题,希望现在更有意义。 你应该把你的球员卡和打牌放在一个playcardsnode和playercardsnode中。这将让您分离数据,以便您可以在屏幕上重新排序卡片。实际上,您应该在另一个具有网格的类中拥有游戏逻辑,网格将跟踪所有内容的位置以及占用的空间等等。由于您的逻辑没有正确分离,这将更加困难。最好的办法是使用射线投射来检测移除/添加的卡片周围有哪些卡片。 另外,如果不运行代码并且浏览上面的代码,仍然很难判断目标是什么。可读性是 obj c 代码的关键。将这些东西分成方法并指出它们的作用。 【参考方案1】:

我在业余时间也写了一个纸牌游戏,所以我知道你正在寻找的问题。我创建了一个 SKSpriteNode 的子类,在其中我有卡片具有不同值的键。

但是,如果您想保持更基本的功能,您甚至不需要这样做,只需设置 SKSpriteNode 的 name 属性,然后使用 enumerateChildNodesWithName: 方法或带有 if statementfor loop,如建议的厘米。

【讨论】:

【参考方案2】:

我想我理解你的问题更好。要解决上述问题,请使用卡片的原始点并使用该区域的宽度通过右侧/左侧调用光线投射,并增加所有具有该名称的节点的距离(假设您将卡片称为“卡片") 在适当的距离上。由于您将具有该名称的所有节点移动相同的距离,因此不需要特定的顺序。使用

hitTestWithSegmentFromPoint:toPoint:options:

否则,您必须枚举您的节点以及如何用一个标志来标记SKSpriteNode 对象,该标志会通知您它是“已播放”还是“在手”。枚举时,必须得到总距离并计算出每张卡必须占据的位置。您应该能够使用您的数组来记录卡片从左到右的位置,并将该对象的索引乘以计算出的距离除以总距离除以总卡片数。 (别忘了你可以在 Swift 中使用indexOfObject:on NSArrayfind(arr, "d") 从数组中获取对象的索引。

【讨论】:

以上是关于SKSpriteNode moveTo:X 用于数组中的所有内容的主要内容,如果未能解决你的问题,请参考以下文章

canvas基础入门绘制线条三角形七巧板

skemitternode 与 skspritenode 碰撞

iOS -- SKSpriteNode类

调整和缩放 SKSpriteNode

将 SKLabelNode 设置为 SKSpriteNode Swift 的中心

skspritenode 看不到添加的孩子