【问题标题】:SKAction & SKSpriteNode troubleSKAction & SKSpriteNode 麻烦
【发布时间】:2020-10-18 16:35:23
【问题描述】:

我正在使用 SKSprite 节点在 Swift 中创建一个纸牌游戏来显示纸牌面。

在我的“发牌”功能中,它向每位玩家发 3 张牌,以“循环”方式一次发一张。这工作正常,但我正在尝试添加一些动画 - 我试图通过动画显示每张卡片从牌组移动到玩家手的位置,从而显示每张卡片被发给本地玩家。

我可以让 Sprite 节点在没有动画的情况下显示,但是当我尝试使用 SKAction 时,它在动作完成后给我以下错误:

原因:'尝试添加已经有父节点的 SKNode:名称:'本地玩家节点'纹理:['CARD39' (203 x 350)] 位置:{281.25, 100.05000305175781}

class GameScene: SKScene {

let tempCard = SKSpriteNode(texture: SKTexture(imageNamed: "back"))

        func deal() {

        players = createPlayers(with: numberOfPlayers)
        
        tempCard.setScale((screenSize.width/100) * 0.2)
        tempCard.zPosition = 10
        tempCard.name = "tempcard"
        addChild(tempCard)
        
        let localPlayer = 0
        var i = 0
        repeat {
            print("Card number: \(i)")
            var x = 0
            let xPos = screenSize.width * (0.25 * CGFloat(i+1))
            
            players.forEach { player in
                
                let newCard = self.deck.dealOneCard()
                player.hand.addCard(card: newCard)
                
                localPlayerNode = players[localPlayer].hand[i].cardImage()
                localPlayerNode.position = CGPoint(x: xPos, y: screenSize.height * 0.15)
                localPlayerNode.setScale((screenSize.width/100) * 0.2)
                localPlayerNode.name = "local player node"
                
                if player.id == localPlayer {
                    
                    let moveCard = SKAction.move(to: CGPoint(x: xPos, y: screenSize.height * 0.15),duration: 1.5)
                    
                    //addChild(localPlayerNode) --using this instead of SKAction works

                    tempCard.run(moveCard, completion: {() -> Void in
                        self.tempCard.removeFromParent()
                        self.addChild(self.localPlayerNode)
                    })
                }
                x+=1
            }
            i+=1
        } while i<3

【问题讨论】:

  • “它给了我以下错误”哪里!? tempcard...它是干什么用的?它来自哪里?
  • 嗨! SKAction 完成时出现错误。 tempCard 只用在这个功能里,它只用来显示卡片背面的图像,我已经更新了帖子,我知道是否需要添加更多细节

标签: swift skaction


【解决方案1】:

我认为问题在于在循环中添加播放器节点,然后再不删除它们。我确定您不想在每次调用“ deal() ”函数时删除播放器,因此您应该在 didMove() 方法中添加播放器节点。 我已经建立了一个游乐场来演示这个(github Link)
我尝试使用延迟来使卡片一张一张地发牌,但这是一个不同的问题,您需要寻找其他地方来解决。 (带有 .run( 动作)的东西使它在循环完成之前实际上不会动画。

example gif with bad pixel art

class GameScene: SKScene {
let scale : CGFloat = 50
var deck : [String] = []
let composition = deckComp()
let numberOfPlayers = 3
var players : [Player] = []
override func didMove(to view: SKView) {
    // creates deck
for c in deckComp().colors {
    for s in deckComp().suits {
        deck.append( s + " of " + c )
       }
    }
players = createPlayers(numberOfPlayers: numberOfPlayers, center : CGPoint(x : 25, y : 25))
// setup the scales, and players
for plyr in players {
    plyr.setScale(scale: (frame.width/10000) * scale)
    addChild( plyr.node)
    }
    }
func createPlayers(numberOfPlayers : Int, center : CGPoint) -> [Player] {

    let radius = Float(5*scale)
    let two_pi = 2 * 3.14159
    let angular_positions = two_pi / Double(numberOfPlayers)
    var players_out : [Player] = []
    for i in 0...numberOfPlayers - 1 {
        let sprite = SKSpriteNode(texture: SKTexture(imageNamed: "card_player.png"))
        sprite.zPosition = 1
        sprite.position = CGPoint( x : center.x + CGFloat(radius * sin( Float(angular_positions) * Float(i) )), y : center.y +  CGFloat(radius * cos( Float(angular_positions) * Float(i) )) )
        sprite.texture?.filteringMode = .nearest // .linear for blurry, .nearest for pixely
        let player_instance = Player(node : sprite, name : "Player " + String(i + 1), id : Int8(i + 1) )
        players_out.append(player_instance)
    }
    return players_out
}
func deal() {
         // I moved the setscale stuff for player sprites to didMove()
    // first check if there is enough in deck
    if deck.count > players.count {
    var i = 0
        repeat {
        // add the temp card
        let tempCard = SKSpriteNode(texture: SKTexture(imageNamed: "back"))
        tempCard.size = CGSize( width: tempCard.size.width * (frame.width/10000) * scale, height : tempCard.size.height * (frame.width/10000) * scale )
        tempCard.zPosition = 10
        tempCard.texture?.filteringMode = .nearest
        self.addChild(tempCard)
        // done adding temporary card
        let xPos = frame.width * (0.25 * CGFloat(i+1))
        tempCard.position = CGPoint(x : xPos, y : 0.75 * frame.height)
            let newCard = self.deck.popLast() // replaced dealOneCard() since I haven't defined it
            players[i].addCard(card: newCard!)  // removed hand.addCard(), since I don't have the array extensions
        //                player.name = "local player node"
        let moveCard = SKAction.move(to: players[i].node.position ,duration: 1.5)
                //addChild(localPlayerNode) --using this instead of SKAction works
            tempCard.run(moveCard, completion: { () -> Void in tempCard.removeFromParent();                })
            i += 1
        } while i < players.count
    } else { print("not enough cards to deal to everyone")} // when deck is empty
}

override func mouseUp(with event: NSEvent) {
    deal()
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-11
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多