在Spritekit中更改多个级别的状态

时间:2016-11-09 19:08:02

标签: swift sprite-kit swift3

我制作了一个不同级别的游戏,但感觉它太过扩展了。我用我有限的知识创造了不同的层次,我认为它可以更有效地编码。我想根据当前的水平改变敌人的状态。 这是我的代码↓

    func addEnemy() {
        if currentLevel == 1{
        let enemyGhost = SKSpriteNode(imageNamed: "enemy")
        enemyGhost.setScale(random(min: 1.5, max: 2.5))
        enemyGhost.physicsBody = SKPhysicsBody(rectangleOf: enemyGhost.size)
        enemyGhost.physicsBody?.isDynamic = true 
        enemyGhost.physicsBody?.categoryBitMask = PhysicsCategory.enemyGhost
        enemyGhost.physicsBody?.contactTestBitMask = PhysicsCategory.Projectile 
        enemyGhost.physicsBody?.collisionBitMask = PhysicsCategory.None
        let actualY = random(min: enemyGhost.size.height/2, max: size.height - enemyGhost.size.height/2)
        enemyGhost.position = CGPoint(x: size.width + enemyGhost.size.width/2, y: actualY)
        addChild(enemyGhost)
        let actualDuration = random(min: CGFloat(5.0), max: CGFloat(7.0))
        let actionMove = SKAction.move(to: CGPoint(x: -enemyGhost.size.width/2, y: actualY), duration: TimeInterval(actualDuration))
        let actionMoveDone = SKAction.removeFromParent()
        let loseAction = SKAction.run() {
        let reveal:SKTransition = SKTransition.flipHorizontal(withDuration: 0.5)
        let gameOverScene = GameOverScene(size: self.size, won: false)
        self.view?.presentScene(gameOverScene, transition: reveal)
        }
    enemyGhost.run(SKAction.sequence([actionMove, loseAction, actionMoveDone]))
    }
    else if currentLevel == 2 {
        let enemyGhost = SKSpriteNode(imageNamed: "enemy")
        enemyGhost.setScale(random(min: 1.0, max: 1.5))
        enemyGhost.physicsBody = SKPhysicsBody(rectangleOf: enemyGhost.size)
        enemyGhost.physicsBody?.isDynamic = true 
        enemyGhost.physicsBody?.categoryBitMask = PhysicsCategory.enemyGhost 
        enemyGhost.physicsBody?.contactTestBitMask = PhysicsCategory.Projectile 
        enemyGhost.physicsBody?.collisionBitMask = PhysicsCategory.None 
        let actualY = random(min: enemyGhost.size.height/2, max: size.height - enemyGhost.size.height/2)
        enemyGhost.position = CGPoint(x: size.width + enemyGhost.size.width/2, y: actualY)
        addChild(enemyGhost)
        let actualDuration = random(min: CGFloat(3.0), max: CGFloat(5.0))
        let actionMove = SKAction.move(to: CGPoint(x: -enemyGhost.size.width/2, y: actualY), duration: TimeInterval(actualDuration))
        let actionMoveDone = SKAction.removeFromParent()
        let loseAction = SKAction.run() {
            let reveal:SKTransition = SKTransition.flipHorizontal(withDuration: 0.5)
            let gameOverScene = GameOverScene(size: self.size, won: false)
            self.view?.presentScene(gameOverScene, transition: reveal)
        }
        enemyGhost.run(SKAction.sequence([actionMove, loseAction, actionMoveDone]))
        }
    }else if currentLevel == 3 {
        let enemyGhost = SKSpriteNode(imageNamed: "enemy")
        enemyGhost.setScale(random(min: 0.5, max: 1.0))
        enemyGhost.physicsBody = SKPhysicsBody(rectangleOf: enemyGhost.size) 
        enemyGhost.physicsBody?.isDynamic = true 
        enemyGhost.physicsBody?.categoryBitMask = PhysicsCategory.enemyGhost 
        enemyGhost.physicsBody?.contactTestBitMask = PhysicsCategory.Projectile 
        enemyGhost.physicsBody?.collisionBitMask = PhysicsCategory.None 
        let actualY = random(min: enemyGhost.size.height/2, max: size.height - enemyGhost.size.height/2)
        enemyGhost.position = CGPoint(x: size.width + enemyGhost.size.width/2, y: actualY)
        addChild(enemyGhost)
        let actualDuration = random(min: CGFloat(2.0), max: CGFloat(3.0))
        let actionMove = SKAction.move(to: CGPoint(x: -enemyGhost.size.width/2, y: actualY), duration: TimeInterval(actualDuration))
        let actionMoveDone = SKAction.removeFromParent()
        let loseAction = SKAction.run() {
            let reveal:SKTransition = SKTransition.flipHorizontal(withDuration: 0.5)
            let gameOverScene = GameOverScene(size: self.size, won: false)
            self.view?.presentScene(gameOverScene, transition: reveal)
        }
        enemyGhost.run(SKAction.sequence([actionMove, loseAction, actionMoveDone]))
        }

