从类中的方法更新类中的var值

时间:2017-01-16 17:32:19

标签: swift

我觉得这并不像我要做的那样困难,所以任何建议都会受到高度赞赏。

我只是在操场上乱搞,试图更好地理解课程。在游戏场景中,我制作了一个具有健康价值和攻击价值的“玩家”类。攻击值来自一个名为“武器”的不同类,每个类都有自己的Double值。我试图在'Player'类中创建一个函数,当被调用时,就好像正在拾取一个新武器,为玩家创建一个新的攻击值。

我的名为'weaponPickUp'的函数总是说它不能将Weapon.Type的值赋给Double类型。我需要任何建议让这个功能按预期工作!

class Player {
    var health = 100.00
    var armor = 0
    var attack: Double

    init() {
        attack = Weapon.init().fist
    }

    func weaponPickUp(weaponPickedUp: Weapon.Type){
        attack = weaponPickedUp
    }

    func attackEnemy(enemy: Enemy) {
        let weaponStrike = enemy.health - attack
        let currentEnemyHealth = weaponStrike

        if currentEnemyHealth > 0 {
            print("Enemy Hit, life remaining \(currentEnemyHealth)")
            enemy.health = currentEnemyHealth
        } else {
            print("Enemy Destroyed")
        }
    }
}


class Weapon {
    var fist = 25.0
    var machette = 35.0
    var special = Enemy.init().health / 2.0
}


class Enemy {
    var health = 100.0
    var armor = 100.0
    var attack1 = 10.0
    var specialAttack = 50.0
}

2 个答案:

答案 0 :(得分:2)

您的Weapon课程设计得不是很好。在你的Weapon课程中,你似乎列出了武器类型及其攻击伤害。但是你不应该将它们声明为实例属性。此外,special总是会造成50的伤害,而不是将敌人的生命减半(我猜你应该这样做)。

我将你的武器类重新设计成一个结构:

struct Weapon {
    var damage: (Enemy) -> Double
    static let fist = Weapon { _ in return 25.0 }
    static let machette = Weapon { _ in return 35.0 }
    static let special = Weapon { enemy in return enemy.health / 2.0 }
}

damage存储一个返回武器伤害的闭包。我还制作了fistmachettespecial个静态常量,这样您就可以在不创建新武器实例的情况下访问它们。

这是改变了玩家类:

class Player {
    var health = 100.00
    var armor = 0
    var weapon: Weapon

    init() {
        weapon = Weapon.fist
    }

    func weaponPickUp(weaponPickedUp: Weapon){
        weapon = weaponPickedUp
    }

    func attackEnemy(enemy: Enemy) {
        let weaponStrike = enemy.health - weapon.damage(enemy)
        let currentEnemyHealth = weaponStrike

        if currentEnemyHealth > 0 {
            print("Enemy Hit, life remaining \(currentEnemyHealth)")
            enemy.health = currentEnemyHealth
        } else {
            print("Enemy Destroyed")
        }
    }
}

由于special将敌人的生命值减半,因此attack中的Player值不会有,Weapon值与敌人的健康状况无关。所以我将其更改为attackEnemy实例。在weapon.damage(enemy)中,我写了img,因为我们需要通过我们正在攻击的敌人来计算武器可以造成多大的伤害。

答案 1 :(得分:1)

如果这是整个程序,我肯定会用Sweeper的风格来写这个,但它依赖于理解闭包,这可能比你想要立即处理的学习曲线要​​高一些。如果除了伤害之外,如果武器可以拥有其他属性,那么它也不是那么灵活。

解决此问题的另一种方法是使用简单的Weapon协议:

protocol Weapon {
    func damage(whenAttacking enemy: Enemy) -> Double
}

现在你可以拥有特定的武器。如果这真的是一个武器(一组统计数据),那么它们应该是结构。但是如果你将武器作为游戏中的独特物品进行追踪,你可以选择让它们成为类。现在,我们将它们作为结构(这意味着任何两个Machettes,例如,是无法区分的。)

struct Fist: Weapon {
    func damage(whenAttacking enemy: Enemy) -> Double {
        return 25
    }
}

struct Machette: Weapon {
    func damage(whenAttacking enemy: Enemy) -> Double {
        return 35
    }
}

struct SpecialWeapon: Weapon {
    func damage(whenAttacking enemy: Enemy) -> Double {
        return enemy.health / 2.0
    }
}

现在对Player进行了一些更改。我做了一些样式更改(不需要init只设置初始值),以及一些实质性更改(如何计算损坏)。

class Player {
    var health = 100.00
    var armor = 0
    var weapon: Weapon = Fist()

    // You'd almost certainly not bother with this method, and just let people call
    //     player.weapon = Machette()
    func pickUp(weapon: Weapon){
        self.weapon = weapon
    }

    func attack(enemy: Enemy) {
        let weaponStrike = enemy.health - weapon.damage(whenAttacking: enemy)
        let currentEnemyHealth = weaponStrike

        if currentEnemyHealth > 0 {
            print("Enemy Hit, life remaining \(currentEnemyHealth)")
            enemy.health = currentEnemyHealth
        } else {
            print("Enemy Destroyed")
        }
    }
}

这是一种合理的方法,但当然有许多其他方法可以做到这一点。事实上,我个人会将attack代码中的大部分代码移到Enemy这样:

class Enemy {
    private(set) var health = 100.0
    private var armor = 100.0
    private var attack1 = 10.0
    private var specialAttack = 50.0

    var isAlive: Bool {
        return health > 0
    }

    func receiveAttack(from weapon: Weapon) {
        health -= weapon.damage(whenAttacking: self)
        // Personally I'd let health be negative, but feel free to force it to be 0 here   
    }
}

现在,Player.attack看起来像这样:

func attack(enemy: Enemy) {
    enemy.receiveAttack(from: weapon)

    if enemy.isAlive {
        print("Enemy Hit, life remaining \(enemy.health)")
    } else {
        print("Enemy Destroyed")
    }
}

这为在敌人内部修改敌人的健康提供了逻辑。如果一个新的敌人拥有保护它免受Machettes威胁的特殊权力,那么可以将其置于receiveAttack内,而无需修改玩家(或任何其他对象)。