如果self是SKSpriteNode导致崩溃,则不会提供与崩溃相关的详细信息

时间:2016-07-30 00:53:08

标签: ios swift sprite-kit

有时我觉得使用Apple的官方Swift 2.0教科书会产生反作用......

我认为这样的事情会起作用:

class SKAbstractSprite: SKSpriteNode {
    func playWalkLEFTAnimation() {
        var castedUnit = self

        if self is SKFootmanSprite {
            castedUnit = (self as! SKFootmanSprite)
        } else if self is SKGruntSprite {
            castedUnit = (self as! SKGruntSprite)
        } else if self is SKSpearThrowerSprite {
            castedUnit = (self as! SKSpearThrowerSprite)
        }

        castedUnit.playWalkLEFTAnimation()
    }
}


class SKFootmanSprite: SKAbstractSprite {
    override func playWalkLEFTAnimation() {
        self.runAction(
            SKAction.animateWithTextures(
                walkUp_Frames, timePerFrame: AnimationDuration_WALK))
    }
}

但是'自我'试图看看它是否是SKFootmanSprite,我得到:

Thread 1: EXC_BAD_ACCESS (code=2)

我有所有这种愚蠢的力量投射,因为如果我不这样做,SKFootmanSprite将播放SKAbstractSprite的动画,它什么都不做。

这种作品:

func playAttackUPAnimation() {
    if self is SKFootmanSprite {
        (self as! SKFootmanSprite).playAttackUPAnimation()
    } else if self is SKGruntSprite {
        (self as! SKGruntSprite).playAttackUPAnimation()
    } else if self is SKSpearThrowerSprite {
        (self as! SKSpearThrowerSprite).playAttackUPAnimation()
    }
}

但是使用上面的块,我仍然会...偶尔会得到同样的错误。只是不经常。

我知道Swift不支持抽象类,但是我的选择是什么,所以我不需要编写500行代码来制作新的SKDragonSprite?!

这是SKAbstractSprite如何转换为SKFootmanSprite:

class FootmanUnit: MeleeUnit {

    override init(player: Int) {
        super.init(player: player)
        teamNumber = player
        HP = 26
        CastUnitClass()
        referenceSpriteToSelf()
        CastUnitReference()
    }

    override func referenceSpriteToSelf() {
        (sprite as! SKFootmanSprite).UnitReference = self
    }

    func CastUnitClass() {
        let CastClassUnit = SKFootmanSprite(imageNamed: "footman_walk_down01")
        CastClassUnit.xScale = GameSettings.SpriteScale.Default
        CastClassUnit.yScale = GameSettings.SpriteScale.Default
        CastClassUnit.zPosition = SpritePositionZ.AliveUnit.Z
        sprite = CastClassUnit
        (sprite as! SKFootmanSprite).loadTextures()
    }

    func CastUnitReference() {
        sprite.UnitReference = self
    }

}

1 个答案:

答案 0 :(得分:0)

  

为什么要用Java / C#编写代码?

     

- )

由于一系列原因

,这种方法没有意义
class SKAbstractSprite: SKSpriteNode {
    func playWalkLEFTAnimation() {
        var castedUnit = self

        if self is SKFootmanSprite {
            castedUnit = (self as! SKFootmanSprite)
        } else if self is SKGruntSprite {
            castedUnit = (self as! SKGruntSprite)
        } else if self is SKSpearThrowerSprite {
            castedUnit = (self as! SKSpearThrowerSprite)
        }

        castedUnit.playWalkLEFTAnimation()
    }
}
  1. "摘要"知道其可能的子类的类(在Swift中不存在)是丑陋的,并且是对未来发展的限制
  2. 如果当前实例为SKFootmanSprite,则永远不会执行SKAbstractSprite. playWalkLEFTAnimation,因为SKFootmanSprite提供了自己的版本。所以写这个if self is SKFootmanSprite毫无意义。
  3. 如果self不是SKFootmanSpriteSKGruntSpriteSKSpearThrowerSprite,那么您刚开始无限递归循环,恭喜:D
  4. 更多

    同样,我假设您还在SKAbstractSprite中定义了此方法,但不需要它。

    func playAttackUPAnimation() {
        if self is SKFootmanSprite {
            (self as! SKFootmanSprite).playAttackUPAnimation()
        } else if self is SKGruntSprite {
            (self as! SKGruntSprite).playAttackUPAnimation()
        } else if self is SKSpearThrowerSprite {
            (self as! SKSpearThrowerSprite).playAttackUPAnimation()
        }
    }
    

    多态性自动调用当前实例所属的类中定义的playAttackUPAnimation版本。这个方法应该是这样的

    func playAttackUPAnimation() { }
    

    或者

    func playAttackUPAnimation() { fatalError("Please override") }
    

    或者在协议中定义得更好,而不是假抽象类。

    协议

    由于我不知道您遇到崩溃的类型,我无法确切地说出原因。我肯定可以建议你修改你的代码,删除假的抽象类"并使用protocols

    像这样的东西

    protocol CanWalk {
        func playWalkLEFTAnimation()
    }
    
    class SKFootmanSprite: SKSpriteNode, CanWalk {
        func playWalkLEFTAnimation() {
            self.runAction(
                SKAction.animateWithTextures(
                    walkUp_Frames, timePerFrame: AnimationDuration_WALK))
        }
    }
    

    总结和最后考虑

    1. 您不应在类名前添加SK
    2. 您不应该使用其他编程语言(如抽象类)来模拟范例,使用Swift语言,它们非常好并且有大量文档可用
    3. 您不应将此_置于var名称内( walkUp_Frames,AnimationDuration_WALK