2 个答案:

答案 0 :(得分:2)

您的功能可以简化,因为它充满了冗余代码:

func addEnemy() {
        let enemyGhost = SKSpriteNode(imageNamed: "enemy")
        enemyGhost.physicsBody = SKPhysicsBody(rectangleOf: enemyGhost.size)
        enemyGhost.physicsBody?.isDynamic = true
        enemyGhost.physicsBody?.categoryBitMask = PhysicsCategory.enemyGhost.rawValue
        enemyGhost.physicsBody?.contactTestBitMask = PhysicsCategory.Projectile.rawValue
        enemyGhost.physicsBody?.collisionBitMask = PhysicsCategory.None.rawValue
        let actualY = random(min: enemyGhost.size.height/2, max: size.height - enemyGhost.size.height/2)
        enemyGhost.position = CGPoint(x: size.width + enemyGhost.size.width/2, y: actualY)
        addChild(enemyGhost)
        var actualDuration = random(min: CGFloat(5.0), max: CGFloat(7.0))
        switch currentLevel {
        case 1:
            enemyGhost.setScale(random(min: 1.5, max: 2.5))
        case 2:
            enemyGhost.setScale(random(min: 1.0, max: 1.5))
            actualDuration = random(min: CGFloat(3.0), max: CGFloat(5.0))
        case 3:
            enemyGhost.setScale(random(min: 0.5, max: 1.0))
            actualDuration = random(min: CGFloat(2.0), max: CGFloat(3.0))
        default:
            break
        }
        let actionMove = SKAction.move(to: CGPoint(x: -enemyGhost.size.width/2, y: actualY), duration: TimeInterval(actualDuration))
        let actionMoveDone = SKAction.removeFromParent()
        let loseAction = SKAction.run() {
            let reveal:SKTransition = SKTransition.flipHorizontal(withDuration: 0.5)
            let gameOverScene = GameOverScene(size: self.size, won: false)
            self.view?.presentScene(gameOverScene, transition: reveal)
        }
        enemyGhost.run(SKAction.sequence([actionMove, loseAction, actionMoveDone]))
}

关于您的敌人状态,请记住您可以使用userDatadocs)来存储和检索特定属性,例如:

enemyGhost.userData? = NSMutableDictionary()
enemyGhost.userData = ["status":"aggressive"]
print(enemyGhost.userData?["status"] ?? "none")

答案 1 :(得分:1)

好吧,我会先为Enemy创建一个单独的类,这样你就不会重复这么多的初始化代码了。然后你可以为EnemyType创建一个enum,它根据敌人的类型或者他所处的等级为敌人提供可变信息。然后你只需根据他的类型创建你的敌人,敌人对象就已经没有了所有必要的信息。

值得注意的是,您的PhysicsCategory名称具有不同的情况“enemyGhost”与“Projectile”。他们应该是同一个案例。

struct EnemyScale {
    var minScale: CGFloat = 0
    var maxScale: CGFloat = 0
}

enum EnemyType: Int {

    case level1, level2, level3

    var textureImage: String {

        switch self {

            case .level1: return "enemy"
            case .level2: return "enemy"
            case .level3: return "enemy"

        }
    }

