首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SKAction & SKSpriteNode故障

SKAction & SKSpriteNode故障
EN

Stack Overflow用户
提问于 2020-06-28 20:19:44
回答 1查看 44关注 0票数 0

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

在我的“发牌”功能中,它以“轮流”的方式给每个玩家发3张牌。这样做效果很好,但我正在尝试添加一些动画-我试图通过动画将每张牌从牌组移动到玩家的手部位置来显示每张牌正在分发给本地玩家。

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

原因:‘尝试添加已有父节点的SKNode :名称:’本地播放器节点‘纹理:'CARD39’(203x350)位置:{281.25,100.05000305175781}

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

发布于 2020-12-20 02:50:38

我认为问题在于在循环中添加播放器节点,然后不删除它们。我确信您不希望在每次调用“deal()”函数时都删除播放器,因此应该在didMove()方法中添加播放器节点。我已经搭建了一个游乐场来演示这个(github Link)

我尝试过使用延迟来让牌一个接一个地发牌,但这是一个不同的问题,您需要在其他地方寻找解决方案。(使用.run(操作)使其在循环完成之前不会实际产生动画效果。

example gif with bad pixel art

代码语言:javascript
复制
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()
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62622454

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档