    var scale: EnemyScale {

        switch self {

            case .level1: return EnemyScale(minScale: 1.5, maxScale: 2.5)
            case .level2: return EnemyScale(minScale: 1.0, maxScale: 1.5)
            case .level3: return EnemyScale(minScale: 0.5, maxScale: 1.0)

        }
    }
}

class Enemy: SKSpriteNode {

    init(type: EnemyType) {

        let enemyTexture = SKTexture(imageNamed: type.textureImage)

        super.init(texture: enemyTexture, color: .clear, size: enemyTexture.size())

        self.setScale(random(min: type.scaleMin, max: type.scaleMax))

        self.physicsBody = SKPhysicsBody(rectangleOf: self.size)
        self.physicsBody?.isDynamic = true
        self.physicsBody?.categoryBitMask = PhysicsCategory.enemyGhost
        self.physicsBody?.contactTestBitMask = PhysicsCategory.Projectile
        self.physicsBody?.collisionBitMask = PhysicsCategory.None
    }
}

func addEnemy() {

    if currentLevel == 1 {

        let enemyGhost = Enemy(type: .level1)
        let actualY = random(min: enemyGhost.size.height / 2, max: size.height - enemyGhost.size.height / 2)
        enemyGhost.position = CGPoint(x: size.width + enemyGhost.size.width / 2, y: actualY)
        self.addChild(enemyGhost)

        let actualDuration = random(min: CGFloat(5.0), max: CGFloat(7.0))
        let actionMove = SKAction.move(to: CGPoint(x: -enemyGhost.size.width / 2, y: actualY), duration: TimeInterval(actualDuration))
        let actionMoveDone = SKAction.removeFromParent()
        let loseAction = SKAction.run() {
            let reveal:SKTransition = SKTransition.flipHorizontal(withDuration: 0.5)
            let gameOverScene = GameOverScene(size: self.size, won: false)
            self.view?.presentScene(gameOverScene, transition: reveal)
        }
        enemyGhost.run(SKAction.sequence([actionMove, loseAction, actionMoveDone]))
    }
    else if currentLevel == 2 {

        let enemyGhost = Enemy(type: .level2)
        let actualY = random(min: enemyGhost.size.height / 2, max: size.height - enemyGhost.size.height / 2)
        enemyGhost.position = CGPoint(x: size.width + enemyGhost.size.width / 2, y: actualY)
        self.addChild(enemyGhost)

        let actualDuration = random(min: CGFloat(3.0), max: CGFloat(5.0))
        let actionMove = SKAction.move(to: CGPoint(x: -enemyGhost.size.width / 2, y: actualY), duration: TimeInterval(actualDuration))
        let actionMoveDone = SKAction.removeFromParent()
        let loseAction = SKAction.run() {
            let reveal:SKTransition = SKTransition.flipHorizontal(withDuration: 0.5)
            let gameOverScene = GameOverScene(size: self.size, won: false)
            self.view?.presentScene(gameOverScene, transition: reveal)
        }
        enemyGhost.run(SKAction.sequence([actionMove, loseAction, actionMoveDone]))
    }
    else if currentLevel == 3 {

        let enemyGhost = Enemy(type: .level3)
        let actualY = random(min: enemyGhost.size.height / 2, max: size.height - enemyGhost.size.height / 2)
        enemyGhost.position = CGPoint(x: size.width + enemyGhost.size.width / 2, y: actualY)
        self.addChild(enemyGhost)

        let actualDuration = random(min: CGFloat(2.0), max: CGFloat(3.0))
        let actionMove = SKAction.move(to: CGPoint(x: -enemyGhost.size.width / 2, y: actualY), duration: TimeInterval(actualDuration))
        let actionMoveDone = SKAction.removeFromParent()
        let loseAction = SKAction.run() {
            let reveal:SKTransition = SKTransition.flipHorizontal(withDuration: 0.5)
            let gameOverScene = GameOverScene(size: self.size, won: false)
            self.view?.presentScene(gameOverScene, transition: reveal)
        }
        enemyGhost.run(SKAction.sequence([actionMove, loseAction, actionMoveDone]))
    }
}